--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pygpibtoolkit/qt4/qpreferenceseditor.py Tue Feb 05 18:59:29 2008 +0100 @@ -0,0 +1,231 @@ +import os +from PyQt4 import QtCore, QtGui, uic +from PyQt4.QtCore import Qt, SIGNAL +import sip +from qpreferences import fromVariant +from qpreferences import UnicodeItem +from tools import AbstractRegister + +class WidgetMetaclass(sip.wrappertype): + _widgets = {} + def __init__(cls, name, bases, dct): + # called at class creation + super(WidgetMetaclass, cls).__init__(name, bases, dct) + if name != "BaseWidget": + WidgetRegister().add(cls) + +class BaseWidget(QtGui.QWidget): + __metaclass__ = WidgetMetaclass + _filter = None + +class WidgetRegister(AbstractRegister): + _registered_type = BaseWidget + getWidget = AbstractRegister.get_class + +form_class, base_class = uic.loadUiType(os.path.join(os.path.dirname(__file__), "qpreferences_dialog.ui")) + +class ItemValidator(QtGui.QValidator): + def __init__(self, parent, item): + QtGui.QValidator.__init__(self, parent) + self._item = item + + def validate(self, value, pos): + value = unicode(value) + if value.strip() == "": + return (self.Intermediate, pos) + if self._item.validate(value): + return (self.Acceptable, pos) + return (self.Invalid, pos) + +class BaseEditor(BaseWidget): + """ + Basic editor for preference items. Use a QLineEdit with no + validation or so... + """ + _accepts = "UnicodeItem" + def __init__(self, parent, item): + BaseWidget.__init__(self, parent) + self._item = item + self.setupUI() + + def setValue(self, value): + self._editor.setText(unicode(value)) + + def getValue(self): + return unicode(self._editor.text()) + + def setupUI(self): + self._editor = QtGui.QLineEdit(self) + self._validator = ItemValidator(self, self._item) + self._editor.setValidator(self._validator) + l = QtGui.QHBoxLayout(self) + l.setContentsMargins(0,0,0,0) + l.addWidget(self._editor, 1) + self.setFocusProxy(self._editor) + +class IntEditor(BaseEditor): + _accepts = "IntItem" + def setupUI(self): + self._editor = QtGui.QSpinBox(self) + self._editor.setMinimum(self._item._min) + self._editor.setMaximum(self._item._max) + l = QtGui.QHBoxLayout(self) + l.setContentsMargins(0,0,0,0) + l.addWidget(self._editor, 1) + self.setFocusProxy(self._editor) + + def setValue(self, value): + self._editor.setValue(int(value)) + + def getValue(self): + return self._editor.value() + +class ColorEditor(BaseEditor): + _accepts = "ColorItem" + def setupUI(self): + self._editor_pix = QtGui.QPixmap(40,30) + self._editor_pix.fill(QtGui.QColor('white')) + + self._editor_btn = QtGui.QPushButton("") + self._editor_btn.setFlat(True) + self._editor_btn.setFocusPolicy(Qt.NoFocus) + self._editor_btn.setIcon(QtGui.QIcon(self._editor_pix)) + + self._editor_edt = QtGui.QLineEdit() + self._editor_edt.setInputMask(r"\#HHHHHHhh") + fm = QtGui.QApplication.fontMetrics() + w = fm.width("#FFFFFFFF ") + self._editor_edt.setMaximumWidth(w) + + + l = QtGui.QHBoxLayout(self) + l.setContentsMargins(0,0,0,0) + l.addWidget(self._editor_edt) + l.addWidget(self._editor_btn) + l.addStretch(1) + self.setFocusProxy(self._editor_edt) + assert self.connect(self._editor_btn, SIGNAL("pressed()"), + self.chooseColor) + assert self.connect(self._editor_edt, SIGNAL("editingFinished()"), + self.colorEdited) + + def setValue(self, value): + if isinstance(value, tuple): + color = self._item._type(*value) + elif isinstance(value, self._item._type): + color = value + elif isinstance(value, long): + color = self._item._type(value) + alpha = value >> 24 + color.setAlpha(alpha) + else: + color = self._item._type(value) + + rgba = color.getRgb() + colorname = ("#"+"%02X"*4)%rgba + self._rgba = rgba + self._editor_pix.fill(color) + self._editor_btn.setIcon(QtGui.QIcon(self._editor_pix)) + self._editor_edt.setText(colorname) + + def getValue(self): + return self._item._type(*self._rgba) + + def colorEdited(self): + val = unicode(self._editor_edt.text()) + if len(val) == 7: + val += "FF" # miss alpha channel + val = val[1:] + val = [val[2*i:2*i+2] for i in range(len(val)/2)] + val = [int(x, 16) for x in val] + + self._rgba = tuple(val) + self.setValue(self._rgba) + + + def chooseColor(self): + newcolor, ok = QtGui.QColorDialog.getRgba(self.getValue().rgba(), self) + if ok: + self.setValue(newcolor) + +class PreferencesEditor(QtGui.QDialog, form_class): + def __init__(self, preferences, parent=None): + QtGui.QDialog.__init__(self, parent) + self.setupUi(self) + self._prefs = preferences + self.buildUI() + + def buildUI(self): + mainw = self.centralTab + for i in range(mainw.count()): + mainw.removeTab(0) + + eds = {} + self._editors = eds + + wr = WidgetRegister() + if len(self._prefs.groups)>1: + for group in self._prefs.groups: + if group is None: + continue + w = QtGui.QWidget(mainw) + mainw.addTab(w, group) + g = QtGui.QGridLayout(w) + g.setVerticalSpacing(2) + for i, k in enumerate(self._prefs.keys(group)): + name = self._prefs.getName(k) + item = self._prefs.getItem(k) + if not name: + name = k + l = QtGui.QLabel(name, w) + g.addWidget(l, i, 0) + if self._prefs.getDescription(k): + l.setToolTip(self._prefs.getDescription(k)) + wcls = wr.getWidget(item) + e = wcls(w, item) + eds[k] = e + g.addWidget(e, i, 1) + val = self._prefs.getPref(k) + if val is None: + val = '' + e.setValue(val) + + # add blank space + g.addWidget(QtGui.QWidget(w), i+1, 0) + g.setRowStretch(i+1,1) + g.setColumnStretch(1,1) + + def accept(self): + p=self._prefs + for k in self._editors: + newval = self._editors[k].getValue() + p.setPref(k, newval) + return QtGui.QDialog.accept(self) + +if __name__ == '__main__': + from qpreferences import AbstractPreferences, UnicodeItem, IntItem, BaseItem + from qpreferences import ColorItem + class TestPreferences(AbstractPreferences): + ORGANISATION="Logilab" + APPLICATION="test_qpref_editor" + + device = UnicodeItem('/dev/ttyUSB0', name="the device", + group="GPIB settings") + address = IntItem(5, name="address", + description="GPIB address of the plotter", + group="GPIB settings", + min=0, max=16) + other = UnicodeItem('toto', name="other stuff", + group="General") + color = ColorItem(default='red',name="Colour", + group="General") + _pos = BaseItem(None) + _size = BaseItem(None) + _appState = BaseItem(None) + + a = QtGui.QApplication([]) + + prefs = TestPreferences() + w = PreferencesEditor(prefs) + w.show() + a.exec_()