# HG changeset patch # User David Douard # Date 1202150988 -3600 # Node ID 8becd52c2171a6def9dfc54a47722f6b948b4a82 # Parent 73bd2fe8100531fd8ec78f64a132c42af85532cd refactoring in progress diff -r 73bd2fe81005 -r 8becd52c2171 HP3562A/__init__.py --- a/HP3562A/__init__.py Mon Feb 04 19:19:57 2008 +0100 +++ b/HP3562A/__init__.py Mon Feb 04 19:49:48 2008 +0100 @@ -14,7 +14,7 @@ """ import struct import re -import gpib +import pygpib as gpib import numpy ######################################## diff -r 73bd2fe81005 -r 8becd52c2171 HP3562A/q3562A.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HP3562A/q3562A.py Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,346 @@ +# + +import os, sys +import time +import glob + +from PyQt4 import QtGui, QtCore, uic +from PyQt4.QtCore import SIGNAL, Qt + +if "-m" in sys.argv: + from dump_datablock_mockup import HP3562dumper +else: + from dump_datablock import HP3562dumper +import q3562A_rc + +ldir = os.path.abspath(os.path.dirname(__file__)) +sys.path.append(ldir) +form_class, base_class = uic.loadUiType(os.path.join(ldir, "q3562A.ui")) + +from qpreferences import BaseItem, IntItem, UnicodeItem, ColorItem +from qpreferences import PointItem, SizeItem, ByteArrayItem +from qpreferences import AbstractPreferences +from qpreferenceseditor import PreferencesEditor + +from tools import str_num_cmp + +class Preferences(AbstractPreferences): + ORGANISATION="Logilab" + APPLICATION="qgpib_plotter" + + _pos = PointItem() + _size = SizeItem() + _appState = ByteArrayItem() + + device = UnicodeItem(default='/dev/ttyUSB0', + name=u'device', + description=u'GPIB device', + group="GPIB settings") + address = IntItem(default=5, min=0, max=16, + name=u'GPIB address', + group="GPIB settings") + + background = ColorItem(default=QtGui.QColor("white"), + name="Background", + group="Colors") + color0 = ColorItem(default=QtGui.QColor("black"), + name="Pen #0", + group="Colors") + color1 = ColorItem(default=QtGui.QColor("green"), + name="Pen #1", + group="Colors") + color2 = ColorItem(default=QtGui.QColor("red"), + name="Pen #2", + group="Colors") + color3 = ColorItem(default=QtGui.QColor("blue"), + name="Pen #3", + group="Colors") + color4 = ColorItem(default=QtGui.QColor("yellow"), + name="Pen #4", + group="Colors") + color5 = ColorItem(default=QtGui.QColor("cyan"), + name="Pen #5", + group="Colors") + color6 = ColorItem(default=QtGui.QColor("magenta"), + name="Pen #6", + group="Colors") + color7 = ColorItem(default=QtGui.QColor("darkred"), + name="Pen #7", + group="Colors") + +class QtHPGLPlotter(QtGui.QMainWindow, form_class): + def __init__(self, parent=None): + QtGui.QMainWindow.__init__(self, parent) + self._plots = {} + self._prefs = Preferences() + self.setupUi() + self.initializeGPIB() + if self._prefs._pos: + self.move(self._prefs._pos) + if self._prefs._size: + self.resize(self._prefs._size) + if self._prefs._appState: + self.restoreState(self._prefs._appState) + self.readPreferences() + + def readPreferences(self): + bg = self._prefs.background + if bg and bg.isValid(): + self.plotterWidget.qview.setBackgroundBrush(QtGui.QBrush(bg)) + pen_colors = [self._prefs["color%d"%i] for i in range(8)] + self.plotterWidget.pen_colors = pen_colors + + def replotCurrent(self): + self.currentPlotChanged(self.plotsView.currentIndex()) + + def setupUi(self): + form_class.setupUi(self, self) # call qtdesigner generated form creation + # actions defined in designer + self.connect(self.actionPreferences, SIGNAL('triggered(bool)'), + self.preferencesTriggered) + self.connect(self.actionQuit, SIGNAL('triggered(bool)'), + self.quitTriggered) + self.actionQuit.setShortcut(QtGui.QKeySequence(u'Ctrl+Q')) + self.connect(self.actionOpen, SIGNAL('triggered(bool)'), + self.openTriggered) + self.actionOpen.setShortcut(QtGui.QKeySequence(u'Ctrl+O')) + self.connect(self.actionSave, SIGNAL('triggered(bool)'), + self.saveTriggered) + self.actionSave.setShortcut(QtGui.QKeySequence(u'Ctrl+S')) + self.connect(self.actionSaveAs, SIGNAL('triggered(bool)'), + self.saveAsTriggered) + + self.plotterWidget = QHPGLPlotterWidget(self) + self.setCentralWidget(self.plotterWidget) + + self.connect(self.captureButton, SIGNAL("toggled(bool)"), + self.captureToggled) + + self._plots_list = QtGui.QStringListModel() + self.plotsView.setModel(self._plots_list) + self.connect(self.plotsView, SIGNAL('activated(const QModelIndex&)'), + self.currentPlotChanged) + self.connect(self.plotsView.selectionModel(), + SIGNAL('currentChanged(const QModelIndex&, const QModelIndex&)'), + self.currentPlotChanged) + + def currentPlotChanged(self, index, old_index=None): + if index.isValid(): + value = unicode(self.plotsView.model().data(index, Qt.DisplayRole).toString()) + + self.plotterWidget.clear() + self.plotterWidget.parse(self._plots[value]) + + def preferencesTriggered(self, checked=False): + PreferencesEditor(self._prefs, self).exec_() + self.readPreferences() + self.replotCurrent() + + def quitTriggered(self, checked=False): + self.close() + + def closeEvent(self, event): + if 1: + #if self.promptForSave(): + self._prefs._pos = self.pos() + self._prefs._size = self.size() + self._prefs._appState = self.saveState() + event.accept() + else: + event.ignore() + + def openTriggered(self, checked=False): + filenames = QtGui.QFileDialog.getOpenFileNames(self, "Open a HPGL file to display", '.', 'HPGL files (*.plt)\nAll files (*)') + self.openFiles(filenames) + self.displayFirst() + + def displayFirst(self): + if not self.plotsView.currentIndex().isValid(): + self.plotsView.setCurrentIndex(self.plotsView.model().index(0, 0)) + + def openFiles(self, filenames): + ok = False + for filename in filenames: + filename = str(filename) + if os.path.exists(filename): + data = open(filename).read() + name = os.path.basename(filename) + name = os.path.splitext(name)[0] + lst = self.plotsView.model().stringList() + lst.append(name) + self._plots[name] = data + self.plotsView.model().setStringList(lst) + ok = True + return ok + + def plotReceived(self, num): + self._receiving = False + self.setReceivingLed() + plot, timestamp = self.captureThread.getPlot(num) + name = "plot_%s"%(num) + lst = self.plotsView.model().stringList() + lst.append(name) + self._plots[name] = plot + self.plotsView.model().setStringList(lst) + + def plotStarted(self): + self._receiving = True + self.setReceivingLed() + + def saveTriggered(self, checked=False): + print "save" + + def saveAsTriggered(self, checked=False): + index = self.plotsView.selectionModel().currentIndex() + if index.isValid(): + filename = QtGui.QFileDialog.getSaveFileName(self, "Selecte a file name to save HPGL file", '.', 'HPGL files (*.plt)\nAll files (*)') + n = index.row() + value = unicode(self.plotsView.model().data(index, Qt.DisplayRole).toString()) + open(filename, 'w').write(self._plots[value]) + + + def initializeGPIB(self): + self._online = False + try: + self.gpib_plotter = QGPIBplotter(device=self._prefs.device, + address=self._prefs.address, + ) + self.captureThread = GPIBReceiver(self.gpib_plotter) + self.connect(self.captureThread, SIGNAL('plotReceived(int)'), + self.plotReceived) + self.connect(self.captureThread, SIGNAL('plotStarted()'), + self.plotStarted) + self.captureThread.start() + except Exception, e: + #print e + self.gpib_plotter = None + self.setCaptureLed() + + def captureToggled(self, state): + if state: + if self.gpib_plotter is None: + self.initializeGPIB() + if self.gpib_plotter is None: + QtGui.QMessageBox.critical(self, self.tr("GPIB error"), + self.tr("Unable to initialize GPIB connection.
Please check your GPIB dongle and settings.")) + self._online = False + self.setCaptureLed() + return + self._online = True + self.captureThread.startCapture() + else: + if self.captureThread: + self.captureThread.stopCapture() + self._online = False + self.setCaptureLed() + + def setCaptureLed(self): + if self._online: + icn = QtGui.QIcon(':/icons/led_green.svg') + else: + icn = QtGui.QIcon(':/icons/led_green_off.svg') + self.captureButton.setIcon(icn) + self.captureButton.setChecked(self._online) + + def setReceivingLed(self): + if self._receiving: + icn = QtGui.QIcon(':/icons/led_red.svg') + else: + icn = QtGui.QIcon(':/icons/led_red_off.svg') + self.receivingButton.setIcon(icn) + +class QGPIBplotter(GPIBplotter): + def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, + address=5): + GPIBplotter.__init__(self, device, baudrate, timeout, address) + self.emitter = None + + def plotStarted(self): + if self.emitter: + self.emitter.emit(SIGNAL('plotStarted()')) + #self.emitter.msleep(1) + +class GPIBReceiver(QtCore.QThread): + def __init__(self, cnx): + QtCore.QThread.__init__(self) + self.gpibplotter = cnx + self.gpibplotter.emitter = self + + self._cancelmutex = QtCore.QMutex() + self._cancel = False + #self._nreceived = 0 + self._plotsmutex = QtCore.QMutex() + self._plots = [] + self._startstopmutex = QtCore.QMutex() + self._startstop = QtCore.QWaitCondition() + self._capturing = False + + def cancel(self): + self._cancelmutex.lock() + self._cancel = True + self._cancelmutex.unlock() + + def startCapture(self): + self._startstop.wakeOne() + + def stopCapture(self): + self._startstopmutex.lock() + self._capturing = False + self._startstopmutex.unlock() + + def run(self): + while 1: + self._cancelmutex.lock() + if self._cancel: + return + self._cancelmutex.unlock() + self._startstopmutex.lock() + if not self._capturing: + self._startstop.wait(self._startstopmutex) + self._capturing = True + self._startstopmutex.unlock() + + plot = self.gpibplotter.load_plot(wait_timeout=0.1) + timestamp = time.time() + if plot: + self._plotsmutex.lock() + self._plots.append((plot, timestamp)) + n = len(self._plots) + self._plotsmutex.unlock() + self.emit(SIGNAL('plotReceived(int)'), n-1) + self.msleep(10) + + def getPlot(self, num): + self._plotsmutex.lock() + try: + return self._plots[num] + finally: + self._plotsmutex.unlock() + +def main(): + import optparse + opt = optparse.OptionParser('A simple PyQt4 HP7470A GPIB plotter emulator for USB-GPIB bundle (ProLogix)') + opt.add_option('-m', '--mockup', default=False, + action="store_true", + dest='mockup', + help='Use a pseudo GPIB connection (for test purpose)', + ) + opt.add_option('-v', '--verbose', default=False, + action="store_true", + dest="verbose", + help="Verbose mode",) + + options, argv = opt.parse_args(sys.argv) + + a = QtGui.QApplication(argv) + w = QtHPGLPlotter() + files = [f for f in argv[1:] if os.path.isfile(f)] + files.sort(cmp=str_num_cmp) + if w.openFiles(files): + w.displayFirst() + + w.show() + a.exec_() + +if __name__ == '__main__': + main() diff -r 73bd2fe81005 -r 8becd52c2171 HP3562A/q3562A.ui --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HP3562A/q3562A.ui Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,179 @@ + + MainWindow + + + + 0 + 0 + 507 + 492 + + + + MainWindow + + + + + + 0 + 0 + 507 + 25 + + + + + &File + + + + + + + + + + Edit + + + + + + + + + + 1 + + + + + 4 + + + 1 + + + 4 + + + 1 + + + 1 + + + + + + + + 0 + 29 + + + + get trace + + + + + + + 16 + 16 + + + + true + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 0 + 29 + + + + get status + + + true + + + + + + + + 0 + 29 + + + + get coord + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + &Open + + + + + &Save + + + + + Save as... + + + + + &Quit + + + + + Preferences + + + + + + + + diff -r 73bd2fe81005 -r 8becd52c2171 bin/read_coord --- a/bin/read_coord Mon Feb 04 19:19:57 2008 +0100 +++ b/bin/read_coord Mon Feb 04 19:49:48 2008 +0100 @@ -1,4 +1,9 @@ #!/usr/bin/python -from HP3562A.coord_decoder import main +import sys, os +try: + from HP3562A.coord_decoder import main +except ImportError: + sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) + from HP3562A.coord_decoder import main main() diff -r 73bd2fe81005 -r 8becd52c2171 bin/read_state --- a/bin/read_state Mon Feb 04 19:19:57 2008 +0100 +++ b/bin/read_state Mon Feb 04 19:49:48 2008 +0100 @@ -1,4 +1,9 @@ #!/usr/bin/python -from HP3562A.state_decoder import main +import sys, os +try: + from HP3562A.state_decoder import main +except ImportError: + sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) + from HP3562A.state_decoder import main main() diff -r 73bd2fe81005 -r 8becd52c2171 bin/read_trace --- a/bin/read_trace Mon Feb 04 19:19:57 2008 +0100 +++ b/bin/read_trace Mon Feb 04 19:49:48 2008 +0100 @@ -1,4 +1,8 @@ #!/usr/bin/python - -from HP3562A.trace_decoder import main +import sys, os +try: + from HP3562A.trace_decoder import main +except ImportError: + sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) + from HP3562A.trace_decoder import main main() diff -r 73bd2fe81005 -r 8becd52c2171 plotter/hpgl_plotter.qrc --- a/plotter/hpgl_plotter.qrc Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ - - - icons/led_green.svg - icons/led_green_off.svg - icons/led_red.svg - icons/led_red_off.svg - - diff -r 73bd2fe81005 -r 8becd52c2171 plotter/icons/led_green.svg --- a/plotter/icons/led_green.svg Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff -r 73bd2fe81005 -r 8becd52c2171 plotter/icons/led_green_off.svg --- a/plotter/icons/led_green_off.svg Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff -r 73bd2fe81005 -r 8becd52c2171 plotter/icons/led_red.svg --- a/plotter/icons/led_red.svg Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff -r 73bd2fe81005 -r 8becd52c2171 plotter/icons/led_red_off.svg --- a/plotter/icons/led_red_off.svg Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff -r 73bd2fe81005 -r 8becd52c2171 plotter/qpreferences.py --- a/plotter/qpreferences.py Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -import os -from PyQt4 import QtCore, QtGui, uic -from tools import AbstractRegister - -def fromVariant(v): - _cvrts = {0: lambda x:None, - 1: lambda x:x.toBool(), - 2: lambda x:x.toInt()[0], - 6: lambda x:x.toDouble()[0], - 10: lambda x:unicode(x.toString()), - 12: lambda x:x.toByteArray(), - 21: lambda x:x.toSize(), - 22: lambda x:x.toSizeF(), - 25: lambda x:x.toPoint(), - 26: lambda x:x.toPointF(), - 64: lambda x:QtGui.QFont(x), - 67: lambda x:QtGui.QColor(x), - } - t = v.userType() - return _cvrts[t](v) - -class PreferenceMetaclass(type): - _widgets = {} - def __init__(cls, name, bases, dct): - # called at class creation - super(type, cls).__init__(name, bases, dct) - if name != "BaseItem": - ItemRegister().add(cls) - -class BaseItem(object): - #__metaclass__ = PreferenceMetaclass - _id = 0 - def __init__(self, default=None, name=None, description=None, group=None): - self._default = default - self._id = BaseItem._id - self._name = name - self._description = description - self._group = group - BaseItem._id += 1 - - def validate(self, value): - return True - - def __get__(self, obj, cls): - if obj is None: #when called from the class, return the Item itself - return self - try: - return obj.getPref(self._id) - except Exception, e: - return None - - def __set__(self, obj, value): - obj.setPref(self._id, value) - -class ItemRegister(AbstractRegister): - _registered_type = BaseItem - getItem = AbstractRegister.get_class - -class PointItem(BaseItem): - _type = QtCore.QPoint - -class SizeItem(BaseItem): - _type = QtCore.QSize - -class ByteArrayItem(BaseItem): - _type = QtCore.QByteArray - -class UnicodeItem(BaseItem): - _type = unicode - def validate(self, value): - return isinstance(value, basestring) - -class IntItem(BaseItem): - _type = int - def __init__(self, default=None, name=None, description=None, group=None, min=None, max=None): - BaseItem.__init__(self, default, name, description, group) - self._min = min - self._max = max - - def validate(self, value): - try: - value = self._type(value) - except: - return False - if self._min is not None and valueself._max: - return False - return True - -class ColorItem(BaseItem): - _type = QtGui.QColor - - def validate(self, value): - try: - self._type(value) - return True - except: - return False - -class AbstractPreferences(QtCore.QObject): - def __init__(self): - QtCore.QObject.__init__(self) - self._settings = QtCore.QSettings(QtCore.QSettings.UserScope, - self.ORGANISATION, self.APPLICATION) - self._prefs = {} - self.groups = [] - keys = [] - for k in dir(self.__class__): - item = self.getItem(k) - if isinstance(item, BaseItem): - keys.append((k,item)) - keys.sort(key=lambda x: x[1]._id) - for k, item in keys: - self._prefs[item._id] = k - if item._group not in self.groups: - self.groups.append(item._group) - - def getItem(self, key): - return getattr(self.__class__, key) - #return self._prefs.get(key, None) - - def getPref(self, key): - key = self._prefs.get(key, key) - default = getattr(self.__class__, key)._default - if default is not None: - default = QtCore.QVariant(default) - else: - default = QtCore.QVariant() - val = fromVariant(self._settings.value(key, default)) - return val - - def setPref(self, key, value): - key = self._prefs.get(key, key) - self._settings.setValue(key, QtCore.QVariant(value)) - - def keys(self, group=None): - return [k for k in self._prefs.values() if not k.startswith('_') and self.getItem(k)._group == group] - - def getName(self, key): - item = getattr(self.__class__, key) - return item._name - - def getDescription(self, key): - item = getattr(self.__class__, key) - return item._description - - def __getitem__(self, key): - return getattr(self, key) - diff -r 73bd2fe81005 -r 8becd52c2171 plotter/qpreferences_dialog.ui --- a/plotter/qpreferences_dialog.ui Mon Feb 04 19:19:57 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ - - PreferencesDialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - - 0 - - - - Tab 1 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PreferencesDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - PreferencesDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -r 73bd2fe81005 -r 8becd52c2171 qt4/icons/led_green.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/icons/led_green.svg Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff -r 73bd2fe81005 -r 8becd52c2171 qt4/icons/led_green_off.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/icons/led_green_off.svg Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff -r 73bd2fe81005 -r 8becd52c2171 qt4/icons/led_red.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/icons/led_red.svg Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff -r 73bd2fe81005 -r 8becd52c2171 qt4/icons/led_red_off.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/icons/led_red_off.svg Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff -r 73bd2fe81005 -r 8becd52c2171 qt4/qpreferences.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/qpreferences.py Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,150 @@ +import os +from PyQt4 import QtCore, QtGui, uic +from tools import AbstractRegister + +def fromVariant(v): + _cvrts = {0: lambda x:None, + 1: lambda x:x.toBool(), + 2: lambda x:x.toInt()[0], + 6: lambda x:x.toDouble()[0], + 10: lambda x:unicode(x.toString()), + 12: lambda x:x.toByteArray(), + 21: lambda x:x.toSize(), + 22: lambda x:x.toSizeF(), + 25: lambda x:x.toPoint(), + 26: lambda x:x.toPointF(), + 64: lambda x:QtGui.QFont(x), + 67: lambda x:QtGui.QColor(x), + } + t = v.userType() + return _cvrts[t](v) + +class PreferenceMetaclass(type): + _widgets = {} + def __init__(cls, name, bases, dct): + # called at class creation + super(type, cls).__init__(name, bases, dct) + if name != "BaseItem": + ItemRegister().add(cls) + +class BaseItem(object): + #__metaclass__ = PreferenceMetaclass + _id = 0 + def __init__(self, default=None, name=None, description=None, group=None): + self._default = default + self._id = BaseItem._id + self._name = name + self._description = description + self._group = group + BaseItem._id += 1 + + def validate(self, value): + return True + + def __get__(self, obj, cls): + if obj is None: #when called from the class, return the Item itself + return self + try: + return obj.getPref(self._id) + except Exception, e: + return None + + def __set__(self, obj, value): + obj.setPref(self._id, value) + +class ItemRegister(AbstractRegister): + _registered_type = BaseItem + getItem = AbstractRegister.get_class + +class PointItem(BaseItem): + _type = QtCore.QPoint + +class SizeItem(BaseItem): + _type = QtCore.QSize + +class ByteArrayItem(BaseItem): + _type = QtCore.QByteArray + +class UnicodeItem(BaseItem): + _type = unicode + def validate(self, value): + return isinstance(value, basestring) + +class IntItem(BaseItem): + _type = int + def __init__(self, default=None, name=None, description=None, group=None, min=None, max=None): + BaseItem.__init__(self, default, name, description, group) + self._min = min + self._max = max + + def validate(self, value): + try: + value = self._type(value) + except: + return False + if self._min is not None and valueself._max: + return False + return True + +class ColorItem(BaseItem): + _type = QtGui.QColor + + def validate(self, value): + try: + self._type(value) + return True + except: + return False + +class AbstractPreferences(QtCore.QObject): + def __init__(self): + QtCore.QObject.__init__(self) + self._settings = QtCore.QSettings(QtCore.QSettings.UserScope, + self.ORGANISATION, self.APPLICATION) + self._prefs = {} + self.groups = [] + keys = [] + for k in dir(self.__class__): + item = self.getItem(k) + if isinstance(item, BaseItem): + keys.append((k,item)) + keys.sort(key=lambda x: x[1]._id) + for k, item in keys: + self._prefs[item._id] = k + if item._group not in self.groups: + self.groups.append(item._group) + + def getItem(self, key): + return getattr(self.__class__, key) + #return self._prefs.get(key, None) + + def getPref(self, key): + key = self._prefs.get(key, key) + default = getattr(self.__class__, key)._default + if default is not None: + default = QtCore.QVariant(default) + else: + default = QtCore.QVariant() + val = fromVariant(self._settings.value(key, default)) + return val + + def setPref(self, key, value): + key = self._prefs.get(key, key) + self._settings.setValue(key, QtCore.QVariant(value)) + + def keys(self, group=None): + return [k for k in self._prefs.values() if not k.startswith('_') and self.getItem(k)._group == group] + + def getName(self, key): + item = getattr(self.__class__, key) + return item._name + + def getDescription(self, key): + item = getattr(self.__class__, key) + return item._description + + def __getitem__(self, key): + return getattr(self, key) + diff -r 73bd2fe81005 -r 8becd52c2171 qt4/qpreferences_dialog.ui --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/qpreferences_dialog.ui Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,75 @@ + + PreferencesDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + 0 + + + + Tab 1 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PreferencesDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PreferencesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff -r 73bd2fe81005 -r 8becd52c2171 qt4/resources.qrc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt4/resources.qrc Mon Feb 04 19:49:48 2008 +0100 @@ -0,0 +1,8 @@ + + + icons/led_green.svg + icons/led_green_off.svg + icons/led_red.svg + icons/led_red_off.svg + +