예제 #1
0
파일: viewer.py 프로젝트: laurentb/weboob
    def setData(self, model, qidx):
        self.model = model
        self.current = QPersistentModelIndex(qidx)

        self.model.rowsInserted.connect(self.updatePos)
        self.model.rowsRemoved.connect(self.updatePos)
        self.model.rowsInserted.connect(self.updateNavButtons)
        self.model.rowsRemoved.connect(self.updateNavButtons)
        self.model.dataChanged.connect(self._dataChanged)
        self.model.modelReset.connect(self.disable)

        self.updateImage()
예제 #2
0
 def set_current_idx(self, set_current: QPersistentModelIndex):
     if set_current:
         assert isinstance(set_current, QPersistentModelIndex)
         assert set_current.isValid()
         self.selectionModel().select(QModelIndex(set_current), QItemSelectionModel.SelectCurrent)
예제 #3
0
 def createEditor(self, parent, option, idx):
     self.opened = QPersistentModelIndex(idx)
     return super().createEditor(parent, option, idx)
예제 #4
0
    def update_model(self, clear=True):
        log.info("updating effects model.")
        app = get_app()

        # Get window to check filters
        win = app.window
        _ = app._tr

        # Clear all items
        if clear:
            self.model_names = {}
            self.model.clear()

        # Add Headers
        self.model.setHorizontalHeaderLabels(
            [_("Thumb"), _("Name"), _("Description")])

        # Get the folder path of effects
        effects_dir = os.path.join(info.PATH, "effects")
        icons_dir = os.path.join(effects_dir, "icons")

        # Get a JSON list of all supported effects in libopenshot
        raw_effects_list = json.loads(openshot.EffectInfo.Json())

        # Loop through each effect
        for effect_info in raw_effects_list:
            # Get basic properties about each effect
            effect_name = effect_info["class_name"]
            title = effect_info["name"]
            description = effect_info["description"]
            # Remove any spaces from icon name
            icon_name = "%s.png" % effect_name.lower().replace(' ', '')
            icon_path = os.path.join(icons_dir, icon_name)

            # Determine the category of effect (audio, video, both)
            category = None
            if effect_info["has_video"] and effect_info["has_audio"]:
                category = "Audio & Video"
            elif not effect_info["has_video"] and effect_info["has_audio"]:
                category = "Audio"
            elif effect_info["has_video"] and not effect_info["has_audio"]:
                category = "Video"

            # Filter out effect (if needed)
            if (win.effectsFilter.text() != ""
                    and win.effectsFilter.text().lower()
                    not in self.app._tr(title).lower()
                    and win.effectsFilter.text().lower()
                    not in self.app._tr(description).lower()):
                continue

            # Check for thumbnail path (in build-in cache)
            thumb_path = os.path.join(info.IMAGES_PATH, "cache", icon_name)

            # Check built-in cache (if not found)
            if not os.path.exists(thumb_path):
                # Check user folder cache
                thumb_path = os.path.join(info.CACHE_PATH, icon_name)

            # Generate thumbnail (if needed)
            if not os.path.exists(thumb_path):

                try:
                    # Reload this reader
                    log.info('Generating thumbnail for %s (%s)' %
                             (thumb_path, icon_path))
                    clip = openshot.Clip(icon_path)
                    reader = clip.Reader()

                    # Open reader
                    reader.Open()

                    # Save thumbnail
                    reader.GetFrame(0).Thumbnail(
                        thumb_path, 98, 64,
                        os.path.join(info.IMAGES_PATH, "mask.png"), "", "#000",
                        True, "png", 85)
                    reader.Close()

                except Exception:
                    # Handle exception
                    log.info('Invalid effect image file: %s' % icon_path)
                    msg = QMessageBox()
                    msg.setText(
                        _("{} is not a valid image file.".format(icon_path)))
                    msg.exec_()
                    continue

            row = []

            # Append thumbnail
            col = QStandardItem()

            icon_pixmap = QPixmap(thumb_path)
            scaled_pixmap = icon_pixmap.scaled(QSize(98,
                                                     64), Qt.IgnoreAspectRatio,
                                               Qt.SmoothTransformation)
            col.setIcon(QIcon(scaled_pixmap))
            col.setText(self.app._tr(title))
            col.setToolTip(self.app._tr(title))
            col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled
                         | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
            row.append(col)

            # Append Name
            col = QStandardItem("Name")
            col.setData(self.app._tr(title), Qt.DisplayRole)
            col.setText(self.app._tr(title))
            col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled
                         | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
            row.append(col)

            # Append Description
            col = QStandardItem("Description")
            col.setData(self.app._tr(description), Qt.DisplayRole)
            col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled
                         | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
            row.append(col)

            # Append Category
            col = QStandardItem("Category")
            col.setData(category, Qt.DisplayRole)
            col.setText(category)
            col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled
                         | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
            row.append(col)

            # Append Path
            col = QStandardItem("Effect")
            col.setData(effect_name, Qt.DisplayRole)
            col.setText(effect_name)
            col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled
                         | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
            row.append(col)

            # Append ROW to MODEL (if does not already exist in model)
            if effect_name not in self.model_names:
                self.model.appendRow(row)
                self.model_names[effect_name] = QPersistentModelIndex(
                    row[1].index())

        # Emit signal when model is updated
        self.ModelRefreshed.emit()
예제 #5
0
 def update(self):
     self.wallet = self.parent.wallet
     current_address = self.current_item_user_role(col=self.Columns.LABEL)
     if self.show_change == 1:
         addr_list = self.wallet.get_receiving_addresses()
     elif self.show_change == 2:
         addr_list = self.wallet.get_change_addresses()
     else:
         addr_list = self.wallet.get_addresses()
     self.model().clear()
     self.refresh_headers()
     fx = self.parent.fx
     set_address = None
     for address in addr_list:
         num = self.wallet.get_address_history_len(address)
         label = self.wallet.labels.get(address, '')
         c, u, x = self.wallet.get_addr_balance(address)
         balance = c + u + x
         is_used_and_empty = self.wallet.is_used(address) and balance == 0
         if self.show_used == 1 and (balance or is_used_and_empty):
             continue
         if self.show_used == 2 and balance == 0:
             continue
         if self.show_used == 3 and not is_used_and_empty:
             continue
         balance_text = self.parent.format_amount(balance, whitespaces=True)
         # create item
         if fx and fx.get_fiat_address_config():
             rate = fx.exchange_rate()
             fiat_balance = fx.value_str(balance, rate)
         else:
             fiat_balance = ''
         labels = ['', address, label, balance_text, fiat_balance, "%d"%num]
         address_item = [QStandardItem(e) for e in labels]
         # align text and set fonts
         for i, item in enumerate(address_item):
             item.setTextAlignment(Qt.AlignVCenter)
             if i not in (self.Columns.TYPE, self.Columns.LABEL):
                 item.setFont(QFont(MONOSPACE_FONT))
             item.setEditable(i in self.editable_columns)
         address_item[self.Columns.FIAT_BALANCE].setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
         # setup column 0
         if self.wallet.is_change(address):
             address_item[self.Columns.TYPE].setText(_('change'))
             address_item[self.Columns.TYPE].setBackground(ColorScheme.YELLOW.as_color(True))
         else:
             address_item[self.Columns.TYPE].setText(_('receiving'))
             address_item[self.Columns.TYPE].setBackground(ColorScheme.GREEN.as_color(True))
         address_item[self.Columns.LABEL].setData(address, Qt.UserRole)
         # setup column 1
         if self.wallet.is_frozen(address):
             address_item[self.Columns.ADDRESS].setBackground(ColorScheme.BLUE.as_color(True))
         if self.wallet.is_beyond_limit(address):
             address_item[self.Columns.ADDRESS].setBackground(ColorScheme.RED.as_color(True))
         # add item
         count = self.model().rowCount()
         self.model().insertRow(count, address_item)
         address_idx = self.model().index(count, self.Columns.LABEL)
         if address == current_address:
             set_address = QPersistentModelIndex(address_idx)
     self.set_current_idx(set_address)
     # show/hide columns
     if fx and fx.get_fiat_address_config():
         self.showColumn(self.Columns.FIAT_BALANCE)
     else:
         self.hideColumn(self.Columns.FIAT_BALANCE)
예제 #6
0
파일: viewer.py 프로젝트: laurentb/weboob
class Viewer(QtMainWindow):
    jobAdded = Signal()
    jobFinished = Signal()

    def __init__(self, weboob, parent=None):
        super(Viewer, self).__init__(parent)

        self.ui = Ui_Viewer()
        self.ui.setupUi(self)
        self.ui.prevButton.clicked.connect(self.prev)
        self.ui.nextButton.clicked.connect(self.next)
        self.ui.firstButton.clicked.connect(self.first)
        self.ui.lastButton.clicked.connect(self.last)
        self.ui.actionZoomIn.triggered.connect(self.zoomIn)
        self.ui.actionZoomOut.triggered.connect(self.zoomOut)
        self.ui.actionFullSize.triggered.connect(self.zoomFullSize)
        self.ui.actionFitWindow.triggered.connect(self.zoomFit)

        self.ui.actionSaveImage.setShortcut(QKeySequence.Save)
        self.ui.actionSaveImage.triggered.connect(self.saveImage)
        self.ui.actionClose.setShortcut(QKeySequence.Close)
        self.ui.actionClose.triggered.connect(self.close)

        self.model = None
        self.current = None
        self.total = 0
        self.zoomFactor = 1
        self.zoomMode = ZOOM_FACTOR
        self.weboob = weboob

    def setData(self, model, qidx):
        self.model = model
        self.current = QPersistentModelIndex(qidx)

        self.model.rowsInserted.connect(self.updatePos)
        self.model.rowsRemoved.connect(self.updatePos)
        self.model.rowsInserted.connect(self.updateNavButtons)
        self.model.rowsRemoved.connect(self.updateNavButtons)
        self.model.dataChanged.connect(self._dataChanged)
        self.model.modelReset.connect(self.disable)

        self.updateImage()

    @Slot()
    def disable(self):
        self.setEnabled(False)

    def updateNavButtons(self):
        prev = self.current.row() > 0
        self.ui.prevButton.setEnabled(prev)
        self.ui.firstButton.setEnabled(prev)
        next = self.current.row() < self.total - 1
        self.ui.nextButton.setEnabled(next)
        self.ui.lastButton.setEnabled(next)

    def updatePos(self):
        self.total = self.model.rowCount(self.current.parent())
        self.ui.posLabel.setText('%d / %d' % (self.current.row() + 1, self.total))

    def updateImage(self):
        self.updatePos()
        self.updateNavButtons()

        obj = self.current.data(ResultModel.RoleObject)

        if obj.data is NotLoaded:
            self.model.fillObj(obj, ['data'], QModelIndex(self.current))
            self.pixmap = None
        elif obj.data:
            self.pixmap = QPixmap(QImage.fromData(obj.data))
        else:
            self.pixmap = QPixmap()

        self._rebuildImage()

    @Slot(QModelIndex)
    def _dataChanged(self, qidx):
        if qidx == self.current:
            obj = qidx.data(ResultModel.RoleObject)

            if obj.data:
                self.pixmap = QPixmap(QImage.fromData(obj.data))
            else:
                self.pixmap = QPixmap()
            self._rebuildImage()

    @Slot()
    def next(self):
        new = self.current.sibling(self.current.row() + 1, 0)
        if not new.isValid():
            return
        self.current = QPersistentModelIndex(new)
        self.updateImage()

    @Slot()
    def prev(self):
        if self.current.row() == 0:
            return
        self.current = QPersistentModelIndex(self.current.sibling(self.current.row() - 1, 0))
        self.updateImage()

    @Slot()
    def first(self):
        self.current = QPersistentModelIndex(self.current.sibling(0, 0))
        self.updateImage()

    @Slot()
    def last(self):
        self.current = QPersistentModelIndex(self.current.sibling(self.total - 1, 0))
        self.updateImage()

    @Slot()
    def zoomIn(self):
        self.zoomFactor *= 1.25
        self.zoomMode = ZOOM_FACTOR
        self._rebuildImage()

    @Slot()
    def zoomOut(self):
        self.zoomFactor *= 0.75
        self.zoomMode = ZOOM_FACTOR
        self._rebuildImage()

    @Slot()
    def zoomFullSize(self):
        self.zoomFactor = 1
        self.zoomMode = ZOOM_FACTOR
        self._rebuildImage()

    @Slot()
    def zoomFit(self):
        self.zoomMode = ZOOM_FIT
        self._rebuildImage()

    def resizeEvent(self, ev):
        super(Viewer, self).resizeEvent(ev)
        if self.zoomMode == ZOOM_FIT:
            self._rebuildImage()

    def _rebuildZoom(self):
        if self.zoomMode == ZOOM_FACTOR:
            new_width = int(self.pixmap.width() * self.zoomFactor)
            pixmap = self.pixmap.scaledToWidth(new_width, Qt.SmoothTransformation)
        else:
            new_size = self.ui.scrollArea.viewport().size()
            pixmap = self.pixmap.scaled(new_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
            self.zoomFactor = pixmap.width() / float(self.pixmap.width())
        return pixmap

    def _rebuildImage(self):
        if self.pixmap is None:
            self.ui.view.setText('Loading...')
            return
        elif self.pixmap.isNull():
            self.ui.view.setText('Image could not be loaded')
            return

        pixmap = self._rebuildZoom()
        self.ui.view.setPixmap(pixmap)

    @Slot()
    def saveImage(self):
        def ext_for_filter(s):
            return re.match(r'(?:[A-Z]+) \(\*\.([a-z]+)\)$', s).group(1)

        if not self.pixmap:
            return

        filters = ['PNG (*.png)', 'JPEG (*.jpg)', 'GIF (*.gif)']

        obj = self.current.data(ResultModel.RoleObject)
        name = '%s.%s' % (obj.title or obj.id or u'', obj.ext or 'png')
        default = filters[0]
        for f in filters:
            if name.endswith(ext_for_filter(f)):
                default = f
        filters = ';;'.join(filters)

        target = os.path.join(self.parent().lastSaveDir, name)
        out, filter = QFileDialog.getSaveFileName(self, 'Save image', target, filters, default)
        if not out:
            return

        ext = ext_for_filter(filter)

        self.parent().lastSaveDir = os.path.dirname(out)
        if not os.path.splitext(out)[1]:
            out = '%s.%s' % (out, ext)

            if os.path.exists(out):
                q = self.tr('%s already exists, are you sure you want to replace it?') % out
                reply = QMessageBox.question(self, self.tr('Overwrite?'), q)
                if reply == QMessageBox.No:
                    return self.saveImage()

        self.pixmap.save(out, ext.upper())
예제 #7
0
파일: viewer.py 프로젝트: laurentb/weboob
 def first(self):
     self.current = QPersistentModelIndex(self.current.sibling(0, 0))
     self.updateImage()
예제 #8
0
파일: viewer.py 프로젝트: laurentb/weboob
 def next(self):
     new = self.current.sibling(self.current.row() + 1, 0)
     if not new.isValid():
         return
     self.current = QPersistentModelIndex(new)
     self.updateImage()
예제 #9
0
 def create_menu(self, position: QPoint):
     org_idx: QModelIndex = self.indexAt(position)
     idx = self.proxy.mapToSource(org_idx)
     if not idx.isValid():
         # can happen e.g. before list is populated for the first time
         return
     tx_item = self.hm.transactions.value_from_pos(idx.row())
     if tx_item.get('lightning') and tx_item['type'] == 'payment':
         menu = QMenu()
         menu.addAction(
             _("View Payment"),
             lambda: self.parent.show_lightning_transaction(tx_item))
         cc = self.add_copy_menu(menu, idx)
         cc.addAction(
             _("Payment Hash"),
             lambda: self.place_text_on_clipboard(tx_item['payment_hash'],
                                                  title="Payment Hash"))
         cc.addAction(
             _("Preimage"),
             lambda: self.place_text_on_clipboard(tx_item['preimage'],
                                                  title="Preimage"))
         menu.exec_(self.viewport().mapToGlobal(position))
         return
     tx_hash = tx_item['txid']
     if tx_item.get('lightning'):
         tx = self.wallet.lnworker.lnwatcher.db.get_transaction(tx_hash)
     else:
         tx = self.wallet.db.get_transaction(tx_hash)
     if not tx:
         return
     tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
     tx_details = self.wallet.get_tx_info(tx)
     is_unconfirmed = tx_details.tx_mined_status.height <= 0
     invoice_keys = self.wallet._get_relevant_invoice_keys_for_tx(tx)
     menu = QMenu()
     if tx_details.can_remove:
         menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash))
     cc = self.add_copy_menu(menu, idx)
     cc.addAction(
         _("Transaction ID"),
         lambda: self.place_text_on_clipboard(tx_hash, title="TXID"))
     for c in self.editable_columns:
         if self.isColumnHidden(c): continue
         label = self.hm.headerData(c, Qt.Horizontal, Qt.DisplayRole)
         # TODO use siblingAtColumn when min Qt version is >=5.11
         persistent = QPersistentModelIndex(
             org_idx.sibling(org_idx.row(), c))
         menu.addAction(_("Edit {}").format(label),
                        lambda p=persistent: self.edit(QModelIndex(p)))
     menu.addAction(_("View Transaction"),
                    lambda: self.show_transaction(tx_item, tx))
     channel_id = tx_item.get('channel_id')
     if channel_id:
         menu.addAction(
             _("View Channel"),
             lambda: self.parent.show_channel(bytes.fromhex(channel_id)))
     if is_unconfirmed and tx:
         # note: the current implementation of RBF *needs* the old tx fee
         if tx_details.can_bump and tx_details.fee is not None:
             menu.addAction(_("Increase fee"),
                            lambda: self.parent.bump_fee_dialog(tx))
         else:
             child_tx = self.wallet.cpfp(tx, 0)
             if child_tx:
                 menu.addAction(_("Child pays for parent"),
                                lambda: self.parent.cpfp(tx, child_tx))
     if invoice_keys:
         menu.addAction(
             read_QIcon("seal"), _("View invoice"), lambda:
             [self.parent.show_invoice(key) for key in invoice_keys])
     if tx_URL:
         menu.addAction(_("View on block explorer"),
                        lambda: webopen(tx_URL))
     menu.exec_(self.viewport().mapToGlobal(position))
예제 #10
0
    def create_menu(self, position: QPoint):
        org_idx: QModelIndex = self.indexAt(position)
        idx = self.proxy.mapToSource(org_idx)
        if not idx.isValid():
            # can happen e.g. before list is populated for the first time
            return
        tx_item = self.hm.transactions.value_from_pos(idx.row())
        column = idx.column()
        if column == HistoryColumns.STATUS_ICON:
            column_title = _('Transaction ID')
            column_data = tx_item['txid']
        else:
            column_title = self.hm.headerData(column, Qt.Horizontal,
                                              Qt.DisplayRole)
            column_data = self.hm.data(idx, Qt.DisplayRole).value()
        tx_hash = tx_item['txid']
        tx = self.wallet.db.get_transaction(tx_hash)
        if not tx:
            return
        tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
        height = self.wallet.get_tx_height(tx_hash).height
        is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
        is_unconfirmed = height <= 0
        pr_key = self.wallet.invoices.paid.get(tx_hash)
        menu = QMenu()
        if height == TX_HEIGHT_LOCAL:
            menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash))

        amount_columns = [
            HistoryColumns.COIN_VALUE, HistoryColumns.RUNNING_COIN_BALANCE,
            HistoryColumns.FIAT_VALUE, HistoryColumns.FIAT_ACQ_PRICE,
            HistoryColumns.FIAT_CAP_GAINS
        ]
        if column in amount_columns:
            column_data = column_data.strip()
        menu.addAction(
            _("Copy {}").format(column_title),
            lambda: self.parent.app.clipboard().setText(column_data))

        for c in self.editable_columns:
            if self.isColumnHidden(c): continue
            label = self.hm.headerData(c, Qt.Horizontal, Qt.DisplayRole)
            # TODO use siblingAtColumn when min Qt version is >=5.11
            persistent = QPersistentModelIndex(
                org_idx.sibling(org_idx.row(), c))
            menu.addAction(_("Edit {}").format(label),
                           lambda p=persistent: self.edit(QModelIndex(p)))
        menu.addAction(_("Details"), lambda: self.show_transaction(tx_hash))
        if is_unconfirmed and tx:
            # note: the current implementation of RBF *needs* the old tx fee
            rbf = is_mine and not tx.is_final() and fee is not None
            if rbf:
                menu.addAction(_("Increase fee"),
                               lambda: self.parent.bump_fee_dialog(tx))
            else:
                child_tx = self.wallet.cpfp(tx, 0)
                if child_tx:
                    menu.addAction(_("Child pays for parent"),
                                   lambda: self.parent.cpfp(tx, child_tx))
        if pr_key:
            menu.addAction(read_QIcon("seal"), _("View invoice"),
                           lambda: self.parent.show_invoice(pr_key))
        if tx_URL:
            menu.addAction(_("View on block explorer"),
                           lambda: webopen(tx_URL))
        menu.exec_(self.viewport().mapToGlobal(position))
예제 #11
0
    def myDropEvent(self, event, drop_item):
        """Workaround for broken QTreeWidget::dropEvent
        per https://bugreports.qt.io/browse/QTBUG-45320
        doing reverse ordering of items on dropping. reimplementation in python
        from C++

        For this code we need dual GPL3 license instead of pure BSD3
        """
        if event.source() == self and (event.dropAction() == Qt.MoveAction
                                       or self.dragDropMode()
                                       == QAbstractItemView.InternalMove):
            droptuple = self.dropOn(event, drop_item)
            if droptuple is not None:
                (row, col, drop_index) = droptuple
                # print("droptuple", droptuple[2].row())
                idxs = self.selectedIndexes()
                indexes = []
                for idx in idxs:
                    if idx.column() == 0:
                        indexes.append(idx)
                if drop_index in indexes:
                    return
                # When removing items the drop location could shift
                new_drop_index = QPersistentModelIndex(self.model().index(
                    row, col, drop_index))
                # print("updatated drop_row", new_drop_index.row())
                # Remove the items
                taken = []
                for i in range(len(indexes) - 1, -1, -1):
                    # print("idx", indexes[i].row(), indexes[i].column())
                    parent = self.itemFromIndex(indexes[i])
                    if parent is None or parent.parent() is None:
                        t_item = self.takeTopLevelItem(indexes[i].row())
                        taken.append(t_item)
                    else:
                        t_item = parent.parent().takeChild(indexes[i].row())
                        taken.append(t_item)
                # end for
                # insert them back in at their new positions
                for i in range(len(indexes)):
                    # Either at a specific point or appended
                    if row == -1:
                        if drop_index.isValid():
                            parent = self.itemFromIndex(drop_index)
                            parent.insertChild(parent.childCount(),
                                               taken.pop())
                        else:
                            self.insertTopLevelItem(self.topLevelItemCount(),
                                                    taken.pop())
                    else:
                        r = new_drop_index.row(
                        ) if new_drop_index.row() >= 0 else row
                        if drop_index.isValid():
                            parent = self.itemFromIndex(drop_index)
                            parent.insertChild(min(r, parent.childCount()),
                                               taken.pop())
                        else:
                            self.insertTopLevelItem(
                                min(r, self.topLevelItemCount()), taken.pop())
                # end for

                event.accept()
                # Don't want QAbstractItemView to delete it because it was "moved" we already did it
                event.setDropAction(Qt.CopyAction)
        QTreeView.dropEvent(self, event)
예제 #12
0
 def update(self):
     if self.maybe_defer_update():
         return
     current_address = self.current_item_user_role(col=self.Columns.LABEL)
     if self.show_change == AddressTypeFilter.RECEIVING:
         addr_list = self.wallet.get_receiving_addresses()
     elif self.show_change == AddressTypeFilter.CHANGE:
         addr_list = self.wallet.get_change_addresses()
     else:
         addr_list = self.wallet.get_addresses()
     self.proxy.setDynamicSortFilter(False)  # temp. disable re-sorting after every change
     self.std_model.clear()
     self.refresh_headers()
     fx = self.parent.fx
     set_address = None
     addresses_beyond_gap_limit = self.wallet.get_all_known_addresses_beyond_gap_limit()
     for address in addr_list:
         num = self.wallet.get_address_history_len(address)
         label = self.wallet.labels.get(address, '')
         c, u, x = self.wallet.get_addr_balance(address)
         balance = c + u + x
         is_used_and_empty = self.wallet.is_used(address) and balance == 0
         if self.show_used == AddressUsageStateFilter.UNUSED and (balance or is_used_and_empty):
             continue
         if self.show_used == AddressUsageStateFilter.FUNDED and balance == 0:
             continue
         if self.show_used == AddressUsageStateFilter.USED_AND_EMPTY and not is_used_and_empty:
             continue
         balance_text = self.parent.format_amount(balance, whitespaces=True)
         # create item
         if fx and fx.get_fiat_address_config():
             rate = fx.exchange_rate()
             fiat_balance = fx.value_str(balance, rate)
         else:
             fiat_balance = ''
         labels = ['', address, label, balance_text, fiat_balance, "%d"%num]
         address_item = [QStandardItem(e) for e in labels]
         # align text and set fonts
         for i, item in enumerate(address_item):
             item.setTextAlignment(Qt.AlignVCenter)
             if i not in (self.Columns.TYPE, self.Columns.LABEL):
                 item.setFont(QFont(MONOSPACE_FONT))
         self.set_editability(address_item)
         address_item[self.Columns.FIAT_BALANCE].setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
         # setup column 0
         if self.wallet.is_change(address):
             address_item[self.Columns.TYPE].setText(_('change'))
             address_item[self.Columns.TYPE].setBackground(ColorScheme.YELLOW.as_color(True))
         else:
             address_item[self.Columns.TYPE].setText(_('receiving'))
             address_item[self.Columns.TYPE].setBackground(ColorScheme.GREEN.as_color(True))
         address_item[self.Columns.LABEL].setData(address, Qt.UserRole)
         address_path = self.wallet.get_address_index(address)
         address_item[self.Columns.TYPE].setData(address_path, self.ROLE_SORT_ORDER)
         address_path_str = self.wallet.get_address_path_str(address)
         if address_path_str is not None:
             address_item[self.Columns.TYPE].setToolTip(address_path_str)
         address_item[self.Columns.FIAT_BALANCE].setData(balance, self.ROLE_SORT_ORDER)
         # setup column 1
         if self.wallet.is_frozen_address(address):
             address_item[self.Columns.ADDRESS].setBackground(ColorScheme.BLUE.as_color(True))
         if address in addresses_beyond_gap_limit:
             address_item[self.Columns.ADDRESS].setBackground(ColorScheme.RED.as_color(True))
         # add item
         count = self.std_model.rowCount()
         self.std_model.insertRow(count, address_item)
         address_idx = self.std_model.index(count, self.Columns.LABEL)
         if address == current_address:
             set_address = QPersistentModelIndex(address_idx)
     self.set_current_idx(set_address)
     # show/hide columns
     if fx and fx.get_fiat_address_config():
         self.showColumn(self.Columns.FIAT_BALANCE)
     else:
         self.hideColumn(self.Columns.FIAT_BALANCE)
     self.filter()
     self.proxy.setDynamicSortFilter(True)
예제 #13
0
def test_model_persistent_index(model_test):
    '''
    ☑ 🛇 read-only.ro
    ☑ ★ user.json
    ☑ ⎕ commands.json
    ☐ 🛇 asset:plover:assets/main.json
    '''
    persistent_index = QPersistentModelIndex(model_test.model.index(1))
    assert persistent_index.row() == 1
    assert persistent_index.data(Qt.CheckStateRole) == Qt.Checked
    assert persistent_index.data(Qt.DecorationRole) == 'favorite'
    assert persistent_index.data(Qt.DisplayRole) == 'user.json'
    model_test.configure(classic_dictionaries_display_order=True)
    assert persistent_index.row() == 2
    assert persistent_index.data(Qt.CheckStateRole) == Qt.Checked
    assert persistent_index.data(Qt.DecorationRole) == 'favorite'
    assert persistent_index.data(Qt.DisplayRole) == 'user.json'
    model_test.model.setData(persistent_index, Qt.Unchecked, Qt.CheckStateRole)
    assert persistent_index.row() == 2
    assert persistent_index.data(Qt.CheckStateRole) == Qt.Unchecked
    assert persistent_index.data(Qt.DecorationRole) == 'normal'
    assert persistent_index.data(Qt.DisplayRole) == 'user.json'
예제 #14
0
    def create_menu(self, position):
        from electrum_axe.wallet import Multisig_Wallet
        is_multisig = isinstance(self.wallet, Multisig_Wallet)
        can_delete = self.wallet.can_delete_address()
        selected = self.selectionModel().selectedRows()
        if not selected:
            return
        multi_select = len(selected) > 1
        addr_items = []
        for idx in selected:
            if not idx.isValid():
                return
            addr_items.append(idx.internalPointer())
        addrs = [addr_item['addr'] for addr_item in addr_items]
        menu = QMenu()
        if not multi_select:
            idx = self.indexAt(position)
            if not idx.isValid():
                return
            col = idx.column()
            item = addr_items[0]
            if not item:
                return
            addr = item['addr']
            is_ps = item['is_ps']
            is_ps_ks = item['is_ps_ks']

            hd = self.am.headerData
            addr_title = hd(AddrColumns.LABEL, None, Qt.DisplayRole)
            column_title = hd(col, None, Qt.DisplayRole)
            label_idx = idx.sibling(idx.row(), AddrColumns.LABEL)

            copy_text = str(self.am.data(idx, Qt.DisplayRole).value())
            if col in [AddrColumns.COIN_BALANCE, AddrColumns.FIAT_BALANCE]:
                copy_text = copy_text.strip()
            menu.addAction(_("Copy {}").format(column_title),
                           lambda: self.place_text_on_clipboard(copy_text))
            menu.addAction(_('Details'),
                           lambda: self.parent.show_address(addr))

            persistent = QPersistentModelIndex(label_idx)
            menu.addAction(_("Edit {}").format(addr_title),
                           lambda p=persistent: self.edit(QModelIndex(p)))

            if not is_ps and not is_ps_ks:
                menu.addAction(_("Request payment"),
                               lambda: self.parent.receive_at(addr))
            if self.wallet.can_export() or self.wallet.psman.is_ps_ks(addr):
                menu.addAction(_("Private key"),
                               lambda: self.parent.show_private_key(addr))
            if not is_multisig and not self.wallet.is_watching_only():
                menu.addAction(_("Sign/verify message"),
                               lambda: self.parent.sign_verify_message(addr))
                menu.addAction(_("Encrypt/decrypt message"),
                               lambda: self.parent.encrypt_message(addr))
            if can_delete:
                menu.addAction(_("Remove from wallet"),
                               lambda: self.parent.remove_address(addr))
            addr_URL = block_explorer_URL(self.config, 'addr', addr)
            if addr_URL:
                menu.addAction(_("View on block explorer"),
                               lambda: webopen(addr_URL))

            if not is_ps:
                def set_frozen_state(addrs, state):
                    self.parent.set_frozen_state_of_addresses(addrs, state)
                if not self.wallet.is_frozen_address(addr):
                    menu.addAction(_("Freeze"),
                                   lambda: set_frozen_state([addr], True))
                else:
                    menu.addAction(_("Unfreeze"),
                                   lambda: set_frozen_state([addr], False))

        coins = self.wallet.get_spendable_coins(addrs, config=self.config)
        if coins:
            menu.addAction(_("Spend from"),
                           lambda: self.parent.spend_coins(coins))

        run_hook('receive_menu', menu, addrs, self.wallet)
        menu.exec_(self.viewport().mapToGlobal(position))
예제 #15
0
 def create_menu(self, position: QPoint):
     org_idx: QModelIndex = self.indexAt(position)
     idx = self.proxy.mapToSource(org_idx)
     if not idx.isValid():
         # can happen e.g. before list is populated for the first time
         return
     tx_item = idx.internalPointer().get_data()
     if tx_item.get('lightning') and tx_item['type'] == 'payment':
         menu = QMenu()
         menu.addAction(
             _("View Payment"),
             lambda: self.parent.show_lightning_transaction(tx_item))
         cc = self.add_copy_menu(menu, idx)
         cc.addAction(
             _("Payment Hash"),
             lambda: self.place_text_on_clipboard(tx_item['payment_hash'],
                                                  title="Payment Hash"))
         cc.addAction(
             _("Preimage"),
             lambda: self.place_text_on_clipboard(tx_item['preimage'],
                                                  title="Preimage"))
         key = tx_item['payment_hash']
         log = self.wallet.lnworker.logs.get(key)
         if log:
             menu.addAction(
                 _("View log"),
                 lambda: self.parent.invoice_list.show_log(key, log))
         menu.exec_(self.viewport().mapToGlobal(position))
         return
     tx_hash = tx_item['txid']
     if tx_item.get('lightning'):
         tx = self.wallet.lnworker.lnwatcher.db.get_transaction(tx_hash)
     else:
         tx = self.wallet.db.get_transaction(tx_hash)
     if not tx:
         return
     tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
     tx_details = self.wallet.get_tx_info(tx)
     is_unconfirmed = tx_details.tx_mined_status.height <= 0
     menu = QMenu()
     if tx_details.can_remove:
         menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash))
     cc = self.add_copy_menu(menu, idx)
     cc.addAction(
         _("Transaction ID"),
         lambda: self.place_text_on_clipboard(tx_hash, title="TXID"))
     for c in self.editable_columns:
         if self.isColumnHidden(c): continue
         label = self.hm.headerData(c, Qt.Horizontal, Qt.DisplayRole)
         # TODO use siblingAtColumn when min Qt version is >=5.11
         persistent = QPersistentModelIndex(
             org_idx.sibling(org_idx.row(), c))
         menu.addAction(_("Edit {}").format(label),
                        lambda p=persistent: self.edit(QModelIndex(p)))
     menu.addAction(_("View Transaction"),
                    lambda: self.show_transaction(tx_item, tx))
     channel_id = tx_item.get('channel_id')
     if channel_id:
         menu.addAction(
             _("View Channel"),
             lambda: self.parent.show_channel(bytes.fromhex(channel_id)))
     if is_unconfirmed and tx:
         if tx_details.can_bump:
             menu.addAction(_("Increase fee"),
                            lambda: self.parent.bump_fee_dialog(tx))
         else:
             if tx_details.can_cpfp:
                 menu.addAction(_("Child pays for parent"),
                                lambda: self.parent.cpfp_dialog(tx))
         if tx_details.can_dscancel:
             menu.addAction(_("Cancel (double-spend)"),
                            lambda: self.parent.dscancel_dialog(tx))
     invoices = self.wallet.get_relevant_invoices_for_tx(tx)
     if len(invoices) == 1:
         menu.addAction(
             _("View invoice"),
             lambda inv=invoices[0]: self.parent.show_onchain_invoice(inv))
     elif len(invoices) > 1:
         menu_invs = menu.addMenu(_("Related invoices"))
         for inv in invoices:
             menu_invs.addAction(
                 _("View invoice"),
                 lambda inv=inv: self.parent.show_onchain_invoice(inv))
     if tx_URL:
         menu.addAction(_("View on block explorer"),
                        lambda: webopen(tx_URL))
     menu.exec_(self.viewport().mapToGlobal(position))
예제 #16
0
 def set_current_idx(self, set_current: QPersistentModelIndex):
     if set_current:
         assert isinstance(set_current, QPersistentModelIndex)
         assert set_current.isValid()
         self.selectionModel().select(QModelIndex(set_current), QItemSelectionModel.SelectCurrent)
예제 #17
0
    def fillTable(self, init=False):
        try:
            if self.crs is None or self.crsLay is None: return
            if self.isHidden() and not init: return
            if self.debug: self.info.log("fillTable", "debug", self.debug)
            self.blockItemChange = True
            self.tblCoords.clear()
            self.tblCoords.setColumnCount(5)
            self.tblCoords.setHorizontalHeaderItem(0, QTableWidgetItem("X"))
            self.tblCoords.setHorizontalHeaderItem(1, QTableWidgetItem("Y"))
            self.tblCoords.setHorizontalHeaderItem(2, QTableWidgetItem(""))
            self.tblCoords.setHorizontalHeaderItem(3, QTableWidgetItem("Xr"))
            self.tblCoords.setHorizontalHeaderItem(4, QTableWidgetItem("Yr"))
            self.tblCoords.horizontalHeader().setSectionHidden(3, self.debug)
            # self.tblCoords.setColumnHidden(3, self.debug)
            self.tblCoords.setColumnHidden(4, self.debug)

            self.tblCoords.horizontalHeader().setSectionResizeMode(
                QHeaderView.Stretch)
            self.tblCoords.horizontalHeader().setSectionResizeMode(
                2, QHeaderView.ResizeToContents)  # QHeaderView.Fixed

            destCrs = self.crs
            self.canvas.refresh()

            if self.cboFeat.currentData():
                feat = self.layer.getFeature(self.cboFeat.currentData())
                geometry = feat.geometry()
                tr = QgsCoordinateTransform(self.crsLay, destCrs, self.prj)
                row = 0
                column = 2  # btn column
                for v in geometry.vertices():
                    self.tblCoords.setRowCount(row + 1)
                    if self.debug: self.info.log("vertex:", v.x(), v.y())
                    v.transform(tr)

                    itemX = QTableWidgetItem(str(v.x()))
                    self.tblCoords.setItem(row, 0, itemX)
                    itemY = QTableWidgetItem(str(v.y()))
                    self.tblCoords.setItem(row, 1, itemY)

                    itemXr = QTableWidgetItem(str(v.x()))
                    self.tblCoords.setItem(row, 3, itemXr)
                    itemYr = QTableWidgetItem(str(v.y()))
                    self.tblCoords.setItem(row, 4, itemYr)

                    index = QPersistentModelIndex(self.tblCoords.model().index(
                        row, column))
                    btn = MyButton(self.gtomain)
                    btn.setIcon(self.icon)
                    btn.click.connect(lambda *args, index=index: self.
                                      cellClick(index.row(), index.column()))
                    btn.setEnabled(False)
                    btn.setPixmap(self.icon.pixmap(24, 24))

                    self.tblCoords.setCellWidget(row, 2, btn)
                    row = row + 1
                    if self.debug:
                        self.info.log("vertex transformed:", v.x(), v.y())
                self.reset()

                if geometry.type(
                ) == QgsWkbTypes.GeometryType.PolygonGeometry:  # remove double vertex????
                    self.tblCoords.removeRow(self.tblCoords.rowCount() - 1)
                if self.isVisible():
                    self.setRubber()
                    self.markedFeature = self.helper.markFeature(
                        self.layer, feat)
                    self.btnZoomTo.setEnabled(True)
                    self.blockItemChange = False
                    self.tblCoords.setCurrentCell(0, 0)
            else:
                self.reset()
            self.blockItemChange = False
        except Exception as e:
            self.info.err(e)
예제 #18
0
파일: viewer.py 프로젝트: laurentb/weboob
 def prev(self):
     if self.current.row() == 0:
         return
     self.current = QPersistentModelIndex(self.current.sibling(self.current.row() - 1, 0))
     self.updateImage()
예제 #19
0
    def Save1VEZExcel(self, trig=1):
        i = 0
        N = []
        nm = []
        lv = []
        t = []
        Pe1 = []
        Pe2 = []
        Pe = []
        current_path = {
            1: self.path_vez_excel,
            2: self.path_ro_excel,
            3: self.path_ro_word
        }[trig]
        try:
            fname = QFileDialog.getSaveFileName(
                self, 'Сохранить файл', current_path,
                '*.xlsx;;*.xls' if trig != 3 else
                '*.docx')[0]  # Обрати внимание на последний элемент
            while self.ski.item(i):
                item = self.ski.item(i)
                if item.checkState():
                    modelindex = QPersistentModelIndex(
                        self.ski.indexFromItem(item))
                    ind = self.d[modelindex]

                    p = self.file_path[ind]
                    if p != None:
                        if self.arr[ind] == None:
                            try:
                                arr, st_arr = imagescan.Scan(p)
                            except Exception:
                                arr = None
                        else:
                            arr = self.arr[ind]
                    else:
                        arr = self.arr[ind]

                    if arr != None and arr != []:
                        if trig == 1:
                            N.append(arr)
                            nm.append(self.file_name[ind])
                            lv.append(self.arr_lv[ind] if
                                      self.arr_lv[ind] != self.lv_c else None)
                            t.append(self.arr_t[ind]
                                     if self.arr_t[ind] != self.t_c else None)
                        elif trig == 2 or trig == 3:
                            try:
                                pe1, pe2, pe = roo.RschRoo(
                                    arr, self.arr_lv[ind], self.arr_t[ind])
                            except Exception:
                                1
                            else:
                                nm.append(self.file_name[ind])
                                lv.append(self.arr_lv[ind])
                                t.append(self.arr_t[ind])
                                Pe1.append(round(pe1, 2))
                                Pe2.append(round(pe2, 2))
                                Pe.append(round(pe, 2))

                i += 1

            if trig == 1:
                if fname != "": self.path_vez_excel = os.path.dirname(fname)
                xlsx.SaveFile1(fname, nm, N, lv, t)
            elif trig == 2:
                if fname != "": self.path_ro_excel = os.path.dirname(fname)
                xlsx.SaveFile2(fname, nm, Pe1, Pe2, Pe, lv, t)
            elif trig == 3:
                if fname != "": self.path_ro_word = os.path.dirname(fname)
                Word.Word(fname, nm, Pe, lv, t, self.NPrj.text(),
                          self.NVL.text())

        except Exception as ex:
            if str(ex) != "string index out of range":
                ems = QErrorMessage(self)
                ems.setWindowTitle('Возникла ошибка')
                ems.showMessage('Не получилось сгенерировать массив точек. ' +
                                str(ex))
        else:
            mes = QMessageBox.information(self,
                                          'Генерация массива точек',
                                          'Операция прошла успешно.',
                                          buttons=QMessageBox.Ok,
                                          defaultButton=QMessageBox.Ok)
예제 #20
0
파일: viewer.py 프로젝트: laurentb/weboob
 def last(self):
     self.current = QPersistentModelIndex(self.current.sibling(self.total - 1, 0))
     self.updateImage()
예제 #21
0
 def presseditem(self, modelindex):
     self.adres = QPersistentModelIndex(modelindex)
예제 #22
0
 def createEditor(self, parent, option, idx):
     self.opened = QPersistentModelIndex(idx)
     self.tv.is_editor_open = True
     return super().createEditor(parent, option, idx)
예제 #23
0
    def create_menu(self, position):
        from electrum.wallet import Multisig_Wallet
        is_multisig = isinstance(self.wallet, Multisig_Wallet)
        can_delete = self.wallet.can_delete_address()
        selected = self.selected_in_column(self.Columns.ADDRESS)
        if not selected:
            return
        multi_select = len(selected) > 1
        addrs = [self.model().itemFromIndex(item).text() for item in selected]
        menu = QMenu()
        if not multi_select:
            idx = self.indexAt(position)
            col = idx.column()
            item = self.model().itemFromIndex(idx)
            if not item:
                return
            addr = addrs[0]

            addr_column_title = self.model().horizontalHeaderItem(
                self.Columns.LABEL).text()
            addr_idx = idx.sibling(idx.row(), self.Columns.LABEL)

            column_title = self.model().horizontalHeaderItem(col).text()
            copy_text = self.model().itemFromIndex(idx).text()
            menu.addAction(
                _("Copy {}").format(column_title),
                lambda: self.place_text_on_clipboard(copy_text))
            menu.addAction(_('Details'),
                           lambda: self.parent.show_address(addr))
            persistent = QPersistentModelIndex(addr_idx)
            menu.addAction(_("Edit {}").format(addr_column_title),
                           lambda p=persistent: self.edit(QModelIndex(p)))
            menu.addAction(_("Request payment"),
                           lambda: self.parent.receive_at(addr))
            if self.wallet.can_export():
                menu.addAction(_("Private key"),
                               lambda: self.parent.show_private_key(addr))
            if not is_multisig and not self.wallet.is_watching_only():
                menu.addAction(_("Sign/verify message"),
                               lambda: self.parent.sign_verify_message(addr))
                menu.addAction(_("Encrypt/decrypt message"),
                               lambda: self.parent.encrypt_message(addr))
            if can_delete:
                menu.addAction(_("Remove from wallet"),
                               lambda: self.parent.remove_address(addr))
            addr_URL = block_explorer_URL(self.config, 'addr', addr)
            if addr_URL:
                menu.addAction(_("View on block explorer"),
                               lambda: webbrowser.open(addr_URL))

            if not self.wallet.is_frozen(addr):
                menu.addAction(
                    _("Freeze"),
                    lambda: self.parent.set_frozen_state([addr], True))
            else:
                menu.addAction(
                    _("Unfreeze"),
                    lambda: self.parent.set_frozen_state([addr], False))

        coins = self.wallet.get_utxos(addrs)
        if coins:
            menu.addAction(_("Spend from"),
                           lambda: self.parent.spend_coins(coins))

        run_hook('receive_menu', menu, addrs, self.wallet)
        menu.exec_(self.viewport().mapToGlobal(position))