This repository has been archived on 2020-08-22. You can view files and clone it, but cannot push or open issues or pull requests.
pyaudviz/src/toolkit/common.py

194 lines
5.5 KiB
Python

'''
Common functions
'''
from PyQt5 import QtWidgets
import string
import os
import sys
import subprocess
import logging
from copy import copy
from collections import OrderedDict
log = logging.getLogger('AVP.Toolkit.Common')
class blockSignals:
'''
Context manager to temporarily block list of QtWidgets from updating,
and guarantee restoring the previous state afterwards.
'''
def __init__(self, widgets):
if type(widgets) is dict:
self.widgets = concatDictVals(widgets)
else:
self.widgets = (
widgets if hasattr(widgets, '__iter__')
else [widgets]
)
def __enter__(self):
log.verbose(
'Blocking signals for %s',
", ".join([
str(w.__class__.__name__) for w in self.widgets
])
)
self.oldStates = [w.signalsBlocked() for w in self.widgets]
for w in self.widgets:
w.blockSignals(True)
def __exit__(self, *args):
log.verbose(
'Resetting blockSignals to %s', str(bool(sum(self.oldStates))))
for w, state in zip(self.widgets, self.oldStates):
w.blockSignals(state)
def concatDictVals(d):
'''Concatenates all values in given dict into one list.'''
key, value = d.popitem()
d[key] = value
final = copy(value)
if type(final) is not list:
final = [final]
final.extend([val for val in d.values()])
else:
value.extend([item for val in d.values() for item in val])
return final
def badName(name):
'''Returns whether a name contains non-alphanumeric chars'''
return any([letter in string.punctuation for letter in name])
def alphabetizeDict(dictionary):
'''Alphabetizes a dict into OrderedDict '''
return OrderedDict(sorted(dictionary.items(), key=lambda t: t[0]))
def presetToString(dictionary):
'''Returns string repr of a preset'''
return repr(alphabetizeDict(dictionary))
def presetFromString(string):
'''Turns a string repr of OrderedDict into a regular dict'''
return dict(eval(string))
def appendUppercase(lst):
for form, i in zip(lst, range(len(lst))):
lst.append(form.upper())
return lst
def pipeWrapper(func):
'''A decorator to insert proper kwargs into Popen objects.'''
def pipeWrapper(commandList, **kwargs):
if sys.platform == 'win32':
# Stop CMD window from appearing on Windows
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
kwargs['startupinfo'] = startupinfo
if 'bufsize' not in kwargs:
kwargs['bufsize'] = 10**8
if 'stdin' not in kwargs:
kwargs['stdin'] = subprocess.DEVNULL
return func(commandList, **kwargs)
return pipeWrapper
@pipeWrapper
def checkOutput(commandList, **kwargs):
return subprocess.check_output(commandList, **kwargs)
def disableWhenEncoding(func):
def decorator(self, *args, **kwargs):
if self.encoding:
return
else:
return func(self, *args, **kwargs)
return decorator
def disableWhenOpeningProject(func):
def decorator(self, *args, **kwargs):
if self.core.openingProject:
return
else:
return func(self, *args, **kwargs)
return decorator
def rgbFromString(string):
'''Turns an RGB string like "255, 255, 255" into a tuple'''
try:
tup = tuple([int(i) for i in string.split(',')])
if len(tup) != 3:
raise ValueError
for i in tup:
if i > 255 or i < 0:
raise ValueError
return tup
except:
return (255, 255, 255)
def formatTraceback(tb=None):
import traceback
if tb is None:
import sys
tb = sys.exc_info()[2]
return 'Traceback:\n%s' % "\n".join(traceback.format_tb(tb))
def connectWidget(widget, func):
if type(widget) == QtWidgets.QLineEdit:
widget.textChanged.connect(func)
elif type(widget) == QtWidgets.QSpinBox \
or type(widget) == QtWidgets.QDoubleSpinBox:
widget.valueChanged.connect(func)
elif type(widget) == QtWidgets.QCheckBox:
widget.stateChanged.connect(func)
elif type(widget) == QtWidgets.QComboBox:
widget.currentIndexChanged.connect(func)
else:
log.warning('Failed to connect %s ', str(widget.__class__.__name__))
return False
return True
def setWidgetValue(widget, val):
'''Generic setValue method for use with any typical QtWidget'''
log.verbose('Setting %s to %s' % (str(widget.__class__.__name__), val))
if type(widget) == QtWidgets.QLineEdit:
widget.setText(val)
elif type(widget) == QtWidgets.QSpinBox \
or type(widget) == QtWidgets.QDoubleSpinBox:
widget.setValue(val)
elif type(widget) == QtWidgets.QCheckBox:
widget.setChecked(val)
elif type(widget) == QtWidgets.QComboBox:
widget.setCurrentIndex(val)
else:
log.warning('Failed to set %s ', str(widget.__class__.__name__))
return False
return True
def getWidgetValue(widget):
if type(widget) == QtWidgets.QLineEdit:
return widget.text()
elif type(widget) == QtWidgets.QSpinBox \
or type(widget) == QtWidgets.QDoubleSpinBox:
return widget.value()
elif type(widget) == QtWidgets.QCheckBox:
return widget.isChecked()
elif type(widget) == QtWidgets.QComboBox:
return widget.currentIndex()