class QErrorMessage(QtCore.QObject): LEVEL_ERROR = logging.ERROR LEVEL_WARNING = logging.WARNING LEVEL_INFO = logging.INFO LEVEL_BUSY = -1 def __init__(self, message, level): QtCore.QObject.__init__(self) self._message = message self._level = level changed = qt_compat.Signal() level = qt_compat.Property(int, lambda self: self._level, notify=changed) message = qt_compat.Property(unicode, lambda self: self._message, notify=changed) def __repr__(self): return "%s.%s(%r, %r)" % (__name__, self.__class__.__name__, self._message, self._level)
class AutoQObject(QtCore.QObject): def __init__(self, **initKwargs): QtCore.QObject.__init__(self) def __repr__(self): return '<%s (wrapping %r)>' % ( kwargs.get('name', self.__class__.__name__), obj, ) changed = qt_compat.Signal() for key, value in members: qTypeName = obj_to_qtype(value) def _get(key): def _get(self): return getattr(obj, key) return _get def _set(key): if key == key.upper(): def _set_constant(self, v): raise NotImplementedError() return _set_constant else: def _set_mutable(self, v): setattr(obj, key, v) getattr(self, "changed").emit() return _set_mutable setter = locals()['_set_'+key] = _set(key) getter = locals()['_get_'+key] = _get(key) locals()[key] = qt_compat.Property(qTypeName, getter, setter, notify=changed) del _get, _set, getter, setter, qTypeName
class AutoQObject(QtCore.QObject): def __init__(self, **initKwargs): QtCore.QObject.__init__(self) for key, val in classDef: setattr(self, '_'+key, initKwargs.get(key, val())) def __repr__(self): qTypeNames = ( '%s=%r' % (key, getattr(self, '_'+key)) for key, qTypeName in classDef ) return '<%s (%s)>' % ( kwargs.get('name', self.__class__.__name__), ', '.join(qTypeNames), ) for key, qTypeName in classDef: nfy = locals()['_nfy_'+key] = qt_compat.Signal() def _get(key): def f(self): return self.__dict__['_'+key] return f def _set(key): def f(self, qTypeName): setattr(self, '_'+key, qTypeName) getattr(self, '_nfy_'+key).emit() return f setter = locals()['_set_'+key] = _set(key) getter = locals()['_get_'+key] = _get(key) locals()[key] = qt_compat.Property(qTypeName, getter, setter, notify=nfy) del nfy, _get, _set, getter, setter
class FileSystemModel(QtCore.QAbstractListModel): """ Wrapper around QtGui.QFileSystemModel """ FILEINFOS = [ "fileName", "isDir", "filePath", "completeSuffix", "baseName", ] EXTINFOS = [ "type", ] ALLINFOS = FILEINFOS + EXTINFOS def __init__(self, model, path): QtCore.QAbstractListModel.__init__(self) self._path = path self._model = model self._rootIndex = self._model.index(self._path) self._child = None self.setRoleNames(dict(enumerate(self.ALLINFOS))) self._model.directoryLoaded.connect(self._on_directory_loaded) childChanged = qt_compat.Signal(QtCore.QObject) def _child(self): assert self._child is not None return self._child child = qt_compat.Property(QtCore.QObject, _child, notify=childChanged) backendChanged = qt_compat.Signal() def _parent(self): finfo = self._model.fileInfo(self._rootIndex) return finfo.fileName() parent = qt_compat.Property(str, _parent, notify=backendChanged) @qt_compat.Slot(str) @misc.log_exception(_moduleLogger) def browse_to(self, path): if self._child is None: self._child = FileSystemModel(self._model, path) else: self._child.switch_to(path) self.childChanged.emit() return self._child @qt_compat.Slot(str) @misc.log_exception(_moduleLogger) def switch_to(self, path): with scoped_model_reset(self): self._path = path self._rootIndex = self._model.index(self._path) self.backendChanged.emit() def __len__(self): return self._model.rowCount(self._rootIndex) def __getitem__(self, key): return self._model.index(key, 0, self._rootIndex) def __iter__(self): return (self[i] for i in xrange(len(self))) def rowCount(self, parent=QtCore.QModelIndex()): return len(self) def data(self, index, role): if index.isValid() and 0 <= role and role < len(self.ALLINFOS): internalIndex = self._translate_index(index) info = self._model.fileInfo(internalIndex) if role < len(self.FILEINFOS): field = self.FILEINFOS[role] value = getattr(info, field)() else: role -= len(self.FILEINFOS) field = self.EXTINFOS[role] if field == "type": return self._model.type(internalIndex) else: raise NotImplementedError("Out of range that was already checked") return value return None def _on_directory_loaded(self, path): if self._path == path: self.backendChanged.emit() self.reset() def _translate_index(self, externalIndex): internalIndex = self._model.index(externalIndex.row(), 0, self._rootIndex) return internalIndex
class QErrorLog(QtCore.QObject): messagePushed = qt_compat.Signal() messagePopped = qt_compat.Signal() currentMessageChanged = qt_compat.Signal() def __init__(self): QtCore.QObject.__init__(self) self._messages = [] self._nullMessage = QErrorMessage("", QErrorMessage.LEVEL_INFO) @qt_compat.Slot(str) def push_busy(self, message): _moduleLogger.debug("Entering state: %s" % message) self._push_message(message, QErrorMessage.LEVEL_BUSY) @qt_compat.Slot(str) def push_info(self, message): self._push_message(message, QErrorMessage.LEVEL_INFO) @qt_compat.Slot(str) def push_error(self, message): self._push_message(message, QErrorMessage.LEVEL_ERROR) @qt_compat.Slot(str, int) def push_message(self, message, level): self._push_message(message, level) def push_exception(self): userMessage = str(sys.exc_info()[1]) _moduleLogger.exception(userMessage) self.push_error(userMessage) @qt_compat.Slot() @qt_compat.Slot(str) def pop(self, message = None): if message is None: del self._messages[0] else: _moduleLogger.debug("Exiting state: %s" % message) messageIndex = [ i for (i, error) in enumerate(self._messages) if error.message == message ] # Might be removed out of order if messageIndex: del self._messages[messageIndex[0]] self.messagePopped.emit() self.currentMessageChanged.emit() def peek_message(self): if self._messages: return self._messages[0] else: return self._nullMessage currentMessage = qt_compat.Property(QtCore.QObject, lambda self: self.peek_message(), notify=currentMessageChanged) hasMessages = qt_compat.Property(bool, lambda self: bool(self._messages), notify=currentMessageChanged) def _push_message(self, message, level): self._messages.append(QErrorMessage(message, level)) # Sort is defined as stable, so this should be fine self._messages.sort(key=lambda x: x.level) self._messages.reverse() self.messagePushed.emit() self.currentMessageChanged.emit() def __len__(self): return len(self._messages)