Exemplo n.º 1
0
    def dataChanged(self,
                    topLeft: QModelIndex,
                    bottomRight: QModelIndex,
                    roles=None):
        """
        Listens for dataChanged on an Intent (TreeItem)'s check state.

        Renders/unrenders according to the check state.
        Then, defers showing canvases to any derived views (e.g. StackedCanvasView).
        """
        # We only care about the check state changing here (whether to render or unrender)
        if Qt.CheckStateRole in roles or EnsembleModel.canvas_role in roles:

            intent_row_start = topLeft.row()
            intent_row_stop = bottomRight.row()

            new_intents = set()

            if topLeft.isValid() and bottomRight.isValid():
                for row in range(intent_row_start, intent_row_stop + 1):
                    intent_index = self.model().index(row, 0)
                    intent = intent_index.internalPointer().data(
                        EnsembleModel.object_role)
                    try:
                        canvas = self._canvas_manager.canvas_from_index(
                            intent_index.internalPointer())
                        try:
                            canvas.sigInteractiveAction.connect(
                                self.sigInteractiveAction,
                                type=Qt.UniqueConnection)
                        except TypeError:  # ignore errors from connection already being established
                            pass
                    except Exception as ex:
                        msg.logMessage(
                            f'A error occurred displaying the intent named {intent.name}:',
                            level=msg.ERROR)
                        msg.logError(ex)
                    else:
                        new_intents.add((canvas, intent))

            removed_intents = self._last_seen_intents - new_intents
            added_intents = new_intents - self._last_seen_intents

            for canvas, intent in removed_intents:
                if canvas is not None:
                    self.unrender(intent, canvas)

            for canvas, intent in added_intents:
                if canvas is not None:
                    self.render(intent, canvas)

            self._last_seen_intents = new_intents

            self.show_canvases()
Exemplo n.º 2
0
 def data(self, index: QModelIndex, role: int = ...) -> typing.Any:
     if not index.isValid():
         return QVariant()
     elif role != Qt.DisplayRole:
         return QVariant()
     else:
         return QVariant(self._measurementModel[index.row()]._name)
Exemplo n.º 3
0
    def data(self, index: QModelIndex, role: int) -> Union[str, None]:
        if not index.isValid():
            return None
        node = index.internalPointer()

        if role == Qt.DisplayRole:
            return node.name
Exemplo n.º 4
0
 def hasChildren(self, parent: QModelIndex) -> bool:
     # Reimplemented, since in the source model, the realizations have
     # children (i.e. valid indices.). Realizations do not have children in
     # this model.
     if parent.isValid():
         return False
     return self.sourceModel().hasChildren(self.mapToSource(parent))
Exemplo n.º 5
0
    def doubleClicked_callback(self, index: QModelIndex):

        import pandas as pd
        import numpy as np
        import numpy.ma

        if index.isValid() and index.column() == NodeCols.Value:

            item = index.internalPointer()
            obj = item.node['obj']['fullname']
            args = str(item.node['args'])

            data, _ = self.shell.get_obj_value(
                'analyze_getval', obj, args)

            if isinstance(data, (pd.DataFrame, pd.Index, pd.Series)):
                dialog = DataFrameEditor(self)
                dialog.setup_and_check(data)
            elif isinstance(data, (np.ndarray, np.ma.MaskedArray)):
                dialog = ArrayEditor(self)
                dialog.setup_and_check(data, title='', readonly=True)
            elif isinstance(data, (list, set, tuple, dict)):
                dialog = CollectionsEditor(self)
                dialog.setup(data, title='', readonly=True)
            else:
                return

            dialog.show()
Exemplo n.º 6
0
    def setData(self, index: QModelIndex, value, role=Qt.EditRole):
        if not index.isValid():
            return False

        node = index.internalPointer()

        if role == Qt.EditRole:
            if isinstance(node, JsonItem):
                if node.type in ('float', 'int', None):
                    node.value = value
                try:  # PyQt5
                    self.dataChanged.emit(index, index, [Qt.EditRole])
                except TypeError:  # PyQt4, PySide
                    self.dataChanged.emit(index, index)

        elif role == Qt.CheckStateRole:
            if isinstance(node, JsonItem):
                if node.type == 'bool':
                    node.value = value == Qt.Checked
                    try:  # PyQt5
                        self.dataChanged.emit(
                            index, index, [Qt.CheckStateRole])
                    except TypeError:  # PyQt4, PySide
                        self.dataChanged.emit(index, index)
                    return True
        return False
Exemplo n.º 7
0
    def flags(self, index: QModelIndex) -> Qt.ItemFlags:
        """Returns the item flags for the given `index`.

        This describes the properties of a given item in the model.  We set
        them to be editable, checkable, dragable, droppable, etc...
        If index is not a list, we additionally set `Qt.ItemNeverHasChildren`
        (for optimization). Editable models must return a value containing
        `Qt.ItemIsEditable`.

        See Qt.ItemFlags https://doc.qt.io/qt-5/qt.html#ItemFlag-enum
        """
        if (
            not index.isValid()
            or index.row() >= len(self._root)
            or index.model() is not self
        ):
            # we allow drops outside the items
            return Qt.ItemIsDropEnabled

        base_flags = (
            Qt.ItemIsSelectable
            | Qt.ItemIsEditable
            | Qt.ItemIsUserCheckable
            | Qt.ItemIsDragEnabled
            | Qt.ItemIsEnabled
        )
        if isinstance(self.getItem(index), MutableSequence):
            return base_flags | Qt.ItemIsDropEnabled
        return base_flags | Qt.ItemNeverHasChildren
Exemplo n.º 8
0
 def mapFromSource(self, sourceIndex: QModelIndex) -> QModelIndex:
     if not sourceIndex.isValid():
         return QModelIndex()
     if not self._index_is_on_our_branch(sourceIndex):
         return QModelIndex()
     source_node = sourceIndex.internalPointer()
     return self.index(source_node.row(), sourceIndex.column(), QModelIndex())
Exemplo n.º 9
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole) -> QVariant:
        if not index.isValid():
            return QVariant()

        if role == Qt.TextAlignmentRole:
            return Qt.AlignCenter

        if role == ProgressRole:
            return self._progress

        if role in (Qt.StatusTipRole, Qt.WhatsThisRole, Qt.ToolTipRole):
            return ""

        if role == Qt.SizeHintRole:
            return QSize(30, 30)

        if role == Qt.FontRole:
            return QFont()

        if role in (Qt.BackgroundRole, Qt.ForegroundRole, Qt.DecorationRole):
            return QColor()

        if role == Qt.DisplayRole:
            return ""

        return QVariant()
Exemplo n.º 10
0
 def data(self, index: QModelIndex, role: int = ...) -> typing.Any:
     if not index.isValid():
         return QVariant()
     elif role != Qt.DisplayRole:
         return QVariant()
     else:
         filter_at_row = self.__filter_model[index.row()]
         if index.column() == 0:
             return QVariant(filter_at_row.filter_type)
         elif index.column() == 1:
             if hasattr(filter_at_row, 'freq'):
                 return QVariant(filter_at_row.freq)
             else:
                 return QVariant('N/A')
         elif index.column() == 2:
             if hasattr(filter_at_row, 'q'):
                 return QVariant(filter_at_row.q)
             else:
                 return QVariant('N/A')
         elif index.column() == 3:
             if hasattr(filter_at_row, 'q_to_s'):
                 return QVariant(round(filter_at_row.q_to_s(), 3))
             else:
                 return QVariant('N/A')
         elif index.column() == 4:
             if hasattr(filter_at_row, 'gain'):
                 return QVariant(filter_at_row.gain)
             else:
                 return QVariant('N/A')
         elif index.column() == 5:
             return QVariant(len(filter_at_row))
         else:
             return QVariant()
Exemplo n.º 11
0
 def data(self, index: QModelIndex, role: Qt.ItemDataRole):
     """Return data stored under ``role`` for the item at ``index``."""
     if not index.isValid():
         return None
     layer = self.getItem(index)
     if role == Qt.DisplayRole:  # used for item text
         return layer.name
     if role == Qt.TextAlignmentRole:  # alignment of the text
         return Qt.AlignCenter
     if role == Qt.EditRole:  # used to populate line edit when editing
         return layer.name
     if role == Qt.ToolTipRole:  # for tooltip
         return layer.name
     if role == Qt.CheckStateRole:  # the "checked" state of this item
         return Qt.Checked if layer.visible else Qt.Unchecked
     if role == Qt.SizeHintRole:  # determines size of item
         return QSize(200, 34)
     if role == ThumbnailRole:  # return the thumbnail
         thumbnail = layer.thumbnail
         return QImage(
             thumbnail,
             thumbnail.shape[1],
             thumbnail.shape[0],
             QImage.Format_RGBA8888,
         )
     # normally you'd put the icon in DecorationRole, but we do that in the
     # # LayerDelegate which is aware of the theme.
     # if role == Qt.DecorationRole:  # icon to show
     #     pass
     return super().data(index, role)
Exemplo n.º 12
0
    def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
        """Renders the delegate using the given painter and style option for the item specified by index.

        :param painter: A QPainter object to draw
        :param option: Options to describe what should be drawn
        :param index: _description_
        """
        if not index.isValid():
            return

        # Initialize the style options. This is not very Pythonic as it uses C++
        # references under the hood so opt is affected by the second call
        opt = QStyleOptionViewItem(option)
        self.initStyleOption(opt, index)

        # Standard setup, paint, restore operation
        painter.save()
        try:
            painter.setClipRect(opt.rect)
            foreground_colour, background_colour = index.data(Qt.ForegroundRole), index.data(Qt.BackgroundRole)
            if foreground_colour is not None:
                painter.setPen(foreground_colour)
            if background_colour is not None:
                painter.fillRect(option.rect, background_colour)
            padding = self._padding
            opt.rect = option.rect.adjusted(padding, padding, -padding, -padding)
            painter.drawText(opt.rect, int(Qt.AlignLeft | Qt.AlignVCenter),
                             opt.fontMetrics.elidedText(opt.text, Qt.ElideRight, opt.rect.width()))
        finally:
            painter.restore()
Exemplo n.º 13
0
    def canvas_from_index(self, index: QModelIndex):
        if not index.isValid():
            return None

        if index.data(
                EnsembleModel.data_type_role) != WorkspaceDataType.Intent:
            print(f'WARNING: canvas_from_index index {index} is not an intent')
            return None

        # Canvas exists for index, return
        # TODO: in tab view, with multiple intents selected (e.g. 2 rows checked),
        #       non-0 row intents (every intent except first) does not have a valid object in canvas_role
        canvas = index.model().data(index, EnsembleModel.canvas_role)
        if canvas:
            return canvas

        # There is another canvas we know about we should use
        for match_index in self.all_intent_indexes(index.model()):
            if self.is_matching_canvas_type(index, match_index):
                canvas = match_index.model().data(match_index,
                                                  EnsembleModel.canvas_role)
                if canvas is not None:
                    index.model().setData(index, canvas,
                                          EnsembleModel.canvas_role)
                    return canvas

        # Does not exist, create new canvas and return
        intent = index.model().data(index, EnsembleModel.object_role)
        canvas_class_name = intent.canvas
        registry = pluginmanager
        canvas = self.canvas_from_registry(canvas_class_name, registry,
                                           intent.canvas_name)

        index.model().setData(index, canvas, EnsembleModel.canvas_role)
        return canvas
Exemplo n.º 14
0
 def currentChanged(self, current: QModelIndex, previous: QModelIndex) -> None:
     if current.isValid():
         item = current.internalPointer()
         if isinstance(item, ValueItem) and item.attrs["spec"]:
             self.parent().update_dataattrs(item)
         else:
             self.parent().update_dataattrs(None)
Exemplo n.º 15
0
    def setData(self,
                index: QModelIndex,
                value: str,
                role=Qt.EditRole) -> bool:
        col = index.column()
        row = index.row()

        if index.isValid() and role == Qt.EditRole:
            # type(value) == str

            data = self.col_data[col]
            key = data.key
            if value and not value.isspace():
                try:
                    value = data.cls(value)
                except ValueError:
                    return False
            else:
                value = data.default

            if key.startswith(self.TRIGGER):
                key = behead(key, self.TRIGGER)
                trigger = self.triggers(row)
                if value == data.default:
                    # Delete key if (key: value) present
                    trigger.pop(key, None)
                else:
                    trigger[key] = value

            else:
                setattr(self.channels[row], key, value)

            self.dataChanged.emit(index, index, [role])
            return True
        return False
Exemplo n.º 16
0
 def columnCount(self, index: QModelIndex) -> int:
     """Returns the number of columns in the given index."""
     if index.isValid():
         return index.internalPointer().columnCount()
     # For an invalid index, return the number of columns defined at the root item of the tree
     else:
         return self.rootItem.columnCount()
Exemplo n.º 17
0
 def flags(self, index: QModelIndex) -> int:
     if not index.isValid():
         return Qt.NoItemFlags
     flags = super(ChannelTableModel, self).flags(index)
     if index.column() == self.CHECK_COLUMN:
         flags |= Qt.ItemIsUserCheckable
     return flags
Exemplo n.º 18
0
 def flags(self, index: QModelIndex):
     if not index.isValid():
         return None
     if index.column() == 0:
         flags = Qt.ItemIsEnabled
     else:
         flags = super(DerivedDataModel, self).flags(index)
     return flags
Exemplo n.º 19
0
 def _source_rows_about_to_be_inserted(
     self, parent: QModelIndex, start: int, end: int
 ):
     if not parent.isValid():
         return
     if not self._index_is_on_our_branch(parent):
         return
     self.beginInsertRows(self.mapFromSource(parent), start, end)
Exemplo n.º 20
0
    def flags(self, index: QModelIndex) -> Qt.ItemFlag:
        """Re-implement to additionally ensure that this model is checkable."""
        if not index.isValid():
            return Qt.NoItemFlags

        return super(
            TreeModel,
            self).flags(index) | Qt.ItemIsUserCheckable  #|Qt.ItemIsEditable
 def flags(self, index: QModelIndex) -> int:
     if not index.isValid():
         return Qt.NoItemFlags
     flags = super(IMCFileTreeModel, self).flags(index)
     item: IMCFileTreeItem = index.internalPointer()
     if index.column(
     ) == self.CHECK_COLUMN and item.imc_file_tree_is_checkable:
         flags |= Qt.ItemIsUserCheckable
     return flags
 def parent(self, index: QModelIndex = None, **kwargs) -> QModelIndex:
     if index is not None and index.isValid():
         parent_item: IMCFileTreeItem = index.internalPointer(
         ).imc_file_tree_parent
         if parent_item is not None and parent_item.imc_file_tree_parent is not None:
             parent_row = parent_item.imc_file_tree_parent.imc_file_tree_children.index(
                 parent_item)
             return self.createIndex(parent_row, 0, parent_item)
     return QModelIndex()
Exemplo n.º 23
0
 def mapToSource(self, proxyIndex: QModelIndex) -> QModelIndex:
     if not proxyIndex.isValid():
         return QModelIndex()
     sm = self.sourceModel()
     iter_index = sm.index(self._iter, 0, QModelIndex())
     if not iter_index.isValid() or not sm.hasChildren(iter_index):
         return QModelIndex()
     real_index = sm.index(proxyIndex.row(), proxyIndex.column(), iter_index)
     return real_index
Exemplo n.º 24
0
    def _redecorate_root(self, parent: QModelIndex = None, *_):
        """Add a branch/arrow column only if there are Groups in the root.

        This makes the tree fall back to looking like a simple list if there
        are no lists in the root level.
        """
        if not parent or not parent.isValid():
            hasgroup = any(isinstance(i, MutableSequence) for i in self._root)
            self.setRootIsDecorated(hasgroup)
Exemplo n.º 25
0
 def data(self, index: QModelIndex, role: Optional[int] = None) -> Any:
     if index.isValid():
         channel = self._controller.channels[index.row()]
         if index.column(
         ) == self.CHECK_COLUMN and role == Qt.CheckStateRole:
             return Qt.Checked if channel.is_shown else Qt.Unchecked
         if index.column() == self.LABEL_COLUMN and role == Qt.DisplayRole:
             return channel.label
     return None
Exemplo n.º 26
0
    def getItem(self, index: QModelIndex) -> Node:
        """Return ``Node`` object for a given `QModelIndex`.

        A null or invalid ``QModelIndex`` will return the root Node.
        """
        if index.isValid():
            item = index.internalPointer()
            if item is not None:
                return item
        return self._root
Exemplo n.º 27
0
 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
Exemplo n.º 28
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole) -> QVariant:
        if not index.isValid():
            return QVariant()

        if role == Qt.TextAlignmentRole:
            return Qt.AlignCenter

        if role == ProgressRole:
            return self._progress
        return QVariant()
Exemplo n.º 29
0
    def getItem(self, index: QModelIndex) -> TreeItem:
        """Convenience method to get a TreeItem from a given index.

        Returns the root item if the index passed is not valid."""
        if index.isValid():
            item = index.internalPointer()
            if item:
                return item

        return self.rootItem
Exemplo n.º 30
0
    def on_new_iteration(self, parent: QModelIndex, start: int, end: int) -> None:
        if not parent.isValid():
            iter = start
            self._iteration_progress_label.setText(f"Progress for iteration {iter}")

            widget = RealizationWidget(iter)
            widget.setSnapshotModel(self._snapshot_model)
            widget.currentChanged.connect(self._select_real)

            self._tab_widget.addTab(widget, f"Realizations for iteration {iter}")
Exemplo n.º 31
0
    def getItem(self, index: QModelIndex) -> NodeType:
        """Return python object for a given `QModelIndex`.

        An invalid `QModelIndex` will return the root object.
        """
        if index.isValid():
            item = index.internalPointer()
            if item is not None:
                return item
        return self._root
Exemplo n.º 32
0
    def flags(self, index: QModelIndex):
        flags = (Qt.NoItemFlags | Qt.ItemIsDragEnabled | Qt.ItemIsSelectable |
                 Qt.ItemIsEnabled)

        if index.isValid():
            node = self.node_from_index(index)
            column = self.columns[index.column()].name

            if isinstance(node, JsonItem):
                if column == 'value' and not node.readonly:
                    if not node.type == 'bool':
                        flags |= Qt.ItemIsEditable
                    else:
                        flags |= Qt.ItemIsUserCheckable
        return flags