class EmbeddedViewTable(QtGui.QTableView, BaseWidget, EnableLogic, EditLogic, TriggeredPillowsLogic): __metaclass__ = QWallabyMeta room = Meta.property("string") path = Meta.property("string") reverseOrder = Meta.property("bool") identifier = Meta.property("string") isList = Meta.property("bool", default=True) dbColumns = Meta.property("list") wrapInList = Meta.property("bool") sizeHints = Meta.property("dict") notSelectableIfDisabled = Meta.property("bool", default=False) doubleClickPillow = Meta.property("string", extended=True) doubleClickFeathers = Meta.property("string", extended=True) doubleClickTab = Meta.property("string", extended=True) autoResizeCells = Meta.property("bool", extended=True) minRowHeight = Meta.property("int", extended=True) minColumnWidth = Meta.property("int", extended=True) alternateRowColors = Meta.property("bool", default=False) editOnInsert = Meta.property("bool") triggers = Meta.property("list", readOnly=True, default=["", "clicked", "double-clicked", "key"]) def __init__(self, parent=None): QtGui.QTableView.__init__(self, parent) BaseWidget.__init__(self, QtGui.QTableView) EnableLogic.__init__(self) EditLogic.__init__(self, Editor, self.getData) TriggeredPillowsLogic.__init__(self) self.setSortingEnabled(False) self.horizontalHeader().setStretchLastSection(True) self._popup = None self._model = None self._actionPeer = None self._ignoreClick = False self._proxyModel = None self._selectedRow = None self._isEnabled = False # self.setAlternatingRowColors(True) self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.verticalHeader().sectionMoved.connect(self.reorderRows) self.verticalHeader().setMovable(False) self.verticalHeader().sectionClicked.connect(self._itemClicked) self.clicked.connect(self._itemClicked) self.doubleClicked.connect(self._itemDoubleClicked) self._autoColumns = [] self._imageDelegate = ImageDelegate() self._progressDelegate = ProgressDelegate() self._comboDelegates = [] def editCell(self, row, col): idx = self._model.createIndex(row, col) if self._proxyModel is not None: idx = self._proxyModel.mapFromSource(idx) QtGui.QTableView.setCurrentIndex(self, idx) QtGui.QTableView.edit(self, idx, QtGui.QTableView.AllEditTriggers, None) def selectRow(self, row): if self._proxyModel is not None: idx = self._model.createIndex(row, 0) idx = self._proxyModel.mapFromSource(idx) row = idx.row() QtGui.QTableView.selectRow(self, row) def newData(self): if not self.autoResizeCells: return self.horizontalHeader().resizeSections(QtGui.QHeaderView.ResizeToContents) self.verticalHeader().resizeSections(QtGui.QHeaderView.ResizeToContents) self.horizontalHeader().setStretchLastSection(True) # for c in self._autoColumns: # self.horizontalHeader().setResizeMode(c, QtGui.QHeaderView.ResizeToContents) if len(self._autoColumns) > 0: self.verticalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents) def _resolve(self, value, **ka): self._model.resolve(data=value, **ka) def getData(self): self._model.getData() def deregister(self, remove=False): EnableLogic.deregister(self, remove) EditLogic.deregister(self, remove) TriggeredPillowsLogic.deregister(self, remove) if self._model: FXUI.mainWindow.settings().setValue(self._template + "_headerState", self.horizontalHeader().saveState()) if self._model: self._model.destroyPeers(remove) if self._actionPeer: self._actionPeer.destroy(remove) self._actionPeer = None def reorderRows(self, row, oldIndex, newIndex): if not self._isEnabled: return if self._model != None: self._model.reorderRows(row, oldIndex, newIndex) def register(self): EnableLogic.register(self) EditLogic.register(self) TriggeredPillowsLogic.register(self) self.setAlternatingRowColors(self.alternateRowColors) if ( isinstance(self.dbColumns, list) and len(self.dbColumns) > 0 and isinstance(self.dbColumns[0], (str, unicode)) ): columns, labels = FX.splitList(self.dbColumns, ":") types, args, columns = FX.extractType(columns, json=False) dbColumns = [] # convert old format for i in range(len(columns)): dbColumns.append({"path": columns[i], "label": labels[i], "type": types[i], "type-args": args[i]}) self.dbColumns = dbColumns self._columns = [] self._labels = [] self._types = [] for cfg in self.dbColumns: if cfg is None: continue self._columns.append(cfg.get("path", None)) self._labels.append(cfg.get("label", None)) self._types.append(FX.convertType(cfg.get("type", None))) self._autoColumns = [] self._comboDelegate = [] col = 0 for t in self._types: hasDelegate = False if t is None: col = col + 1 continue if isinstance(t, dict): for k, v in t.items(): if not hasDelegate and len(v) > 0 and v[0] == ":": self.setItemDelegateForColumn(col, self._imageDelegate) self._autoColumns.append(col) hasDelegate = True elif "image" in t: self.setItemDelegateForColumn(col, self._imageDelegate) self._autoColumns.append(col) hasDelegate = True elif t == "progress": self.setItemDelegateForColumn(col, self._progressDelegate) elif t == "comboedit": self._comboDelegate.append(ComboBoxDelegate(self, col)) self.setItemDelegateForColumn(col, self._comboDelegate[-1]) col = col + 1 from wallaby.frontends.qt.models.embeddedViewTableModel import EmbeddedViewTableModel self._model = EmbeddedViewTableModel( self, self.room, self.path, self.dbColumns, conflictCB=self._conflict, isList=self.isList, identifier=self.identifier, reverseOrder=self.reverseOrder, minRowHeight=self.minRowHeight, minColumnWidth=self.minColumnWidth, wrapInList=self.wrapInList, sizeHints=self.sizeHints, editOnInsert=self.editOnInsert, ) if FXUI.mainWindow.options() != None and FXUI.mainWindow.options().app != "inspector": self._proxyModel = QtGui.QSortFilterProxyModel(self) self._proxyModel.setSourceModel(self._model) self._proxyModel.setFilterRegExp( QtCore.QRegExp("^(?!inspector-|itest-)", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp2) ) # proxyModel.setFilterRegExp(QtCore.QRegExp("^inspector", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp2)) # proxyModel.setFilterKeyColumn(0) self.setModel(self._proxyModel) else: self.setModel(self._model) if self.doubleClickPillow != None: self._actionPeer = ActionButtonPeer( self.room, self.doubleClickPillow, self.doubleClickFeathers, tab=self.doubleClickTab, translate=True ) QtCore.QTimer.singleShot(0, self.restoreSettings) def restoreSettings(self): headerState = FXUI.mainWindow.settings().value(self._template + "_headerState") # if headerState: self.horizontalHeader().restoreState(headerState) def _itemDoubleClicked(self, index): # FIXME self._ignoreClick = True self.trigger("double-clicked") if self._actionPeer: self._actionPeer.buttonClicked(index.row()) def _itemClicked(self, index): if self._ignoreClick: self._ignoreClick = False # return self.resetSelection() self.trigger("clicked") def setEnabled(self, enabled): self._isEnabled = enabled self.verticalHeader().setMovable(enabled) if self.notSelectableIfDisabled: QtGui.QTableView.setEnabled(self, enabled) return if not enabled: self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) else: self.setEditTriggers(QtGui.QAbstractItemView.DoubleClicked) def keyPressEvent(self, event): import wallaby.FXUI as FXUI if self.trigger("key", FXUI.key_event_to_name(event)): event.accept() else: event.ignore() QtGui.QTableView.keyPressEvent(self, event) if self.state() != QtGui.QAbstractItemView.EditingState: self.resetSelection() # def selectionChanged(self, selected, deselected): # QtGui.QTableView.selectionChanged(self, selected, deselected) # sel = self.selectionModel().selectedIndexes() # if len(sel) == 0: # self._model.doSelect(None) # else: # self._model.doSelect(sel[0].row()) def resetSelection(self): sel = self.selectionModel().selectedIndexes() if len(sel) == 0: self._model.doSelect(None) else: if self._proxyModel != None: sel = self._proxyModel.mapToSource(sel[0]) else: sel = sel[0] self._selectedRow = sel.row() self._model.doSelect(self._selectedRow) self.scrollTo(sel)
def register(self): EnableLogic.register(self) EditLogic.register(self) TriggeredPillowsLogic.register(self) self.setAlternatingRowColors(self.alternateRowColors) if ( isinstance(self.dbColumns, list) and len(self.dbColumns) > 0 and isinstance(self.dbColumns[0], (str, unicode)) ): columns, labels = FX.splitList(self.dbColumns, ":") types, args, columns = FX.extractType(columns, json=False) dbColumns = [] # convert old format for i in range(len(columns)): dbColumns.append({"path": columns[i], "label": labels[i], "type": types[i], "type-args": args[i]}) self.dbColumns = dbColumns self._columns = [] self._labels = [] self._types = [] for cfg in self.dbColumns: if cfg is None: continue self._columns.append(cfg.get("path", None)) self._labels.append(cfg.get("label", None)) self._types.append(FX.convertType(cfg.get("type", None))) self._autoColumns = [] self._comboDelegate = [] col = 0 for t in self._types: hasDelegate = False if t is None: col = col + 1 continue if isinstance(t, dict): for k, v in t.items(): if not hasDelegate and len(v) > 0 and v[0] == ":": self.setItemDelegateForColumn(col, self._imageDelegate) self._autoColumns.append(col) hasDelegate = True elif "image" in t: self.setItemDelegateForColumn(col, self._imageDelegate) self._autoColumns.append(col) hasDelegate = True elif t == "progress": self.setItemDelegateForColumn(col, self._progressDelegate) elif t == "comboedit": self._comboDelegate.append(ComboBoxDelegate(self, col)) self.setItemDelegateForColumn(col, self._comboDelegate[-1]) col = col + 1 from wallaby.frontends.qt.models.embeddedViewTableModel import EmbeddedViewTableModel self._model = EmbeddedViewTableModel( self, self.room, self.path, self.dbColumns, conflictCB=self._conflict, isList=self.isList, identifier=self.identifier, reverseOrder=self.reverseOrder, minRowHeight=self.minRowHeight, minColumnWidth=self.minColumnWidth, wrapInList=self.wrapInList, sizeHints=self.sizeHints, editOnInsert=self.editOnInsert, ) if FXUI.mainWindow.options() != None and FXUI.mainWindow.options().app != "inspector": self._proxyModel = QtGui.QSortFilterProxyModel(self) self._proxyModel.setSourceModel(self._model) self._proxyModel.setFilterRegExp( QtCore.QRegExp("^(?!inspector-|itest-)", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp2) ) # proxyModel.setFilterRegExp(QtCore.QRegExp("^inspector", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp2)) # proxyModel.setFilterKeyColumn(0) self.setModel(self._proxyModel) else: self.setModel(self._model) if self.doubleClickPillow != None: self._actionPeer = ActionButtonPeer( self.room, self.doubleClickPillow, self.doubleClickFeathers, tab=self.doubleClickTab, translate=True ) QtCore.QTimer.singleShot(0, self.restoreSettings)