def drop_canvas(self, key: QModelIndex): # TODO: do we use this anywhere? return intent = key.data(IntentsModel.intent_role) canvas = key.data(EnsembleModel.canvas_role) if canvas: canvas_can_be_removed = canvas.unrender(intent) if canvas_can_be_removed: key.model().removeRow(key.row(), key.parent()) key.model().layoutChanged.emit()
def _index_is_on_our_branch(self, index: QModelIndex) -> bool: # the tree is only traversed towards the root if index.internalPointer().type not in (NodeType.ITER, NodeType.REAL): return False while index.isValid() and index.internalPointer() is not None: node = index.internalPointer() if node.type == NodeType.ITER and node.row() != self._iter: return False index = index.parent() return True
def mapFromSource(self, sourceIndex: QModelIndex) -> QModelIndex: if not sourceIndex.isValid(): return QModelIndex() source_node = sourceIndex.internalPointer() if source_node is None or source_node.type != NodeType.JOB: return QModelIndex() if not self._index_is_on_our_branch(sourceIndex.parent()): return QModelIndex() return self.index(source_node.row(), sourceIndex.column(), QModelIndex())
def setData(self, index: QModelIndex, value: Any, role: Qt.ItemDataRole = Qt.EditRole) -> bool: """Re-implemented to set the associated item's itemData property and emit dataChanged. Special case for CheckStateRole handles checking of all children (recursively) and all ancestors to appropriate check states (including PartiallyChecked states). Returns True if the data was successfully set. """ if not index.isValid(): return False item = self.getItem(index) if role == Qt.CheckStateRole: item_checked = self._determineCheckState(item) # Subsequently set all childrens' check states self._setItemAndChildrenCheckState(item, item_checked) self._setParentItemCheckState(item, item_checked) highest_parent_index = index.parent() while highest_parent_index.parent().isValid(): highest_parent_index = highest_parent_index.parent() def find_lowest_index(idx): itm = self.getItem(idx) if itm.hasChildren(): lowest_child_index = self.index(item.childCount() - 1, 0, idx) find_lowest_index(lowest_child_index) return idx lowest_sibling_index = idx.siblingAtRow( itm.parent().childCount() - 1) if self.getItem(lowest_sibling_index).hasChildren(): find_lowest_index(lowest_sibling_index) else: return lowest_sibling_index lowest_index = find_lowest_index(index) # self.dataChanged.emit(index, index, [role]) print("TreeModel") print( f"\t{highest_parent_index.data()}, {lowest_index.data()}, {role}\n" ) self.dataChanged.emit(highest_parent_index, lowest_index, [role]) return True else: return self._setData(index, value, role)
def setupModelData(self, parent, data): #index = self.currentIndex() index = QModelIndex() if not self.insertRow(index.row() + 1, index.parent()): print("Ups") return # Two strings, two checkboxes and a hidden data for column in range(self.columnCount(index.parent()) - 3): child = self.index(index.row() + 1, column, index.parent()) self.setData(child, "Root", Qt.EditRole) column = self.columnCount(index.parent()) - 3 child = self.index(index.row() + 1, column, index.parent()) self.setData(child, Qt.Unchecked, Qt.CheckStateRole) column = self.columnCount(index.parent()) - 2 child = self.index(index.row() + 1, column, index.parent()) self.setData(child, Qt.Unchecked, Qt.CheckStateRole) column = self.columnCount(index.parent()) - 1 child = self.index(index.row() + 1, column, index.parent()) self.setData(child, data, Qt.UserRole) return
def resolveChecks(self, index: QModelIndex): """ Logic that controls how a clicked item and children items are checked and unchecked. When the clicked item is checked or unchecked (and when any children need to be checked or unchecked), this implicitly emits the itemChanged() signal (since the Qt.CheckStatRole data is changed). This is captured by the HintTabView to visualize and remove Hints as appropriate. Parameters ---------- index The index of the item that was clicked. """ if not self.model(): return item = self.model().itemFromIndex(index) # The item has been clicked and its previous state is unchecked (going to be checking items) if item.data(Qt.CheckStateRole) == Qt.Unchecked: # TODO: Potential duplicate signal emissions (dataChanged on setCheckState()) if item.isCheckable(): # First, check the clicked item item.setCheckState(Qt.Checked) # All children should be checked if the clicked item is a parent item if self.model().hasChildren(index): numChildren = self.model().rowCount(index) childrenIndexes = [ self.model().index(row, 0, index) for row in range(numChildren) ] for childIndex in childrenIndexes: childItem = self.model().itemFromIndex(childIndex) if childItem.isCheckable(): childItem.setCheckState(Qt.Checked) else: # Item is a child item parentIndex = index.parent() numChildren = self.model().rowCount(parentIndex) childrenIndexes = [ self.model().index(row, 0, parentIndex) for row in range(numChildren) ] # When all other siblings are already checked, update parent item to be checked as well if all([ self.model().itemFromIndex(index).checkState() == Qt.Checked for index in childrenIndexes ]): self.model().itemFromIndex(parentIndex).setCheckState( Qt.Checked) else: # Not all siblings are checked, indicate with parent item being partially checked self.model().itemFromIndex(parentIndex).setCheckState( Qt.PartiallyChecked) else: # The item has been clicked and its previous state is checked (going to be unchecking items) if item.isCheckable(): # First, uncheck the clicked item item.setCheckState(Qt.Unchecked) # All children should be unchecked if the clicked item is a parent item if self.model().hasChildren(index): if self.model().itemFromIndex( index).checkState() == Qt.PartiallyChecked: raise NotImplementedError numChildren = self.model().rowCount(index) childrenIndexes = [ self.model().index(row, 0, index) for row in range(numChildren) ] for childIndex in childrenIndexes: childItem = self.model().itemFromIndex(childIndex) if childItem.isCheckable(): childItem.setCheckState(Qt.Unchecked) else: # The clicked item is a child item parentIndex = index.parent() numChildren = self.model().rowCount(parentIndex) childrenIndexes = [ self.model().index(row, 0, parentIndex) for row in range(numChildren) ] # If any other sibling is unchecked, partially check the parent item if any([ self.model().itemFromIndex(index).checkState() == Qt.Checked for index in childrenIndexes ]): self.model().itemFromIndex(parentIndex).setCheckState( Qt.PartiallyChecked) else: # No other siblings are checked, so uncheck the parent item self.model().itemFromIndex(parentIndex).setCheckState( Qt.Unchecked)