Beispiel #1
0
    def getItem(self, index: QModelIndex) -> ProtocolTreeItem:
        if index.isValid():
            item = index.internalPointer()
            if item:
                return item

        return self.rootItem
Beispiel #2
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        i = index.row()
        j = index.column()
        device = self.get_device_at(i)
        if role == Qt.DisplayRole:
            if j == 0:
                return self.backend_handler.DEVICE_NAMES[i]
            elif j == 1:
                if device.is_enabled:
                    if device.supports_rx and device.supports_tx:
                        device_info = "supports RX and TX"
                    elif device.supports_rx and not device.supports_tx:
                        device_info = "supports RX only"
                    elif not device.supports_rx and device.supports_tx:
                        device_info = "supports TX only"
                    else:
                        device_info = ""
                else:
                    device_info = "disabled"

                return device_info
            elif j == 2:
                return "" if device.has_native_backend else "not available"
            elif j == 3:
                return "" if device.has_gnuradio_backend else "not available"
        elif role == Qt.CheckStateRole:
            if j == 0 and (device.has_native_backend or device.has_gnuradio_backend):
                return Qt.Checked if device.is_enabled else Qt.Unchecked
            elif j == 2 and device.has_native_backend:
                return Qt.Checked if device.selected_backend == Backends.native else Qt.Unchecked
            elif j == 3 and device.has_gnuradio_backend:
                return Qt.Checked if device.selected_backend == Backends.grc else Qt.Unchecked
Beispiel #3
0
    def setData(self, index: QModelIndex, value: QVariant, role: int = None):
        if not index.isValid():
            return False
        item = index.internalPointer()

        if role == Qt.CheckStateRole:
            childrenCount = item.childrenCount()
            if childrenCount:
                for i in range(childrenCount):
                    self.setData(index.child(i, 0), value, role = role)
            else:
                item.selected = bool(value)
            self.dataChanged.emit(index, index, [Qt.CheckStateRole])

            # recalculate parents
            p = index
            while True:
                p = p.parent()
                if p.isValid():
                    self.dataChanged.emit(p, p, [Qt.CheckStateRole])
                else:
                    break

            # success
            return True

        if role == Qt.EditRole:
            assert index.column() == TaskTreeColumn.FileName
            item.setNameByUser(value)
            self.dataChanged.emit(index, index, [Qt.DisplayRole])
            return True

        return False
Beispiel #4
0
 def __newFolder(self):
     """
     Private slot to add a new bookmarks folder.
     """
     from .BookmarkNode import BookmarkNode
     
     currentIndex = self.bookmarksTree.currentIndex()
     idx = QModelIndex(currentIndex)
     sourceIndex = self.__proxyModel.mapToSource(idx)
     sourceNode = self.__bookmarksModel.node(sourceIndex)
     row = -1    # append new folder as the last item per default
     
     if sourceNode is not None and \
        sourceNode.type() != BookmarkNode.Folder:
         # If the selected item is not a folder, add a new folder to the
         # parent folder, but directly below the selected item.
         idx = idx.parent()
         row = currentIndex.row() + 1
     
     if not idx.isValid():
         # Select bookmarks menu as default.
         idx = self.__proxyModel.index(1, 0)
     
     idx = self.__proxyModel.mapToSource(idx)
     parent = self.__bookmarksModel.node(idx)
     node = BookmarkNode(BookmarkNode.Folder)
     node.title = self.tr("New Folder")
     self.__bookmarksManager.addBookmark(parent, node, row)
 def flags(self, index: QModelIndex):
     if index.isValid():
         if self.is_writeable:
             return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable
         else:
             return Qt.ItemIsEnabled | Qt.ItemIsSelectable
     else:
         return Qt.NoItemFlags
Beispiel #6
0
    def parent(self, index: QtCore.QModelIndex):
        if not index.isValid():
            return QtCore.QModelIndex()

        item = index.internalPointer().parent
        if item == self.root or item is None:
            return QtCore.QModelIndex()
        else:
            return self.createIndex(item.row, 0, item)
Beispiel #7
0
    def rowCount(self, parent: QModelIndex = None, *args, **kwargs):
        if not self._root:
            return 0

        if parent.isValid():
            parentItem = parent.internalPointer()
            return parentItem.childrenCount()
        else:
            return self._root.childrenCount()
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        i, j = index.row(), index.column()

        try:
            lbl = self.display_labels[i]
        except IndexError:
            return None

        if not lbl or not self.message:
            return None

        if isinstance(lbl, ChecksumLabel):
            calculated_crc = lbl.calculate_checksum_for_message(self.message, use_decoded_bits=True)
        else:
            calculated_crc = None

        if role == Qt.DisplayRole:
            if j == 0:
                return lbl.name
            elif j == 1:
                return lbl.DISPLAY_FORMATS[lbl.display_format_index]
            elif j == 2:
                start, end = self.message.get_label_range(lbl, lbl.display_format_index % 3, True)
                if lbl.display_format_index in (0, 1, 2):
                    try:
                        data = self.bit_str[self.message_index][start:end] if lbl.display_format_index == 0 \
                            else self.hex_str[self.message_index][start:end] if lbl.display_format_index == 1 \
                            else self.ascii_str[self.message_index][start:end] if lbl.display_format_index == 2 \
                            else ""
                    except IndexError:
                        return None
                else:
                    # decimal
                    try:
                        data = str(int(self.bit_str[self.message_index][start:end], 2))
                    except (IndexError, ValueError):
                        return None

                if calculated_crc is not None:
                    data += " (should be {0})".format(util.convert_bits_to_string(calculated_crc, lbl.display_format_index))

                return data

        elif role == Qt.BackgroundColorRole:
            if isinstance(lbl, ChecksumLabel):
                start, end = self.message.get_label_range(lbl, 0, True)
                if calculated_crc == self.message.decoded_bits[start:end]:
                    return constants.BG_COLOR_CORRECT
                else:
                    return constants.BG_COLOR_WRONG

            else:
                return None
Beispiel #9
0
 def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole):
     if index.isValid():
         ip = index.internalPointer()
         if index.column() == 0:
             if role == QtCore.Qt.DisplayRole:
                 return ("*" if ip.unfinished() else "") + ip.title()
             elif role == QtCore.Qt.ToolTipRole:
                 return ip.tooltip()
             elif role == QtCore.Qt.DecorationRole:
                 return ip.image()
Beispiel #10
0
    def parent(self, index: QModelIndex = None):
        if not index.isValid():
            return QModelIndex()

        childItem = index.internalPointer()
        parentItem = childItem.parent

        if parentItem == self._root:
            return QModelIndex()
        else:
            return self.createIndex(parentItem.siblingNumber(), 0, parentItem)
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        i = index.row()
        participant = self.simulator_config.active_participants[i]

        if not index.isValid():
            return None

        if role == Qt.DisplayRole:
            return participant.name + " (" + participant.shortname + ")"
        elif role == Qt.CheckStateRole:
            return Qt.Checked if participant.simulate else Qt.Unchecked
 def flags(self, index: QtCore.QModelIndex) -> QtCore.Qt.ItemFlags:
     flags = super().flags(index)
     if not index.isValid():
         return flags
     flags |= QtCore.Qt.ItemIsDragEnabled
     file_item = self.item(index)
     if index.column() == 0:
         flags |= QtCore.Qt.ItemIsEditable
         if file_item.is_dir:
             flags |= QtCore.Qt.ItemIsDropEnabled
     return flags
 def data(self, index: QModelIndex,
          role: int = Qt.DisplayRole) -> Optional[str]:
     """Qt override."""
     if index.isValid() and role == Qt.DisplayRole:
         obj = self.listdata[index.row()]
         colname = self.header_attr[index.column()]
         thing = getattr(obj, colname)
         if callable(thing):
             return str(thing())
         else:
             return str(thing)
     return None
Beispiel #14
0
    def flags(self, index: QModelIndex):
        if index.isValid():
            alignment_offset = self.get_alignment_offset_at(index.row())
            if index.column() < alignment_offset:
                return Qt.ItemIsSelectable | Qt.ItemIsEnabled

            if self.is_writeable:
                return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable
            else:
                return Qt.ItemIsEnabled | Qt.ItemIsSelectable
        else:
            return Qt.NoItemFlags
Beispiel #15
0
    def tilesChanged(self, tiles):
        if (tiles.first().tileset() != self.mTileset):
            return
        topLeft = QModelIndex()
        bottomRight = QModelIndex()
        for tile in tiles:
            i = self.tileIndex(tile)
            if (not topLeft.isValid()):
                topLeft = i
                bottomRight = i
                continue

            if (i.row() < topLeft.row() or i.column() < topLeft.column()):
                topLeft = self.index(min(topLeft.row(), i.row()),
                                min(topLeft.column(), i.column()))
            if (i.row() > bottomRight.row() or i.column() > bottomRight.column()):
                bottomRight = self.index(max(bottomRight.row(), i.row()),
                                    max(bottomRight.column(), i.column()))

        if (topLeft.isValid()):
            self.dataChanged.emit(topLeft, bottomRight)
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        i = index.row()
        j = index.column()

        if role == Qt.DisplayRole and self.display_data:
            if self.label_mask[i, j]:
                return "."

        return super().data(index, role)
Beispiel #17
0
        def data(self, index: QModelIndex, role=Qt.DisplayRole):
            if not index.isValid():
                return None

            i, j = index.row(), index.column()

            if role == Qt.DisplayRole:
                data_range = self.checksum_label.data_ranges[i]
                if j == 0:
                    return self.message.convert_index(data_range[0], 0, self.proto_view, True)[0] + 1
                elif j == 1:
                    return self.message.convert_index(data_range[1], 0, self.proto_view, True)[0]
            return None
Beispiel #18
0
    def parent(self, index: QModelIndex = None):
        if not index.isValid():
            return QModelIndex()

        child_item = self.getItem(index)
        try:
            parent_item = child_item.parent()
        except AttributeError:
            return QModelIndex()

        if parent_item == self.rootItem or parent_item is None:
            return QModelIndex()

        return self.createIndex(parent_item.indexInParent(), 0, parent_item)
Beispiel #19
0
    def data(self, index: QModelIndex, role = None):
        if not index.isValid():
            return None

        item = index.internalPointer()
        if role == Qt.DisplayRole:
            return item.data(index.column())
        elif role == Qt.CheckStateRole and index.column() == TaskTreeColumn.FileName:
            return item.selected
        elif role == Qt.DecorationRole and index.column() == TaskTreeColumn.FileName:
            # TODO: use with real icons
            from PyQt5.QtGui import QIcon
            return QIcon.fromTheme("xware-desktop")

        return None
Beispiel #20
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        if role == Qt.DisplayRole or role == Qt.EditRole:
            i = index.row()
            j = index.column()
            fieldtype = self.field_types[i]

            if j == 0:
                return fieldtype.caption
            elif j == 1:
                return fieldtype.function.name
            elif j == 2:
                return ProtocolLabel.DISPLAY_FORMATS[fieldtype.display_format_index]
    def selection_changed(self, curr_index: QModelIndex, prev_index: QModelIndex):
        """
        Updates the information about currently selected account.
        """
        if not curr_index.isValid():
            return None

        # Make sure selection is visible in the view
        self.selection.setCurrentIndex(
            curr_index, QItemSelectionModel.SelectCurrent)

        acc = curr_index.data(role=Qt.UserRole)

        # Set the type of account
        self.typeBox.setCurrentText(acc.type)

        # Set the checkboxes
        self.closedBox.setChecked(acc.closed)
        self.exBudgetBox.setChecked(acc.exbudget)
Beispiel #22
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        i = index.row()
        j = index.column()
        if role == Qt.DisplayRole and self.display_data:
            try:
                alignment_offset = self.get_alignment_offset_at(i)
                if j < alignment_offset:
                    return self.ALIGNMENT_CHAR

                if self.proto_view == 0:
                    return self.display_data[i][j - alignment_offset]
                elif self.proto_view == 1:
                    return "{0:x}".format(self.display_data[i][j - alignment_offset])
                elif self.proto_view == 2:
                    return chr(self.display_data[i][j - alignment_offset])
            except IndexError:
                return None

        elif role == Qt.TextAlignmentRole:
            if i in self.first_messages:
                return Qt.AlignHCenter + Qt.AlignBottom
            else:
                return Qt.AlignCenter

        elif role == Qt.BackgroundColorRole:
            return self.background_colors[i, j]

        elif role == Qt.FontRole:
            font = QFont()
            font.setBold(self.bold_fonts[i, j])
            font.setItalic(self.italic_fonts[i, j])
            return font

        elif role == Qt.TextColorRole:
            return self.text_colors[i, j]

        elif role == Qt.ToolTipRole:
            return self.get_tooltip(i, j)
        else:
            return None
Beispiel #23
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        if role == Qt.DisplayRole:
            i = index.row()
            j = index.column()
            rule = self.ruleset[i]
            assert isinstance(rule, Rule)

            if j == 0:
                return rule.start + 1
            elif j == 1:
                return rule.end
            elif j == 2:
                return rule.value_type
            elif j == 3:
                return rule.operator_description
            elif j == 4:
                return rule.target_value
    def data(self, index: QtCore.QModelIndex,
             role: int=QtCore.Qt.DisplayRole) -> QtCore.QVariant:
        if not index.isValid():
            return QtCore.QVariant()

        if index.column() < 0 or index.column() >= self.columnCount:
            return QtCore.QVariant()

        if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            return self.item(index).data[index.column()]

        if index.column() == 0:
            for case in switch(role):
                if case(QtWidgets.QDirModel.FileIconRole):
                    return self.file_icon if not self.item(index).is_dir else \
                        self.folder_icon
                if case():
                    return QtCore.QVariant()

        return QtCore.QVariant()
 def dropMimeData(self, mime_data: QtCore.QMimeData,
                  drop_actions: QtCore.Qt.DropActions,
                  row: int, column: int,
                  index: QtCore.QModelIndex):
     if not index.isValid() or not drop_actions & QtCore.Qt.CopyAction:
         return False
     urls = mime_data.urls()
     root = mime_data.property('root')
     print(root)
     for url in urls:
         source_path = os.path.dirname(url.path())
         filename = os.path.basename(url.path())
         print(source_path)
         print(filename)
         target_path = self.filePath(index)
         print(target_path)
         if root != '':
             target_path += source_path[source_path.index(root):]
             print(target_path)
         self.file_downloading.emit(source_path, target_path, filename)
     return True
    def paint(self, painter, option, index):
        ##option.rect.setWidth(option.rect.width() - 18)
        # QStyledItemDelegate.paint(self, painter, option, index)
        ##option.rect.setWidth(option.rect.width() + 18)

        itemIndex = QModelIndex()
        character = self.mdlCharacter.getCharacterByID(index.data())
        if character:
            itemIndex = character.index(Character.name.value)

        opt = QStyleOptionViewItem(option)
        self.initStyleOption(opt, itemIndex)

        qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)

        # if index.isValid() and index.internalPointer().data(Outline.POV.value) not in ["", None]:
        if itemIndex.isValid() and self.mdlCharacter.data(itemIndex) not in ["", None]:
            opt = QStyleOptionComboBox()
            opt.rect = option.rect
            r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow)
            option.rect = r
            qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)
Beispiel #27
0
    def setData(self, index: QModelIndex, value, role=None):
        if not index.isValid():
            return False

        i, j = index.row(), index.column()
        device = self.get_device_at(i)
        if role == Qt.CheckStateRole:
            enabled = bool(value)
            if j == 0:
                device.is_enabled = enabled
            if j == 2:
                if enabled and device.has_native_backend:
                    device.selected_backend = Backends.native
                elif not enabled and device.has_gnuradio_backend:
                    device.selected_backend = Backends.grc
            elif j == 3:
                if enabled and device.has_gnuradio_backend:
                    device.selected_backend = Backends.grc
                elif not enabled and device.has_native_backend:
                    device.selected_backend = Backends.native

            self.update()
            device.write_settings()
            return True
Beispiel #28
0
    def flags(self, index: QModelIndex):
        if not index.isValid():
            return None

        j = index.column()
        device = self.get_device_at(index.row())
        if j == 0 and not device.has_native_backend and not device.has_gnuradio_backend:
            return Qt.NoItemFlags

        if j in [1, 2, 3] and not device.is_enabled:
            return Qt.NoItemFlags

        if j == 2 and not device.has_native_backend:
            return Qt.NoItemFlags

        if j == 3 and not device.has_gnuradio_backend:
            return Qt.NoItemFlags

        flags = Qt.ItemIsEnabled

        if j in [0, 2, 3]:
            flags |= Qt.ItemIsUserCheckable

        return flags
Beispiel #29
0
 def setData(self, index: QModelIndex, data_value, role=Qt.EditRole):
     if index.isValid() and role == Qt.EditRole:
         self.column_objects[index.column()].set_data(
             index, data_value, role)
         self.dataEdited.emit()
Beispiel #30
0
 def set_data(self, index: QModelIndex, data, role=Qt.EditRole):
     if index.isValid() and role == Qt.EditRole:
         self.data_type.set_data(index.row(), data)
Beispiel #31
0
    def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> QVariant:
        # note: this method is performance-critical.
        # it is called a lot, and so must run extremely fast.
        assert index.isValid()
        col = index.column()
        tx_item = self.transactions.value_from_pos(index.row())
        tx_hash = tx_item['txid']
        conf = tx_item['confirmations']
        txpos = tx_item['txpos_in_block'] or 0
        height = tx_item['height']
        token = self.parent.wallet.db.get_token(tx_item['token_key'])
        bind_addr = tx_item['bind_addr']
        from_addr = tx_item['from_addr']
        to_addr = tx_item['to_addr']

        timestamp = tx_item['timestamp']
        if timestamp is None:
            timestamp = float("inf")

        try:
            status, status_str = self.tx_status_cache[tx_hash]
        except KeyError:
            tx_mined_info = self.tx_mined_info_from_tx_item(tx_item)
            status, status_str = self.parent.wallet.get_tx_status(tx_hash, tx_mined_info)

        balance_str = f"{tx_item['amount']}" if to_addr == bind_addr else f"- {tx_item['amount']}"

        if role == Qt.UserRole:
            # for sorting
            d = {
                TokenHistoryColumns.STATUS: (-timestamp, conf, -status, -height, -txpos),
                TokenHistoryColumns.BIND_ADDRESS: bind_addr,
                TokenHistoryColumns.TOKEN: token.symbol,
                TokenHistoryColumns.AMOUNT: balance_str,
            }
            return QVariant(d[col])

        if role not in (Qt.DisplayRole, Qt.EditRole):
            if col == TokenHistoryColumns.STATUS and role == Qt.DecorationRole:
                return QVariant(read_QIcon(TX_ICONS[status]))
            elif col == TokenHistoryColumns.STATUS and role == Qt.ToolTipRole:
                return QVariant(str(conf) + _(" confirmation" + ("s" if conf != 1 else "")))
            elif col > TokenHistoryColumns.BIND_ADDRESS and role == Qt.TextAlignmentRole:
                return QVariant(Qt.AlignRight | Qt.AlignVCenter)
            elif col != TokenHistoryColumns.STATUS and role == Qt.FontRole:
                return QVariant(QFont(MONOSPACE_FONT))
            elif col in (TokenHistoryColumns.TOKEN, TokenHistoryColumns.AMOUNT) \
                    and role == Qt.ForegroundRole and from_addr == bind_addr:
                red_brush = QBrush(QColor("#BC1E1E"))
                return QVariant(red_brush)
            return QVariant()
        if col == TokenHistoryColumns.STATUS:
            return QVariant(status_str)
        elif col == TokenHistoryColumns.BIND_ADDRESS:
            return QVariant(bind_addr)
        elif col == TokenHistoryColumns.TOKEN:
            return QVariant(token.symbol)
        elif col == TokenHistoryColumns.AMOUNT:
            amount = tx_item['amount']
            if from_addr == bind_addr:
                amount = -amount
            v_str = self.parent.format_amount(amount, is_diff=True, whitespaces=True, num_zeros=0, decimal_point=token.decimals)
            return QVariant(v_str)
        return QVariant()
Beispiel #32
0
    def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> QVariant:
        # note: this method is performance-critical.
        # it is called a lot, and so must run extremely fast.
        assert index.isValid()
        col = index.column()
        tx_item = self.transactions.value_from_pos(index.row())
        is_lightning = tx_item.get('lightning', False)
        timestamp = tx_item['timestamp']
        if is_lightning:
            status = 0
            txpos = tx_item['txpos']
            if timestamp is None:
                status_str = 'unconfirmed'
            else:
                status_str = format_time(int(timestamp))
        else:
            tx_hash = tx_item['txid']
            conf = tx_item['confirmations']
            txpos = tx_item['txpos_in_block'] or 0
            height = tx_item['height']
            try:
                status, status_str = self.tx_status_cache[tx_hash]
            except KeyError:
                tx_mined_info = self.tx_mined_info_from_tx_item(tx_item)
                status, status_str = self.parent.wallet.get_tx_status(tx_hash, tx_mined_info)

        # we sort by timestamp
        if timestamp is None:
            timestamp = float("inf")

        if role == Qt.UserRole:
            # for sorting
            d = {
                HistoryColumns.STATUS:
                    # height breaks ties for unverified txns
                    # txpos breaks ties for verified same block txns
                    (-timestamp, conf, -status, -height, -txpos) if not is_lightning else (-timestamp, 0,0,0,-txpos),
                HistoryColumns.DESCRIPTION:
                    tx_item['label'] if 'label' in tx_item else None,
                HistoryColumns.AMOUNT:
                    (tx_item['bc_value'].value if 'bc_value' in tx_item else 0)\
                    + (tx_item['ln_value'].value if 'ln_value' in tx_item else 0),
                HistoryColumns.BALANCE:
                    (tx_item['balance'].value if 'balance' in tx_item else 0)\
                    + (tx_item['balance_msat']//1000 if 'balance_msat'in tx_item else 0),
                HistoryColumns.FIAT_VALUE:
                    tx_item['fiat_value'].value if 'fiat_value' in tx_item else None,
                HistoryColumns.FIAT_ACQ_PRICE:
                    tx_item['acquisition_price'].value if 'acquisition_price' in tx_item else None,
                HistoryColumns.FIAT_CAP_GAINS:
                    tx_item['capital_gain'].value if 'capital_gain' in tx_item else None,
                HistoryColumns.TXID: tx_hash if not is_lightning else None,
            }
            return QVariant(d[col])
        if role not in (Qt.DisplayRole, Qt.EditRole):
            if col == HistoryColumns.STATUS and role == Qt.DecorationRole:
                icon = "lightning" if is_lightning else TX_ICONS[status]
                return QVariant(read_QIcon(icon))
            elif col == HistoryColumns.STATUS and role == Qt.ToolTipRole:
                msg = 'lightning transaction' if is_lightning else str(conf) + _(" confirmation" + ("s" if conf != 1 else ""))
                return QVariant(msg)
            elif col > HistoryColumns.DESCRIPTION and role == Qt.TextAlignmentRole:
                return QVariant(Qt.AlignRight | Qt.AlignVCenter)
            elif col != HistoryColumns.STATUS and role == Qt.FontRole:
                monospace_font = QFont(MONOSPACE_FONT)
                return QVariant(monospace_font)
            #elif col == HistoryColumns.DESCRIPTION and role == Qt.DecorationRole and not is_lightning\
            #        and self.parent.wallet.invoices.paid.get(tx_hash):
            #    return QVariant(read_QIcon("seal"))
            elif col in (HistoryColumns.DESCRIPTION, HistoryColumns.AMOUNT) \
                    and role == Qt.ForegroundRole and not is_lightning and tx_item['value'].value < 0:
                red_brush = QBrush(QColor("#BC1E1E"))
                return QVariant(red_brush)
            elif col == HistoryColumns.FIAT_VALUE and role == Qt.ForegroundRole \
                    and not tx_item.get('fiat_default') and tx_item.get('fiat_value') is not None:
                blue_brush = QBrush(QColor("#1E1EFF"))
                return QVariant(blue_brush)
            return QVariant()
        if col == HistoryColumns.STATUS:
            return QVariant(status_str)
        elif col == HistoryColumns.DESCRIPTION and 'label' in tx_item:
            return QVariant(tx_item['label'])
        elif col == HistoryColumns.AMOUNT:
            bc_value = tx_item['bc_value'].value if 'bc_value' in tx_item else 0
            ln_value = tx_item['ln_value'].value if 'ln_value' in tx_item else 0
            value = bc_value + ln_value
            v_str = self.parent.format_amount(value, is_diff=True, whitespaces=True)
            return QVariant(v_str)
        elif col == HistoryColumns.BALANCE:
            balance = tx_item['balance'].value
            balance_str = self.parent.format_amount(balance, whitespaces=True)
            return QVariant(balance_str)
        elif col == HistoryColumns.FIAT_VALUE and 'fiat_value' in tx_item:
            value_str = self.parent.fx.format_fiat(tx_item['fiat_value'].value)
            return QVariant(value_str)
        elif col == HistoryColumns.FIAT_ACQ_PRICE and \
                tx_item['value'].value < 0 and 'acquisition_price' in tx_item:
            # fixme: should use is_mine
            acq = tx_item['acquisition_price'].value
            return QVariant(self.parent.fx.format_fiat(acq))
        elif col == HistoryColumns.FIAT_CAP_GAINS and 'capital_gain' in tx_item:
            cg = tx_item['capital_gain'].value
            return QVariant(self.parent.fx.format_fiat(cg))
        elif col == HistoryColumns.TXID:
            return QVariant(tx_hash)
        return QVariant()
Beispiel #33
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        i, j = index.row(), index.column()

        try:
            lbl = self.display_labels[i]
        except IndexError:
            return None

        if isinstance(lbl, ChecksumLabel) and self.message is not None:
            calculated_crc = lbl.calculate_checksum_for_message(
                self.message, use_decoded_bits=True)
        else:
            calculated_crc = None

        if role == Qt.DisplayRole:
            if j == 0:
                return lbl.name
            elif j == 1:
                return lbl.color_index
            elif j == 2:
                return lbl.DISPLAY_FORMATS[lbl.display_format_index]
            elif j == 3:
                return lbl.display_order_str
            elif j == 4:
                return self.__display_data(lbl, calculated_crc)
        elif role == Qt.CheckStateRole and j == 0:
            return lbl.show
        elif role == Qt.BackgroundColorRole:
            if isinstance(
                    lbl,
                    ChecksumLabel) and j == 4 and self.message is not None:
                start, end = self.message.get_label_range(lbl, 0, True)
                if calculated_crc == self.message.decoded_bits[start:end]:
                    return settings.BG_COLOR_CORRECT
                else:
                    return settings.BG_COLOR_WRONG

            else:
                return None

        elif role == Qt.ToolTipRole:
            if j == 2:
                return self.tr(
                    "Choose display type for the value of the label:"
                    "<ul>"
                    "<li>Bit</li>"
                    "<li>Hexadecimal (Hex)</li>"
                    "<li>ASCII chars</li>"
                    "<li>Decimal Number</li>"
                    "<li>Binary Coded Decimal (BCD)</li>"
                    "</ul>")
            if j == 3:
                return self.tr("Choose bit order for the displayed value:"
                               "<ul>"
                               "<li>Most Significant Bit (MSB) [Default]</li>"
                               "<li>Least Significant Bit (LSB)</li>"
                               "<li>Least Significant Digit (LSD)</li>"
                               "</ul>")
        elif role == Qt.FontRole and j == 0:
            font = QFont()
            font.setBold(i in self.selected_label_indices)
            return font
Beispiel #34
0
 def columnCount(self, parent: QModelIndex = ...) -> int:
     if parent.isValid():
         return parent.internalPointer().column_count
     else:
         return self.root_item.column_count
Beispiel #35
0
 def rowCount(self, parent:QModelIndex=None, *args, **kwargs):
         if parent.isValid():  # internal nodes
             child: CustomNode=parent.internalPointer()
             return len(child.children)
         return len(self._root.children)  # first level nodes
Beispiel #36
0
 def flags(self, index: QModelIndex):
     if not index.isValid():
         return 0
     item = index.internalPointer()
     return item.flags(index.column())
Beispiel #37
0
 def hasChildren(self, index: QModelIndex):
     return not index.isValid()
Beispiel #38
0
 def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> QVariant:
     # note: this method is performance-critical.
     # it is called a lot, and so must run extremely fast.
     assert index.isValid()
     col = index.column()
     tx_item = self.transactions.value_from_pos(index.row())
     tx_hash = tx_item['txid']
     conf = tx_item['confirmations']
     txpos = tx_item['txpos_in_block'] or 0
     height = tx_item['height']
     try:
         status, status_str = self.tx_status_cache[tx_hash]
     except KeyError:
         tx_mined_info = self.tx_mined_info_from_tx_item(tx_item)
         status, status_str = self.parent.wallet.get_tx_status(
             tx_hash, tx_mined_info)
     if role == Qt.UserRole:
         # for sorting
         d = {
             HistoryColumns.STATUS_ICON:
             # height breaks ties for unverified txns
             # txpos breaks ties for verified same block txns
             (status, conf, -height, -txpos),
             HistoryColumns.STATUS_TEXT:
             status_str,
             HistoryColumns.DESCRIPTION:
             tx_item['label'],
             HistoryColumns.COIN_VALUE:
             tx_item['value'].value,
             HistoryColumns.RUNNING_COIN_BALANCE:
             tx_item['balance'].value,
             HistoryColumns.FIAT_VALUE:
             tx_item['fiat_value'].value
             if 'fiat_value' in tx_item else None,
             HistoryColumns.FIAT_ACQ_PRICE:
             tx_item['acquisition_price'].value
             if 'acquisition_price' in tx_item else None,
             HistoryColumns.FIAT_CAP_GAINS:
             tx_item['capital_gain'].value
             if 'capital_gain' in tx_item else None,
             HistoryColumns.TXID:
             tx_hash,
         }
         return QVariant(d[col])
     if role not in (Qt.DisplayRole, Qt.EditRole):
         if col == HistoryColumns.STATUS_ICON and role == Qt.DecorationRole:
             return QVariant(read_QIcon(TX_ICONS[status]))
         elif col == HistoryColumns.STATUS_ICON and role == Qt.ToolTipRole:
             return QVariant(
                 str(conf) + _(" confirmation" +
                               ("s" if conf != 1 else "")))
         elif col > HistoryColumns.DESCRIPTION and role == Qt.TextAlignmentRole:
             return QVariant(Qt.AlignRight | Qt.AlignVCenter)
         elif col != HistoryColumns.STATUS_TEXT and role == Qt.FontRole:
             monospace_font = QFont(MONOSPACE_FONT)
             return QVariant(monospace_font)
         elif col == HistoryColumns.DESCRIPTION and role == Qt.DecorationRole \
                 and self.parent.wallet.invoices.paid.get(tx_hash):
             return QVariant(read_QIcon("seal"))
         elif col in (HistoryColumns.DESCRIPTION, HistoryColumns.COIN_VALUE) \
                 and role == Qt.ForegroundRole and tx_item['value'].value < 0:
             red_brush = QBrush(QColor("#BC1E1E"))
             return QVariant(red_brush)
         elif col == HistoryColumns.FIAT_VALUE and role == Qt.ForegroundRole \
                 and not tx_item.get('fiat_default') and tx_item.get('fiat_value') is not None:
             blue_brush = QBrush(QColor("#1E1EFF"))
             return QVariant(blue_brush)
         return QVariant()
     if col == HistoryColumns.STATUS_TEXT:
         return QVariant(status_str)
     elif col == HistoryColumns.DESCRIPTION:
         return QVariant(tx_item['label'])
     elif col == HistoryColumns.COIN_VALUE:
         value = tx_item['value'].value
         v_str = self.parent.format_amount(value,
                                           is_diff=True,
                                           whitespaces=True)
         return QVariant(v_str)
     elif col == HistoryColumns.RUNNING_COIN_BALANCE:
         balance = tx_item['balance'].value
         balance_str = self.parent.format_amount(balance, whitespaces=True)
         return QVariant(balance_str)
     elif col == HistoryColumns.FIAT_VALUE and 'fiat_value' in tx_item:
         value_str = self.parent.fx.format_fiat(tx_item['fiat_value'].value)
         return QVariant(value_str)
     elif col == HistoryColumns.FIAT_ACQ_PRICE and \
             tx_item['value'].value < 0 and 'acquisition_price' in tx_item:
         # fixme: should use is_mine
         acq = tx_item['acquisition_price'].value
         return QVariant(self.parent.fx.format_fiat(acq))
     elif col == HistoryColumns.FIAT_CAP_GAINS and 'capital_gain' in tx_item:
         cg = tx_item['capital_gain'].value
         return QVariant(self.parent.fx.format_fiat(cg))
     elif col == HistoryColumns.TXID:
         return QVariant(tx_hash)
     return QVariant()
Beispiel #39
0
    def get_data_for_role(self, index: QModelIndex,
                          role: Qt.ItemDataRole) -> QVariant:
        # note: this method is performance-critical.
        # it is called a lot, and so must run extremely fast.
        assert index.isValid()
        col = index.column()
        window = self.model.parent
        tx_item = self.get_data()
        is_lightning = tx_item.get('lightning', False)
        timestamp = tx_item['timestamp']
        if is_lightning:
            status = 0
            if timestamp is None:
                status_str = 'unconfirmed'
            else:
                status_str = format_time(int(timestamp))
        else:
            tx_hash = tx_item['txid']
            conf = tx_item['confirmations']
            try:
                status, status_str = self.model.tx_status_cache[tx_hash]
            except KeyError:
                tx_mined_info = self.model.tx_mined_info_from_tx_item(tx_item)
                status, status_str = window.wallet.get_tx_status(
                    tx_hash, tx_mined_info)

        if role == Qt.UserRole:
            # for sorting
            d = {
                HistoryColumns.STATUS:
                    # respect sort order of self.transactions (wallet.get_full_history)
                    -index.row(),
                HistoryColumns.DESCRIPTION:
                    tx_item['label'] if 'label' in tx_item else None,
                HistoryColumns.AMOUNT:
                    (tx_item['bc_value'].value if 'bc_value' in tx_item else 0)\
                    + (tx_item['ln_value'].value if 'ln_value' in tx_item else 0),
                HistoryColumns.BALANCE:
                    (tx_item['balance'].value if 'balance' in tx_item else 0),
                HistoryColumns.FIAT_VALUE:
                    tx_item['fiat_value'].value if 'fiat_value' in tx_item else None,
                HistoryColumns.FIAT_ACQ_PRICE:
                    tx_item['acquisition_price'].value if 'acquisition_price' in tx_item else None,
                HistoryColumns.FIAT_CAP_GAINS:
                    tx_item['capital_gain'].value if 'capital_gain' in tx_item else None,
                HistoryColumns.TXID: tx_hash if not is_lightning else None,
            }
            return QVariant(d[col])
        if role not in (Qt.DisplayRole, Qt.EditRole):
            if col == HistoryColumns.STATUS and role == Qt.DecorationRole:
                icon = "lightning" if is_lightning else TX_ICONS[status]
                return QVariant(read_QIcon(icon))
            elif col == HistoryColumns.STATUS and role == Qt.ToolTipRole:
                if is_lightning:
                    msg = 'lightning transaction'
                else:  # on-chain
                    if tx_item['height'] == TX_HEIGHT_LOCAL:
                        # note: should we also explain double-spends?
                        msg = _(
                            "This transaction is only available on your local machine.\n"
                            "The currently connected server does not know about it.\n"
                            "You can either broadcast it now, or simply remove it."
                        )
                    else:
                        msg = str(conf) + _(" confirmation" +
                                            ("s" if conf != 1 else ""))
                return QVariant(msg)
            elif col > HistoryColumns.DESCRIPTION and role == Qt.TextAlignmentRole:
                return QVariant(int(Qt.AlignRight | Qt.AlignVCenter))
            elif col > HistoryColumns.DESCRIPTION and role == Qt.FontRole:
                monospace_font = QFont(MONOSPACE_FONT)
                return QVariant(monospace_font)
            #elif col == HistoryColumns.DESCRIPTION and role == Qt.DecorationRole and not is_lightning\
            #        and self.parent.wallet.invoices.paid.get(tx_hash):
            #    return QVariant(read_QIcon("seal"))
            elif col in (HistoryColumns.DESCRIPTION, HistoryColumns.AMOUNT) \
                    and role == Qt.ForegroundRole and tx_item['value'].value < 0:
                red_brush = QBrush(QColor("#BC1E1E"))
                return QVariant(red_brush)
            elif col == HistoryColumns.FIAT_VALUE and role == Qt.ForegroundRole \
                    and not tx_item.get('fiat_default') and tx_item.get('fiat_value') is not None:
                blue_brush = QBrush(QColor("#1E1EFF"))
                return QVariant(blue_brush)
            return QVariant()
        if col == HistoryColumns.STATUS:
            return QVariant(status_str)
        elif col == HistoryColumns.DESCRIPTION and 'label' in tx_item:
            return QVariant(tx_item['label'])
        elif col == HistoryColumns.AMOUNT:
            bc_value = tx_item['bc_value'].value if 'bc_value' in tx_item else 0
            ln_value = tx_item['ln_value'].value if 'ln_value' in tx_item else 0
            value = bc_value + ln_value
            v_str = window.format_amount(value, is_diff=True, whitespaces=True)
            return QVariant(v_str)
        elif col == HistoryColumns.BALANCE:
            balance = tx_item['balance'].value
            balance_str = window.format_amount(balance, whitespaces=True)
            return QVariant(balance_str)
        elif col == HistoryColumns.FIAT_VALUE and 'fiat_value' in tx_item:
            value_str = window.fx.format_fiat(tx_item['fiat_value'].value)
            return QVariant(value_str)
        elif col == HistoryColumns.FIAT_ACQ_PRICE and \
                tx_item['value'].value < 0 and 'acquisition_price' in tx_item:
            # fixme: should use is_mine
            acq = tx_item['acquisition_price'].value
            return QVariant(window.fx.format_fiat(acq))
        elif col == HistoryColumns.FIAT_CAP_GAINS and 'capital_gain' in tx_item:
            cg = tx_item['capital_gain'].value
            return QVariant(window.fx.format_fiat(cg))
        elif col == HistoryColumns.TXID:
            return QVariant(tx_hash) if not is_lightning else QVariant('')
        return QVariant()
Beispiel #40
0
class editorWidget(QWidget, Ui_editorWidget_ui):
    """
    `editorWidget` is a class responsible for displaying and editing one
    `outlineItem`. This item can be a folder or a text.

    It has four views (see `self.setView`)

      - For folders: "text", "outline" or "cork" (set in `self.folderView`)

        Text: displays a list of `textEditView` in a scroll area

        Outline: displays an outline, using an `outlineView`

        Cork: displays flash cards, using a `corkView`

      - For text: item is simply displayed in a `textEditView`

    All those views are contained in `editorWidget` single widget: `self.stack`.

    `editorWidget` are managed in `tabSplitted` (that allow to open several
    `outlineItem`s, either in Tabs or in split views.

    `tabSplitted` are in turn managed by the `mainEditor`, which is unique and
    gives UI buttons to manage all those views.
    """

    toggledSpellcheck = pyqtSignal(bool)
    dictChanged = pyqtSignal(str)

    _maxTabTitleLength = 24

    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.setupUi(self)
        self.currentIndex = QModelIndex()
        self.currentID = None
        self.txtEdits = []
        self.scroll.setBackgroundRole(QPalette.Base)
        self.toggledSpellcheck.connect(self.txtRedacText.toggleSpellcheck, AUC)
        self.dictChanged.connect(self.txtRedacText.setDict, AUC)
        self.txtRedacText.setHighlighting(True)
        self.currentDict = ""
        self.spellcheck = True
        self.folderView = "cork"
        self.mw = mainWindow()
        self._tabWidget = None  # set by mainEditor on creation

        self._model = None

        # Capture textEdit scrollbar, so that we can put it outside the margins.
        self.txtEditScrollBar = self.txtRedacText.verticalScrollBar()
        self.txtEditScrollBar.setParent(self)
        self.stack.currentChanged.connect(self.setScrollBarVisibility)

        # def setModel(self, model):
        # self._model = model
        # self.setView()

    def resizeEvent(self, event):
        """
        textEdit's scrollBar has been reparented to self. So we need to
        update it's geomtry when self is resized, and put it where we want it
        to be.
        """
        # Update scrollbar geometry
        r = self.geometry()
        w = 10  # Cf. style.mainEditorTabSS
        r.setWidth(w)
        r.moveRight(self.geometry().width())
        self.txtEditScrollBar.setGeometry(r)

        QWidget.resizeEvent(self, event)

    def setScrollBarVisibility(self):
        """
        Since the texteEdit scrollBar has been reparented to self, it is not
        hidden when stack changes. We have to do it manually.
        """
        self.txtEditScrollBar.setVisible(self.stack.currentIndex() == 0)

    def setFolderView(self, v):
        oldV = self.folderView
        if v == "cork":
            self.folderView = "cork"
        elif v == "outline":
            self.folderView = "outline"
        else:
            self.folderView = "text"

        # Saving value
        settings.folderView = self.folderView

        if oldV != self.folderView and self.currentIndex:
            self.setCurrentModelIndex(self.currentIndex)

    def setCorkSizeFactor(self, v):
        self.corkView.itemDelegate().setCorkSizeFactor(v)
        self.redrawCorkItems()

    def redrawCorkItems(self):
        r = self.corkView.rootIndex()

        if r.isValid():
            count = r.internalPointer().childCount()
        elif self._model:
            count = self._model.rootItem.childCount()
        else:
            count = 0

        for c in range(count):
            self.corkView.itemDelegate().sizeHintChanged.emit(r.child(c, 0))

    def updateTabTitle(self):
        """
        `editorWidget` belongs to a `QTabWidget` in a `tabSplitter`. We update
        the tab title to reflect that of current item.
        """
        # `self._tabWidget` is set by mainEditor when creating tab and `editorWidget`.
        # if `editorWidget` is ever used out of `mainEditor`, this could throw
        # an error.
        if not self._tabWidget:
            return

        if self.currentIndex.isValid():
            item = self.currentIndex.internalPointer()
        elif self._model:
            item = self._model.rootItem
        else:
            return

        i = self._tabWidget.indexOf(self)

        self._tabWidget.setTabText(i, self.ellidedTitle(item.title()))
        self._tabWidget.setTabToolTip(i, item.title())

    def ellidedTitle(self, title):
        if len(title) > self._maxTabTitleLength:
            return "{}…".format(title[:self._maxTabTitleLength])
        else:
            return title

    def setView(self):
        # index = mainWindow().treeRedacOutline.currentIndex()

        # Counting the number of other selected items
        # sel = []
        # for i in mainWindow().treeRedacOutline.selectionModel().selection().indexes():
        # if i.column() != 0: continue
        # if i not in sel: sel.append(i)

        # if len(sel) != 0:
        # item = index.internalPointer()
        # else:
        # index = QModelIndex()
        # item = self.mw.mdlOutline.rootItem

        # self.currentIndex = index

        if self.currentIndex.isValid():
            item = self.currentIndex.internalPointer()
        else:
            item = self.mw.mdlOutline.rootItem

        self.updateTabTitle()

        def addTitle(itm):
            edt = MDEditView(self,
                             html="<h{l}>{t}</h{l}>".format(l=min(
                                 itm.level() + 1, 5),
                                                            t=itm.title()),
                             autoResize=True)
            edt.setFrameShape(QFrame.NoFrame)
            self.txtEdits.append(edt)
            l.addWidget(edt)

        def addLine():
            line = QFrame(self.text)
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)
            l.addWidget(line)

        def addText(itm):
            edt = MDEditView(self,
                             index=itm.index(),
                             spellcheck=self.spellcheck,
                             dict=settings.dict,
                             highlighting=True,
                             autoResize=True)
            edt.setFrameShape(QFrame.NoFrame)
            edt.setStatusTip("{}".format(itm.path()))
            self.toggledSpellcheck.connect(edt.toggleSpellcheck, AUC)
            self.dictChanged.connect(edt.setDict, AUC)
            # edt.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
            self.txtEdits.append(edt)
            l.addWidget(edt)

        def addChildren(itm):
            for c in range(itm.childCount()):
                child = itm.child(c)

                if child.isFolder():
                    addTitle(child)
                    addChildren(child)

                else:
                    addText(child)
                    addLine()

        def addSpacer():
            l.addItem(
                QSpacerItem(10, 1000, QSizePolicy.Minimum,
                            QSizePolicy.Expanding))

            # Display multiple selected items
            # if len(sel) > 1 and False:  # Buggy and not very useful, skip
            # self.stack.setCurrentIndex(1)
            # w = QWidget()
            # l = QVBoxLayout(w)
            # self.txtEdits = []
            # for idx in sel:
            # sItem = idx.internalPointer()
            # addTitle(sItem)
            # if sItem.isFolder():
            # addChildren(sItem)
            # else:
            # addText(sItem)
            # addLine()
            # addSpacer()
            # self.scroll.setWidget(w)

        if item and item.isFolder() and self.folderView == "text":
            self.stack.setCurrentIndex(1)
            w = QWidget()
            w.setObjectName("editorWidgetFolderText")
            l = QVBoxLayout(w)
            opt = settings.textEditor
            background = (opt["background"] if not opt["backgroundTransparent"]
                          else "transparent")
            w.setStyleSheet("background: {};".format(background))
            self.stack.widget(1).setStyleSheet(
                "background: {}".format(background))
            # self.scroll.setWidgetResizable(False)

            self.txtEdits = []

            if item != self._model.rootItem:
                addTitle(item)

            addChildren(item)
            addSpacer()
            self.scroll.setWidget(w)

        elif item and item.isFolder() and self.folderView == "cork":
            self.stack.setCurrentIndex(2)
            self.corkView.setModel(self._model)
            self.corkView.setRootIndex(self.currentIndex)
            try:
                self.corkView.selectionModel().selectionChanged.connect(
                    mainWindow().redacMetadata.selectionChanged, AUC)
                self.corkView.clicked.connect(
                    mainWindow().redacMetadata.selectionChanged, AUC)
                self.corkView.clicked.connect(
                    mainWindow().mainEditor.updateTargets, AUC)
            except TypeError:
                pass

        elif item and item.isFolder() and self.folderView == "outline":
            self.stack.setCurrentIndex(3)
            self.outlineView.setModelCharacters(mainWindow().mdlCharacter)
            self.outlineView.setModelLabels(mainWindow().mdlLabels)
            self.outlineView.setModelStatus(mainWindow().mdlStatus)
            self.outlineView.setModel(self._model)
            self.outlineView.setRootIndex(self.currentIndex)

            try:
                self.outlineView.selectionModel().selectionChanged.connect(
                    mainWindow().redacMetadata.selectionChanged, AUC)
                self.outlineView.clicked.connect(
                    mainWindow().redacMetadata.selectionChanged, AUC)
                self.outlineView.clicked.connect(
                    mainWindow().mainEditor.updateTargets, AUC)
            except TypeError:
                pass

        if item and item.isText():
            self.txtRedacText.setCurrentModelIndex(self.currentIndex)
            self.stack.setCurrentIndex(0)  # Single text item
        else:
            self.txtRedacText.setCurrentModelIndex(QModelIndex())

        try:
            self._model.dataChanged.connect(self.modelDataChanged, AUC)
            self._model.rowsInserted.connect(self.updateIndexFromID, AUC)
            self._model.rowsRemoved.connect(self.updateIndexFromID, AUC)
            #self.mw.mdlOutline.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC)
        except TypeError:
            pass

        self.updateStatusBar()

    def setCurrentModelIndex(self, index=None):
        if index.isValid():
            self.currentIndex = index
            self._model = index.model()
            self.currentID = self._model.ID(index)
        else:
            self.currentIndex = QModelIndex()
            self.currentID = None

        if self._model:
            self.setView()

    def updateIndexFromID(self):
        """
        Index might have changed (through drag an drop), so we keep current
        item's ID and update index. Item might have been deleted too.
        """
        idx = self._model.getIndexByID(self.currentID)

        # If we have an ID but the ID does not exist, it has been deleted
        if self.currentID and idx == QModelIndex():
            # Item has been deleted, we open the parent instead
            self.setCurrentModelIndex(self.currentIndex.parent())
            # FIXME: selection in self.mw.treeRedacOutline is not updated
            #        but we cannot simply setCurrentIndex through treeRedacOutline
            #        because this might be a tab in the background / out of focus
            #        Also the UI of mainEditor is not updated (so the folder icons
            #        are not display, button "up" doesn't work, etc.).

        # Item has been moved
        elif idx != self.currentIndex:
            # We update the index
            self.currentIndex = idx
            self.setView()

    def modelDataChanged(self, topLeft, bottomRight):
        # if self.currentID:
        # self.updateIndexFromID()
        if not self.currentIndex:
            return
        if topLeft.row() <= self.currentIndex.row() <= bottomRight.row():
            self.updateStatusBar()

    #def rowsAboutToBeRemoved(self, parent, first, last):
    #if self.currentIndex:
    #if self.currentIndex.parent() == parent and \
    #first <= self.currentIndex.row() <= last:
    ## Item deleted, close tab
    #self.mw.mainEditor.tab.removeTab(self.mw.mainEditor.tab.indexOf(self))

    def updateStatusBar(self):
        # Update progress
        # if self.currentIndex and self.currentIndex.isValid():
        # if self._model:
        mw = mainWindow()
        if not mw:
            return

        mw.mainEditor.updateStats()

    def toggleSpellcheck(self, v):
        self.spellcheck = v
        self.toggledSpellcheck.emit(v)

    def setDict(self, dct):
        self.currentDict = dct
        self.dictChanged.emit(dct)

    ###############################################################################
    # FUNCTIONS FOR MENU ACCESS
    ###############################################################################

    def getCurrentItemView(self):
        """
        Returns the current item view, between txtRedacText, outlineView and
        corkView. If folder/text view, returns None. (Because handled
        differently)
        """

        if self.stack.currentIndex() == 0:
            return self.txtRedacText
        elif self.folderView == "outline":
            return self.outlineView
        elif self.folderView == "cork":
            return self.corkView
        else:
            return None

    def copy(self):
        if self.getCurrentItemView(): self.getCurrentItemView().copy()

    def cut(self):
        if self.getCurrentItemView(): self.getCurrentItemView().cut()

    def paste(self):
        if self.getCurrentItemView(): self.getCurrentItemView().paste()

    def rename(self):
        if self.getCurrentItemView(): self.getCurrentItemView().rename()

    def duplicate(self):
        if self.getCurrentItemView(): self.getCurrentItemView().duplicate()

    def delete(self):
        if self.getCurrentItemView(): self.getCurrentItemView().delete()

    def moveUp(self):
        if self.getCurrentItemView(): self.getCurrentItemView().moveUp()

    def moveDown(self):
        if self.getCurrentItemView(): self.getCurrentItemView().moveDown()

    def splitDialog(self):
        """
        Opens a dialog to split selected items.
        """
        if self.getCurrentItemView() == self.txtRedacText:
            # Text editor
            if not self.currentIndex.isValid():
                return

            sel = self.txtRedacText.textCursor().selectedText()
            # selectedText uses \u2029 instead of \n, no idea why.
            sel = sel.replace("\u2029", "\n")
            splitDialog(self, [self.currentIndex], mark=sel)

        elif self.getCurrentItemView():
            # One of the views
            self.getCurrentItemView().splitDialog()

    def splitCursor(self):
        """
        Splits items at cursor position. If there is a selection, that selection
        becomes the new item's title.

        Call context: Only works when editing a file.
        """

        if not self.currentIndex.isValid():
            return

        if self.getCurrentItemView() == self.txtRedacText:
            c = self.txtRedacText.textCursor()

            title = c.selectedText()
            # selection can be backward
            pos = min(c.selectionStart(), c.selectionEnd())

            item = self.currentIndex.internalPointer()

            item.splitAt(pos, len(title))

    def merge(self):
        """
        Merges selected items together.

        Call context: Multiple selection, same parent.
        """
        if self.getCurrentItemView() == self.txtRedacText:
            # Text editor, nothing to merge
            pass

        elif self.getCurrentItemView():
            # One of the views
            self.getCurrentItemView().merge()
Beispiel #41
0
 def rowCount(self, parent: QModelIndex = QModelIndex()) -> int:
     """Qt Model API function. Returns the number of rows/children for the given parent."""
     if not parent.isValid():
         return len(self.images)
     else:
         return parent.internalPointer().row_count()
Beispiel #42
0
 def parent(self, in_index: QModelIndex=None):
     if in_index.isValid():
         parent=in_index.internalPointer().parent
         if parent:
             return QtCore.QAbstractItemModel.createIndex(self,parent.row,0,parent)
     return QtCore.QModelIndex()
Beispiel #43
0
 def columnCount(self,parent: QModelIndex=None, *args, **kwargs):
     if parent.isValid():
         return parent.internalPointer().columnCount()
     return self._root.columnCount()
 def columnCount(self, parent: QtCore.QModelIndex = None):
     """Return the number of columns"""
     if parent is None:
         parent = QtCore.QModelIndex()
     return 8 if not parent.isValid() else 0
Beispiel #45
0
 def itemFromIndex(self, index):
     index = QModelIndex(
         index)  # explicitly convert from QPersistentModelIndex
     if index.isValid():
         return index.internalPointer().childAt(index.row())
     return self._root
Beispiel #46
0
 def parentFromIndex(self, index):
     index = QModelIndex(
         index)  # explicitly convert from QPersistentModelIndex
     if index.isValid():
         return index.internalPointer()
     return self._root
Beispiel #47
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):

        if not index.isValid():
            return None

        row = index.row()

        # check for special case where no backup devices are active
        if len(self.rows) == 0:
            if role == Qt.DisplayRole:
                return ViewRowType.header
            elif role == Roles.device_details:
                if not self.prefs.backup_files:
                    return _("Backups are not configured"), self.removableIcon
                elif self.prefs.backup_device_autodetection:
                    return _("No backup devices detected"), self.removableIcon
                else:
                    return (
                        _("Valid backup locations not yet specified"),
                        self.folderIcon,
                    )

        # at least one device  / location is being used
        if row >= len(self.rows) or row < 0:
            return None
        if row not in self.rows:
            return None

        row_id = self.rows[row]
        path = self.row_id_to_path[row_id]

        if role == Qt.DisplayRole:
            if row_id in self.headers:
                return ViewRowType.header
            else:
                return ViewRowType.content
        else:
            device = self.backup_devices[path]
            mount = device.mount

            if role == Qt.ToolTipRole:
                return path
            elif role == Roles.device_details:
                if self.prefs.backup_device_autodetection:
                    icon = self.removableIcon
                else:
                    icon = self.folderIcon
                return device.display_name, icon
            elif role == Roles.storage:
                (
                    photos_size_to_download,
                    videos_size_to_download,
                ) = self._download_size_by_backup_type(
                    backup_type=device.backup_type)

                (
                    photos_size_to_download,
                    videos_size_to_download,
                ) = adjusted_download_size(
                    photos_size_to_download=photos_size_to_download,
                    videos_size_to_download=videos_size_to_download,
                    os_stat_device=device.os_stat_device,
                    downloading_to=self._downloading_to,
                )

                bytes_total, bytes_free = get_mount_size(mount=mount)

                return BackupVolumeUse(
                    bytes_total=bytes_total,
                    bytes_free=bytes_free,
                    backup_type=device.backup_type,
                    marked=self.marked,
                    photos_size_to_download=photos_size_to_download,
                    videos_size_to_download=videos_size_to_download,
                )

        return None
Beispiel #48
0
 def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> QVariant:
     assert index.isValid()
     col = index.column()
     coin_item = index.internalPointer()
     address = coin_item['address']
     is_frozen_addr = coin_item['is_frozen_addr']
     is_frozen_coin = coin_item['is_frozen_coin']
     height = coin_item['height']
     outpoint = coin_item['outpoint']
     out_short = coin_item['out_short']
     label = coin_item['label']
     balance = coin_item['balance']
     ps_rounds = coin_item['ps_rounds']
     is_ps_ks = coin_item['is_ps_ks']
     if ps_rounds is None:
         ps_rounds = 'N/A'
     elif ps_rounds == PSCoinRounds.COLLATERAL:
         ps_rounds = 'Collateral'
     elif ps_rounds == PSCoinRounds.OTHER:
         ps_rounds = 'Other'
     else:
         ps_rounds = str(ps_rounds)
     if role == Qt.ToolTipRole:
         if col == UTXOColumns.ADDRESS and is_frozen_addr:
             return QVariant(_('Address is frozen'))
         elif col == UTXOColumns.OUTPOINT:
             if is_frozen_coin:
                 return QVariant(f'{outpoint}\n{_("Coin is frozen")}')
             else:
                 return QVariant(outpoint)
     elif role not in (Qt.DisplayRole, Qt.EditRole):
         if role == Qt.TextAlignmentRole:
             if col in [
                     UTXOColumns.AMOUNT, UTXOColumns.HEIGHT,
                     UTXOColumns.PS_ROUNDS, UTXOColumns.KEYSTORE_TYPE
             ]:
                 return QVariant(Qt.AlignRight | Qt.AlignVCenter)
             else:
                 return QVariant(Qt.AlignVCenter)
         elif role == Qt.FontRole:
             return QVariant(QFont(MONOSPACE_FONT))
         elif role == Qt.BackgroundRole:
             if col == UTXOColumns.ADDRESS and is_frozen_addr:
                 return QVariant(ColorScheme.BLUE.as_color(True))
             elif col == UTXOColumns.OUTPOINT and is_frozen_coin:
                 return QVariant(ColorScheme.BLUE.as_color(True))
     elif col == UTXOColumns.OUTPOINT:
         return QVariant(out_short)
     elif col == UTXOColumns.ADDRESS:
         return QVariant(address)
     elif col == UTXOColumns.LABEL:
         return QVariant(label)
     elif col == UTXOColumns.AMOUNT:
         return QVariant(balance)
     elif col == UTXOColumns.HEIGHT:
         return QVariant(height)
     elif col == UTXOColumns.PS_ROUNDS:
         return QVariant(ps_rounds)
     elif col == UTXOColumns.KEYSTORE_TYPE:
         return QVariant(_('PS Keystore') if is_ps_ks else _('Main'))
     else:
         return QVariant()
 def rowCount(self, parent: QtCore.QModelIndex = None):
     """Return the number of rows"""
     if parent is None:
         parent = QtCore.QModelIndex()
     return len(self._residues) if not parent.isValid() else 0
Beispiel #50
0
 def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> QVariant:
     if not index.isValid():
         return QVariant()
     item = index.internalPointer()
     # Delegate to the model instance data() method
     return item.data(index.column(), role)
Beispiel #51
0
    def paint(self, painter: QtGui.QPainter, option: 'QStyleOptionViewItem',
              index: QtCore.QModelIndex) -> None:
        """
        Paints the message on the screen

        :param painter: Controls actual painting
        :param option: Options for painting
        :param index: Index of item
        :return:
        """

        if not index.isValid():
            return

        painter.save(
        )  # Save current state, before altering for custom painting

        painter.setRenderHints(QPainter.Antialiasing)

        context = index.model().chat_message_contexts()[index.row()]
        message_text = index.data(Qt.DisplayRole)
        profile_pix: QPixmap = index.data(Qt.DecorationRole)

        # Determine message rect
        message_font = QApplication.font()
        message_fm = QFontMetrics(message_font)

        if context.is_sender:
            # Paint text with 10 pixel padding
            message_rect = message_fm.boundingRect(
                option.rect.left(),
                option.rect.top() + MessageItemDelegate.profile_padding / 2,
                option.rect.width() - MessageItemDelegate.total_pfp_width, 0,
                Qt.AlignRight | Qt.AlignTop | Qt.TextWordWrap, message_text)

            # Draw bubble rect
            bubble_rect = QRect(
                message_rect.left() - MessageItemDelegate.profile_padding / 2,
                message_rect.top() - MessageItemDelegate.profile_padding / 2,
                message_rect.width() + MessageItemDelegate.profile_padding,
                message_rect.height() + MessageItemDelegate.profile_padding)
            blue = QColor(35, 57, 93)
            painter.setBrush(blue)
            painter.setPen(blue)
            painter.drawRoundedRect(bubble_rect, 5, 5)

            painter.setPen(Qt.white)
            painter.setFont(message_font)
            painter.drawText(message_rect,
                             Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap,
                             message_text)

            # Paint icon
            profile_rect = QRect(
                message_rect.right() + MessageItemDelegate.profile_padding,
                option.rect.top(), MessageItemDelegate.icon_radius,
                MessageItemDelegate.icon_radius)
            painter.drawPixmap(profile_rect, profile_pix)
        else:

            # Paint icon
            profile_rect = QRect(option.rect.left(), option.rect.top(),
                                 MessageItemDelegate.icon_radius,
                                 MessageItemDelegate.icon_radius)
            painter.drawPixmap(profile_rect, profile_pix)

            # Paint text with 10 pixel padding
            message_rect = message_fm.boundingRect(
                profile_rect.right() + MessageItemDelegate.profile_padding,
                option.rect.top() + MessageItemDelegate.profile_padding / 2,
                option.rect.width() - MessageItemDelegate.total_pfp_width, 0,
                Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap, message_text)

            # Draw bubble rect
            bubble_rect = QRect(
                message_rect.left() - MessageItemDelegate.profile_padding / 2,
                message_rect.top() - MessageItemDelegate.profile_padding / 2,
                message_rect.width() + MessageItemDelegate.profile_padding,
                message_rect.height() + MessageItemDelegate.profile_padding)
            gray = QColor(105, 105, 105)
            painter.setBrush(gray)
            painter.setPen(gray)
            painter.drawRoundedRect(bubble_rect, 5, 5)

            painter.setPen(Qt.white)
            painter.setFont(message_font)
            painter.drawText(message_rect,
                             Qt.AlignLeft | Qt.AlignTop | Qt.TextWordWrap,
                             message_text)

        painter.restore()  # Reset to state before changes
Beispiel #52
0
 def flags(self, index: QModelIndex):
     if not index.isValid():
         return Qt.ItemIsEnabled
     return (qc.QAbstractItemModel.flags(self, index)
             | Qt.ItemIsEditable
             | Qt.ItemNeverHasChildren)
    def canDropMimeData(self, mime_data: QtCore.QMimeData,
                        action: QtCore.Qt.DropAction, target_row: int,
                        target_column: int,
                        target_parent: QtCore.QModelIndex) -> bool:

        # Some tests if drop is possible at the given location.

        # Only a drop - flags non withstanding - on the ingredient column is possible
        if target_column != self.IngredientColumns.INGREDIENT and target_column != -1:
            return False

        # A drop on the root column
        if target_parent.isValid(
        ) and target_parent.column() != self.IngredientColumns.INGREDIENT:
            return False

        drop_on_item = target_row == -1 and target_column == -1

        # Test all dragged item - if one of those fails, a drop doesn't make sense

        # Unfortunately we cannot rely on item's position - because the user might have dragged the items before
        # and position might not reflect the position inside the tree anymore. This is trade off: Either renumber
        # the tree's content each time a drag has occurred - and causing database load - or renumber the tree only
        # when the user saves the changes, making it more difficult to determine the item's status
        # (group, alternative..)
        for index in self._dragged_indices:
            parent_item = index.parent()

            # -------------------- Groups ---------------------
            # This is the only case where item_position can be safely used: A group can only be moved within the
            # root level, so even if the position doesn't reflect the model's position, it's OK to use the
            # information to determine if it's a group or a root level ingredient
            if data.IngredientListEntry.is_group(
                    int(index.data(QtCore.Qt.UserRole))):
                # A group cannot be dropped on another group or item
                if drop_on_item:
                    # Attempted drop on an item, no matter on which level
                    return False
                else:
                    # A move before/after target_parent's item
                    if target_parent.isValid():
                        # There's a parent (i.e. a level below root)
                        return False

                    if index.row() == target_row:
                        # Drag in front of itself. Makes no sense
                        return False

                    # A group can only be moved inside the "group window", i.e. between the tree's very first row
                    # and before the first root-level ingredient
                    if target_row > 0:
                        previous_index = self.index(
                            target_row - 1, self.IngredientColumns.INGREDIENT,
                            QtCore.QModelIndex())
                        if previous_index == index:
                            # Drag behind itself. Makes no sense
                            return False
                        if not data.IngredientListEntry.is_group(
                                int(previous_index.data(QtCore.Qt.UserRole))):
                            # No group - trying to move the group into the root level ingredients
                            return False

            # -------------------- Ingredients --------------------
            else:
                # Two case: Either a move or a drop on an item (i.e. attach it to parent)
                # First, drop on an item
                if drop_on_item:
                    if not target_parent.isValid():
                        return False

                    # Drop on a group
                    if data.IngredientListEntry.is_group(
                            int(target_parent.data(QtCore.Qt.UserRole))):
                        # The item is allowed to have children, but only if it's an ingredient
                        # (and not alternative ingredients, otherwise the level would change: and becomes or and or
                        # becomes the ingredient. This isn't what the user really wants)
                        if self.hasChildren(index):
                            if self.depth(
                                    index) != self.IngredientLevels.INGREDIENT:
                                return False

                        if self.rowCount(
                                index) >= data.IngredientListEntry.MAX_ENTRIES:
                            return False

                        if parent_item is not None and parent_item == target_parent:
                            return False
                    else:
                        # Only accept items that haven't got children. Otherwise this would lead to odd results:
                        # Ingredient B which has an alternative C (B OR C) dropped on Ingredient A would lead to:
                        # Ingredient A OR Ingredient B AND Ingredient C, which is clearly not right. Alternatively
                        # do some major internal rewriting
                        if self.hasChildren(index):
                            return False

                        # Only a certain level can be accepted
                        if self.depth(
                                target_parent
                        ) >= self.IngredientLevels.ALTERNATIVEGROUP:
                            return False

                        if self.rowCount(
                                target_parent
                        ) >= data.IngredientListEntry.MAX_ENTRIES:
                            return False
                else:
                    # Move
                    parent_level = self.IngredientLevels.ROOT
                    if target_parent.isValid():
                        parent_level = self.depth(target_parent)
                        if self.rowCount(
                                target_parent
                        ) >= data.IngredientListEntry.MAX_ENTRIES:
                            return False

                    # The root-level ingredients have to be beneath the grouped items
                    if parent_level == self.IngredientLevels.ROOT:
                        number_of_root_items = self.invisibleRootItem(
                        ).rowCount()

                        # target_row == number_of_root_items would mean an append at the end of the list,
                        # which would be perfectly acceptable
                        if target_row < number_of_root_items:
                            next_index = self.index(
                                target_row, self.IngredientColumns.INGREDIENT,
                                QtCore.QModelIndex())
                            if data.IngredientListEntry.is_group(
                                    int(next_index.data(QtCore.Qt.UserRole))):
                                # trying to move an ingredient item before a group
                                return False

                    # Contrary to drop, moving an item with children is allowed.. but only if its moved on the
                    # same level. Otherwise the tree would either increase it's depth to a invalid value or
                    # something similar confusing like dropping an item with children on an item would occur.
                    if self.hasChildren(index):
                        # Since parent is always one level higher than the item
                        if parent_level != self.depth(index) - 1:
                            return False

        return super().canDropMimeData(mime_data, action, target_row,
                                       target_column, target_parent)
Beispiel #54
0
 def _indexToItem(self, index: QModelIndex):
     if not index.isValid():
         return self._root
     else:
         return index.internalPointer()
Beispiel #55
0
 def rowCount(self, parent: QtCore.QModelIndex = ...) -> int:
     if parent.isValid():
         pointer = parent.internalPointer()
         return pointer.rowCount()
     else:
         return self.root.rowCount()
Beispiel #56
0
 def index(self, row: int, column: int, parent: QModelIndex):
     if not parent.isValid():  # parent is root
         if len(self.coin_items) > row:
             return self.createIndex(row, column, self.coin_items[row])
     return QModelIndex()
    def data(self, index: QModelIndex, role: int = ...):

        if not index.isValid():
            return QVariant()

        node: EncounterNode = index.internalPointer()
        p: Entity = self.encounter.entities[node.player]
        h = self.headers[index.column()]

        if h == self.TXT_CLASS and role == Qt.DecorationRole:
            if node.pixmap is None:
                try:
                    #print("was none")
                    specInfo = self.resourceHandler.getSpecialization(p.elite, p.prof)
                    p = QPixmap()
                    p.loadFromData(specInfo[self.resourceHandler.PROFESSION_ICON])
                    p = p.scaled(QSize(20, 20), Qt.KeepAspectRatio, Qt.SmoothTransformation)
                    node.pixmap = p
                except Exception as e:
                    return QVariant()
            return node.pixmap

        if role == Qt.TextAlignmentRole:
            if h in [self.TXT_SUBSQUAD, self.TXT_CLASS, self.TXT_DEAD, self.TXT_DOWN, self.TXT_DPS, self.TXT_BOSS_DPS, self.TXT_DMG_BOSS, self.TXT_DMG_TOTAL]:
                return Qt.AlignCenter

        if role == Qt.DisplayRole:

            if h == self.TXT_SUBSQUAD:
                return p.subsquad
            if h == self.TXT_CHARACTER:
                return p.character
            if h == self.TXT_ACCOUNT:
                return p.account
            if h == self.TXT_BOSS_DPS:
                return self.encounter.getBossDps(node.player)
            if h == self.TXT_DPS:
                return self.encounter.getTotalDps(node.player)
            if h == self.TXT_DMG_TOTAL:
                return p.damage.totalOut
            if h ==  self.TXT_DMG_BOSS:
                return self.encounter.getBossDamage(node.player)
            if h == self.TXT_DOWN:
                return p.downed
            if h == self.TXT_DEAD:
                return p.dead
            return QVariant()

        if role == Qt.BackgroundRole:
            if not self.encounter.fullComplete:
                return QVariant()
            rightBound = self.headerWidths[index.column()]/self.totalWidth
            leftBound = 0
            if index.column() > 0:
                leftBound = self.headerWidths[index.column() - 1]/self.totalWidth

            # barBound = self.encounter.getTotalDps(node.player)/self.highestRowValue
            if self.highestRowValue == 0:
                barBound = 0
            else:
                barBound = self.data(self.createIndex(index.row(), self.sortColumn, node), Qt.DisplayRole)/self.highestRowValue

            profColor = QColor(*reference.CLASS_COLORS[p.prof], 60)
            if rightBound <= barBound:
                return profColor
            elif leftBound >= barBound:
                return QVariant()
            else:
                colpercent = rightBound - leftBound
                colwidth = 0
                if index.column() > 0:
                    colwidth = self.headerWidths[index.column()] - self.headerWidths[index.column() - 1]
                else:
                    colwidth = self.headerWidths[index.column()]
                toFill = barBound-leftBound

                gradient = QLinearGradient(0, 0, colwidth, 0)
                gradient.setColorAt(toFill/colpercent, profColor)
                gradient.setColorAt((toFill/colpercent) + .000001, QColor('white'))
                brush = QBrush(gradient)
                return brush
Beispiel #58
0
    def data(self, model_index: QModelIndex, role: int) -> QVariant:
        row = model_index.row()
        column = model_index.column()
        if row >= len(self._data):
            return None
        if column >= len(self._column_names):
            return None

        if model_index.isValid():
            line = self._data[row]

            # First check the custom sort role.
            if role == QT_SORT_ROLE:
                if column == TYPE_COLUMN:
                    if line.flags & AddressFlags.RECEIVING:
                        return 1
                    elif line.flags & AddressFlags.CHANGE:
                        return 2
                    return 100
                elif column == STATE_COLUMN:
                    if line.flags & AddressFlags.FROZEN:
                        return 1
                    elif line.flags & AddressFlags.RETIRED:
                        return 2
                    elif line.flags & AddressFlags.BEYOND_LIMIT:
                        return 3
                    return 0
                elif column == ADDRESS_COLUMN:
                    return line.address.hash160()
                elif column == INDEX_COLUMN:
                    return line.index
                elif column == LABEL_COLUMN:
                    return self._view._wallet.labels.get(line.address.to_string(), '')
                elif column == USAGES_COLUMN:
                    return len(self._view._wallet.get_address_history(line.address))
                elif column in (BALANCE_COLUMN, FIAT_BALANCE_COLUMN):
                    if column == BALANCE_COLUMN:
                        return self._view._parent.format_amount(line.balance, whitespaces=True)
                    elif column == FIAT_BALANCE_COLUMN:
                        fx = app_state.fx
                        rate = fx.exchange_rate()
                        return fx.value_str(line.balance, rate)

            elif role == Qt.DecorationRole:
                if column == TYPE_COLUMN:
                    if line.flags & AddressFlags.RECEIVING:
                        return self._receive_icon
                    elif line.flags & AddressFlags.CHANGE:
                        return self._change_icon

            elif role == Qt.DisplayRole:
                if column == TYPE_COLUMN:
                    pass
                elif column == STATE_COLUMN:
                    if line.flags & AddressFlags.BEYOND_LIMIT:
                        return "B"
                elif column == ADDRESS_COLUMN:
                    return line.address.to_string()
                elif column == INDEX_COLUMN:
                    return line.index
                elif column == LABEL_COLUMN:
                    return self._view._wallet.get_address_label(line.address.to_string())
                elif column == USAGES_COLUMN:
                    return len(self._view._wallet.get_address_history(line.address))
                elif column == BALANCE_COLUMN:
                    return self._view._parent.format_amount(line.balance, whitespaces=True)
                elif column == FIAT_BALANCE_COLUMN:
                    fx = app_state.fx
                    rate = fx.exchange_rate()
                    return fx.value_str(line.balance, rate)
            elif role == Qt.FontRole:
                if column in (ADDRESS_COLUMN, BALANCE_COLUMN, FIAT_BALANCE_COLUMN):
                    return self._monospace_font

            elif role == Qt.BackgroundRole:
                if column == STATE_COLUMN:
                    if line.flags & AddressFlags.FROZEN:
                        return self._frozen_brush
                    elif line.flags & AddressFlags.RETIRED:
                        return self._archived_brush
                    elif line.flags & AddressFlags.BEYOND_LIMIT:
                        return self._beyond_limit_brush
            elif role == Qt.TextAlignmentRole:
                if column in (TYPE_COLUMN, STATE_COLUMN):
                    return Qt.AlignCenter
                elif column in (BALANCE_COLUMN, FIAT_BALANCE_COLUMN, USAGES_COLUMN, INDEX_COLUMN):
                    return Qt.AlignRight | Qt.AlignVCenter
                return Qt.AlignVCenter

            elif role == Qt.ToolTipRole:
                if column == TYPE_COLUMN:
                    if line.flags & AddressFlags.RECEIVING:
                        return _("Receiving address")
                    elif line.flags & AddressFlags.CHANGE:
                        return _("Change address")
                elif column == STATE_COLUMN:
                    if line.flags & AddressFlags.FROZEN:
                        return _("This is a frozen address")
                    elif line.flags & AddressFlags.RETIRED:
                        return _("This an address that was once in use, "+
                            "but is now empty and has been retired")
                    elif line.flags & AddressFlags.BEYOND_LIMIT:
                        return _("This address is generated from beyond the current gap limit")

            elif role == Qt.EditRole:
                if column == LABEL_COLUMN:
                    return self._view._wallet.get_address_label(line.address.to_string())
Beispiel #59
0
    def data(self, index: QModelIndex, role=Qt.DisplayRole):
        if not index.isValid():
            return None

        i, j = index.row(), index.column()

        try:
            lbl = self.display_labels[i]
        except IndexError:
            return None

        if isinstance(lbl, ChecksumLabel) and self.message is not None:
            calculated_crc = lbl.calculate_checksum_for_message(self.message, use_decoded_bits=True)
        else:
            calculated_crc = None

        if role == Qt.DisplayRole:
            if j == 0:
                return lbl.name
            elif j == 1:
                return lbl.color_index
            elif j == 2:
                return lbl.DISPLAY_FORMATS[lbl.display_format_index]
            elif j == 3:
                return lbl.display_order_str
            elif j == 4:
                return self.__display_data(lbl, calculated_crc)
        elif role == Qt.CheckStateRole and j == 0:
            return lbl.show
        elif role == Qt.BackgroundColorRole:
            if isinstance(lbl, ChecksumLabel) and j == 4 and self.message is not None:
                start, end = self.message.get_label_range(lbl, 0, True)
                if calculated_crc == self.message.decoded_bits[start:end]:
                    return constants.BG_COLOR_CORRECT
                else:
                    return constants.BG_COLOR_WRONG

            else:
                return None

        elif role == Qt.ToolTipRole:
            if j == 2:
                return self.tr("Choose display type for the value of the label:"
                               "<ul>"
                               "<li>Bit</li>"
                               "<li>Hexadecimal (Hex)</li>"
                               "<li>ASCII chars</li>"
                               "<li>Decimal Number</li>"
                               "<li>Binary Coded Decimal (BCD)</li>"
                               "</ul>")
            if j == 3:
                return self.tr("Choose bit order for the displayed value:"
                               "<ul>"
                               "<li>Most Significant Bit (MSB) [Default]</li>"
                               "<li>Least Significant Bit (LSB)</li>"
                               "<li>Least Significant Digit (LSD)</li>"
                               "</ul>")
        elif role == Qt.FontRole and j == 0:
            font = QFont()
            font.setBold(i in self.selected_label_indices)
            return font
Beispiel #60
0
    def flags(self, index: QModelIndex):
        if not index.isValid():
            return Qt.ItemIsEnabled

        return Qt.ItemIsEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEditable