pygpibtoolkit/qt4/qpreferenceseditor.py

changeset 40
1bbea188a7e5
child 42
a947d80b1afd
--- /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_()

mercurial