def nodeFromIndex(self, index: QModelIndex) -> Union[BranchNode, LeafNode]: """Utility method we define to get the node from the index. Args: index (QModelIndex): The model index Returns: Union[BranchNode, LeafNode]: Returns the node, which can either be a branch (for a dict) or a leaf (for an option key value pairs) """ if index.isValid(): # The internal pointer will return the leaf or branch node under the given parent. return index.internalPointer() return self.root
def _remove_transformation(self, index: QModelIndex): remove_transform = index.internalPointer() if remove_transform.parent_component.stored_transforms is None: remove_transform.parent_component.stored_transforms = ( remove_transform.parent_component.transforms) transformation_list = remove_transform.parent_component.stored_transforms transformation_list_index = self.parent(index) remove_pos = transformation_list.index(remove_transform) remove_transform.remove_from_dependee_chain() self.__update_link_rows() self.beginRemoveRows(transformation_list_index, remove_pos, remove_pos) transformation_list.pop(remove_pos) self.endRemoveRows() self.model.signals.transformation_changed.emit()
def removeRows(self, row: int, count: int, parent: QtCore.QModelIndex): if (not parent.isValid()): parentItem = self.root else: parentItem = parent.internalPointer() if (row < 0 or row >= parentItem.childCount()): return False self.beginRemoveRows(parent, row, row + count - 1) for i in range(0, count): if (not parentItem.removeChild(row)): break self.endRemoveRows()
def paint(self, painter: QStylePainter, option: QStyleOptionViewItem, index: QModelIndex) -> None: """ Paint a checkbox without the label. :param painter: This draws the widget. :type painter: QStylePainter :param option: Option for the style of checkbox. :type option: QStyleOptionViewItem :param index: Index for the painted checkbox. :type index: QModelIndex :return: None :rtype: NoneType """ QStyledItemDelegate.paint(self, painter, option, index) if index.column() == 1 and isinstance( index.internalPointer(), Property) and index.internalPointer().getType() == bool: checked = index.internalPointer().getValue() check_box_style_option = QtWidgets.QStyleOptionButton() if (index.flags() & QtCore.Qt.ItemIsEditable) > 0: check_box_style_option.state |= QtWidgets.QStyle.State_Enabled else: check_box_style_option.state |= QtWidgets.QStyle.State_ReadOnly if checked: check_box_style_option.state |= QtWidgets.QStyle.State_On else: check_box_style_option.state |= QtWidgets.QStyle.State_Off check_box_style_option.rect = self.getCheckBoxRect(option) check_box_style_option.state |= QtWidgets.QStyle.State_Enabled QtWidgets.QApplication.style().drawControl( QtWidgets.QStyle.CE_CheckBox, check_box_style_option, painter)
def index(self, row: int, column: int, parent: QModelIndex = None, *args, **kwargs): if not self.hasIndex(row, column, parent): return QModelIndex() parent = parent.internalPointer() if parent.isValid() else self.root child = parent.child(row) if child: return self.createIndex(row, column, child) else: return QModelIndex()
def remove_node(self, node: QModelIndex): nexus_object = node.internalPointer() if isinstance(nexus_object, Transformation): self._remove_transformation(node) if isinstance(nexus_object, Group): if nexus_object.name == TRANSFORMATIONS: for transform in nexus_object.parent_node.transforms: # type: ignore transform.remove_from_dependee_chain() nexus_object.parent_node.stored_transforms = None # type: ignore self.model.signals.transformation_changed.emit() self._remove_component(node) elif isinstance(nexus_object, LinkTransformation): self._remove_link(node) elif isinstance(nexus_object, FileWriterModule): self._remove_fw_module(node, nexus_object)
def add_link(self, node: QModelIndex): parent_item = node.internalPointer() target_index, transformation_list, component = self._get_transformation_list( node, parent_item) if transformation_list.has_link: return _, group = self._get_transformation_group(component) target_pos = len(transformation_list) self.beginInsertRows(target_index, target_pos, target_pos) group.children.append(transformation_list.link) transformation_list.link.parent_node = group transformation_list.has_link = True self.endInsertRows()
def on_network_event_list_activated(self, index: QModelIndex): # Gets activated node. activated_node = index.internalPointer() # Recover node packet list. r = Resolver('name') packets = r.get(activated_node, './packets') # Sets packet list as root index on object tree. object_tree_index = self.object_tree.model().index_from_node(packets) self.object_tree.setRootIndex(object_tree_index) # Object tree first element object_tree_first_item = self.object_tree.model().index(0, 0, object_tree_index) self.on_object_tree_clicked(object_tree_first_item)
def _remove_transformation(self, index: QModelIndex): remove_transform = index.internalPointer() transformation_list = remove_transform.parent transformation_list_index = self.parent(index) remove_pos = transformation_list.index(remove_transform) component = transformation_list.parent_component remove_transform.remove_from_dependee_chain() self.__update_link_rows() self.beginRemoveRows(transformation_list_index, remove_pos, remove_pos) component.remove_transformation(remove_transform) transformation_list.pop(remove_pos) self.endRemoveRows() self.instrument.nexus.transformation_changed.emit()
def _remove_link(self, index: QModelIndex): link = index.internalPointer() transformation_list = link.parent transformation_list_index = self.parent(index) parent_group = link.parent_node remove_pos = len(transformation_list) self.beginRemoveRows(transformation_list_index, remove_pos, remove_pos) parent_group.children.remove(link) transformation_list.has_link = False self.endRemoveRows() # Update depends on if len(transformation_list) > 0: parent_transform = transformation_list[len(transformation_list) - 1] parent_transform.depends_on = None self.model.signals.transformation_changed.emit()
def flags(self, index: QModelIndex) -> Qt.ItemFlags: out = Qt.ItemIsSelectable | Qt.ItemIsEnabled if not index.isValid(): return out | Qt.ItemIsDropEnabled data = typing.cast(_InternalData, index.internalPointer()) if "data" in data: out |= Qt.ItemIsDragEnabled else: # Can't drag folder but can drop out |= Qt.ItemIsDropEnabled if "children" not in data: out |= Qt.ItemNeverHasChildren return out
def rowCount(self, parent: QModelIndex) -> int: if not parent.isValid(): return len(self.components) parent_item = parent.internalPointer() if isinstance(parent_item, Component): return 2 elif isinstance(parent_item, TransformationsList): if parent_item.has_link: return len(parent_item) + 1 return len(parent_item) elif isinstance(parent_item, (Transformation, ComponentInfo, LinkTransformation)): return 0 raise RuntimeError("Unknown element type.")
def data(self, index: QModelIndex, role: int = ...): if not index.isValid(): return None item = index.internalPointer() col = index.column() if role == Qt.DisplayRole: if col == 0: return str(item.key()) elif col == 1: return str(item.value()) elif col == 2: return str(item.type()) return None
def parent(self, index: QModelIndex) -> QModelIndex: """ Purpose of this function is to return the parent index of the index that is provided :param index: Index that is provided. :type index: QModelIndex :return: Returns the parent index of the index provided. :rtype: QModelIndex """ if not index.isValid(): return QModelIndex() data = index.internalPointer() if data in self._propData.getCategories(): return QModelIndex() category = self._propData.getPropertyCategory(data) return self.createIndex(self._propData.getCategoryIndex(category), 0, category)
def data(self, index: QModelIndex, role: int = ...): if not index.isValid(): return None item = index.internalPointer() col = index.column() if role == Qt.DisplayRole: if col == 0: return item.key elif col == 1: value = item.value return value elif col == 2: return item.typename return None
def index(self, row: int, column: int, parent: QModelIndex = ...) -> QModelIndex: if not self.hasIndex(row, column, parent): return QModelIndex() if not parent.isValid(): parent_item = self.rootItem else: parent_item = parent.internalPointer() child_item = parent_item.child(row) if child_item: return self.createIndex(row, column, child_item) else: return QModelIndex()
def rowCount(self, parent: QModelIndex) -> int: """ Purpose of this function is to return the number of children of a given parent :param parent: Parent will tell us our column count. :type parent: QModelIndex :return: Number of rows. :rtype: int """ if not parent.isValid(): numCategories = self._propData.getNumCategories() return numCategories parentData = parent.internalPointer() if parentData in self._propData.getCategories(): return self._propData.getNumPropertiesInCategory(parentData) else: return 0
def data(self, index: QModelIndex, role: int) -> object: """ Purpose of this function is to retrieve data stored under the given role for the item referred to by the index :param index: Index that is provided. :type index: QModelIndex :param role: The given role for item referred. :type role: int :return: Data of the given role from index. :rtype: object """ if not index.isValid(): return QModelIndex() row = index.row() col = index.column() data = index.internalPointer() if role == Qt.DisplayRole: if data in self._propData.getCategories(): if col == 0: return data else: return None else: col = index.column() if col == 0: return data.getName() elif col == 1: t = data.getType() if issubclass(t, Enum): return data.getValue().name if t == bool: return None return str(data.getValue()) else: return None elif role == Qt.BackgroundRole: if data in self._propData.getCategories(): return QColor(Qt.darkRed) else: shade = row % 2 * 25 return QColor(100 + shade, 150 + shade, 200 + shade)
def rowCount(self, parent: QModelIndex) -> int: """ Get the number of rows for a given index. :param parent: the index to get the number of rows in. :type parent: QModelIndex :return: The number of rows (children) underneath the given index. :rtype: int """ if not parent.isValid(): return 2 data = parent.internalPointer() if isinstance(data, str): if data == ProjectExplorerModel.TARGET_GUI_LABEL: return 2 elif data == ProjectExplorerModel.COMPONENT_LABEL: return max(1, self._project.getTargetGUIModel().getRoot().childCount()) elif data == ProjectExplorerModel.BEHAVIOR_LABEL: return max(1, len(self._project.getTargetGUIModel().getVisibilityBehaviors())) elif data == ProjectExplorerModel.PIPELINE_LABEL: # TODO: replace this once action pipelines are implemented return 1 elif isinstance(data, Component): return data.childCount() elif isinstance(data, VisibilityBehavior): return 2 elif isinstance(data, ProjectExplorerModel.LeafIndex): return 0 elif isinstance(data, ActionPipeline): # TODO: replace this once action pipelines are implemented pass else: raise ProjectExplorerModel.UnsupportedTypeException( "Unsupported data type in index: {}".format(type(data)))
def expand_transformation_list( node: QModelIndex, component_tree_view: QTreeView, component_model: NexusTreeModel, ): current_pointer = node.internalPointer() if isinstance(current_pointer, TransformationsList) or isinstance( current_pointer, Component): component_tree_view.expand(node) if isinstance(current_pointer, Component): trans_list_index = component_model.index(1, 0, node) component_tree_view.expand(trans_list_index) else: component_index = component_model.parent(node) component_tree_view.expand(component_index) elif isinstance(current_pointer, Transformation): trans_list_index = component_model.parent(node) component_tree_view.expand(trans_list_index) component_index = component_model.parent(trans_list_index) component_tree_view.expand(component_index)
def flags(self, index: QModelIndex) -> Qt.ItemFlags: if not index.isValid(): return Qt.NoItemFlags parent_item = index.internalPointer() self.current_nxs_obj = (parent_item, index) if (isinstance(parent_item, Group) and parent_item.nx_class == NX_TRANSFORMATIONS): return Qt.ItemIsEnabled | Qt.ItemIsSelectable elif isinstance(parent_item, Component): return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDropEnabled elif isinstance(parent_item, ComponentInfo): return Qt.ItemIsEnabled | Qt.ItemIsDropEnabled elif isinstance( parent_item, (Transformation, FileWriterModule, LinkTransformation)): return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable return (Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsDropEnabled)
def flags(self, index: QModelIndex) -> object: """ Purpose of this function is to determine what can be done with a given index :param index: Index that is provided. :type index: QModelIndex :return: Returns the item flags for the given index. :rtype: ItemFlags """ if not index.isValid(): return Qt.NoItemFlags data = index.internalPointer() if data in self._propData.getCategories() or (data.isReadOnly() and data.getType() != bool): return Qt.ItemIsEnabled | Qt.ItemIsSelectable else: if index.column() == 1: return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable else: return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def parent(self, index: QModelIndex) -> QModelIndex: if not index.isValid(): return QModelIndex() parent_item = index.internalPointer() if isinstance(parent_item, Component): return QModelIndex() elif isinstance(parent_item, TransformationsList): try: return self.createIndex( self.components.index(parent_item.parent_component), 0, parent_item.parent_component, ) except ValueError as e: logging.error(e) elif isinstance(parent_item, ComponentInfo): return self.createIndex(self.components.index(parent_item.parent), 0, parent_item.parent) elif isinstance(parent_item, (Transformation, LinkTransformation)): return self.createIndex(1, 0, parent_item.parent) raise RuntimeError("Unknown element type.")
def dropMimeData( self, data: QMimeData, action: Qt.DropAction, row: int, column: int, parent: QModelIndex, ) -> bool: data = json.loads(data.data(MIMETYPE).data()) if parent.isValid(): new_folder = parent.internalPointer()["id"] else: new_folder = "" if data["parent"] == new_folder: return False self.store.add_app_to_folder(data["id"], new_folder) self.store.delete_app_from_folder(data["id"], data["parent"]) return True
def add_transformation(self, parent_index: QModelIndex, transformation_type: TransformationType): parent_item = parent_index.internalPointer() transformation_list = None parent_component = None target_pos = 0 target_index = QModelIndex() ( parent_component, target_index, target_pos, transformation_list, ) = self._get_target_position( parent_component, parent_index, parent_item, target_index, target_pos, transformation_list, ) new_transformation = self._create_new_transformation( parent_component, transformation_list, transformation_type) new_transformation.parent = transformation_list self.beginInsertRows(target_index, target_pos, target_pos) transformation_list.insert(target_pos, new_transformation) self.endInsertRows() parent_component.depends_on = transformation_list[0] linked_component = None if transformation_list.has_link: linked_component = transformation_list.link.linked_component for i in range(len(transformation_list) - 1): transformation_list[i].depends_on = transformation_list[i + 1] if transformation_list.has_link: transformation_list.link.linked_component = linked_component if linked_component is not None: transformation_list[ -1].depends_on = transformation_list.link.linked_component.transforms[ 0] self.instrument.nexus.transformation_changed.emit()
def createEditor(self, parent: QModelIndex, option: QStyleOptionViewItem, index: QModelIndex) -> QWidget: """ Creates the widget used to change data from the model and can be reimplemented to customize editing behavior :param parent: Parent of the editor. :type parent: QModelIndex :param option: Option of the editor. :type option: QStyleOptionViewItem :param index: Index of the editor. :type index: QModelIndex :return: Editor for PropModel :rtype: QWidget """ data = index.internalPointer() if index.column() == 1 and isinstance( data, Property) and data.getType() == bool: return None if type(data) == Property: if index.column() == 1: t = data.getType() if t == str: return QLineEdit(parent) elif t == int: return QSpinBox(parent) elif t == bool: return QCheckBox(parent) elif t == float: return QDoubleSpinBox(parent) elif issubclass(t, Enum): editor = QComboBox(parent) t = type(data.getValue()) for i, option in enumerate(t): editor.addItem(option.name, option) return editor else: pass return QStyledItemDelegate.createEditor(self, parent, option, index)
def selection_changed(self, index: QModelIndex) -> None: self.chosen_item = index.internalPointer() self.ui.plainTextEdit.setPlainText(self.chosen_item.long_desc)
def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> str: """ Gets the data associated with a specific index and the specific role. :param index: The index to get the data from :type index: QModelIndex :param role: The role to use to get the data. :type role: Qt.ItemDataRole :return: The data for the given role :rtype: str or NoneType """ if not index.isValid(): return None elif role != Qt.DisplayRole: return None data = index.internalPointer() col = index.column() row = index.row() if isinstance(data, str): if col == 0: return data else: return None elif isinstance(data, Component): category, name = data.getProperties().getProperty("Name") category, typeOf = data.getProperties().getProperty("Class Name") if col == 0: return name.getValue() elif col == 1: return typeOf.getValue() else: return None elif isinstance(data, VisibilityBehavior): if col == 0: return data.getProperties().getProperty("Name")[1].getValue() elif col == 1: return data.getProperties().getProperty("Reaction Type")[1].getValue().name else: return None elif isinstance(data, ActionPipeline): if col == 0: return data.getName() elif col == 1: return data.getType() else: return None elif isinstance(data, ProjectExplorerModel.LeafIndex): innerData = data.getData() if isinstance(innerData, str): if col == 0: return innerData else: return None if isinstance(innerData, Component): if row == 0: if col == 0: return "From" elif col == 1: return innerData.getProperties().getProperty("Name")[1].getValue() else: return None if row == 1: if col == 0: return "To" elif col == 1: return innerData.getProperties().getProperty("Name")[1].getValue() else: return None else: raise ProjectExplorerModel.UnsupportedTypeException( "Unsupported data type in index: {}".format(type(data)))
def index(self, row: int, column: int, parent: QModelIndex) -> QModelIndex: """ Gets a model index given the parent index, row, and column. :param row: the index of the rowth child of "parent". :type row: int :param column: the column of the index to be created. :type column: int :param parent: the parent of the index to be created. :type parent: QModelIndex :return: the model index with the given parent, row, and column. :rtype: QModelIndex """ if not self.hasIndex(row, column, parent): return QModelIndex() # If the parent is the ghost root, return an index with the appropriate string. if not parent.isValid(): if row == ProjectExplorerModel.TARGET_GUI_ROW: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.TARGET_GUI_LABEL) elif row == ProjectExplorerModel.PIPELINE_ROW: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.PIPELINE_LABEL) else: return QModelIndex() parentData = parent.internalPointer() if isinstance(parentData, str): if parentData == ProjectExplorerModel.TARGET_GUI_LABEL: if row == ProjectExplorerModel.COMPONENT_ROW: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.COMPONENT_LABEL) elif row == ProjectExplorerModel.BEHAVIOR_ROW: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.BEHAVIOR_LABEL) else: return QModelIndex() elif parentData == ProjectExplorerModel.COMPONENT_LABEL: if self._project.getTargetGUIModel().getRoot().childCount() == 0: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.LeafIndex( ProjectExplorerModel.NO_COMPONENTS_LABEL, parentData, 0)) return self.registerAndCreateIndex(row, column, self._project.getTargetGUIModel().getRoot().getNthChild( row)) elif parentData == ProjectExplorerModel.BEHAVIOR_LABEL: if len(self._project.getTargetGUIModel().getVisibilityBehaviors()) == 0: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.LeafIndex( ProjectExplorerModel.NO_BEHAVIORS_LABEL, parentData, 0)) return self.registerAndCreateIndex(row, column, self._project.getTargetGUIModel().getNthVisibilityBehavior( row)) elif parentData == ProjectExplorerModel.PIPELINE_LABEL: # TODO: replace this once action pipelines are implemented return self.registerAndCreateIndex(row, column, ProjectExplorerModel.LeafIndex( ProjectExplorerModel.NO_PIPELINES_LABEL, parentData, 1)) else: raise ProjectExplorerModel.InvalidLabelException( "Unsupported data string: {}".format(parentData)) elif isinstance(parentData, Component): return self.registerAndCreateIndex(row, column, parentData.getNthChild(row)) elif isinstance(parentData, VisibilityBehavior): if row == 0: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.LeafIndex( parentData.getSrcComponent(), parentData)) if row == 1: return self.registerAndCreateIndex(row, column, ProjectExplorerModel.LeafIndex( parentData.getDestComponent(), parentData)) elif isinstance(parentData, ActionPipeline): # TODO: replace this once action pipelines are implemented pass elif isinstance(parentData, ProjectExplorerModel.LeafIndex): # Should never get into here pass else: raise ProjectExplorerModel.UnsupportedTypeException( "Unsupported data type in index: {}".format(type(parentData)))
def rowCount(self, parent: QModelIndex = QModelIndex()) -> int: if not parent.isValid(): return len(self.root_ids) item = parent.internalPointer() return len(item.children)