Ejemplo n.º 1
0
    def create_menu(self, position):
        menu = QMenu()
        selected = self.selectedItems()
        if not selected:
            menu.addAction(_("New contact"), self.parent.new_contact_dialog)
            menu.addAction(_("Import file"), self.import_contacts)
        else:
            keys = [item.text(1) for item in selected]
            column = self.currentColumn()
            column_title = self.headerItem().text(column)
            column_data = '\n'.join([item.text(column) for item in selected])
            menu.addAction(
                _("Copy {}").format(column_title),
                lambda: self.parent.app.clipboard().setText(column_data))
            if column in self.editable_columns:
                item = self.currentItem()
                menu.addAction(
                    _("Edit {}").format(column_title),
                    lambda: self.editItem(item, column))
            menu.addAction(_("Pay to"),
                           lambda: self.parent.payto_contacts(keys))
            menu.addAction(_("Delete"),
                           lambda: self.parent.delete_contacts(keys))
            URLs = [
                web.BE_URL(self.config, 'addr', Address.from_string(key))
                for key in keys if Address.is_valid(key)
            ]
            if URLs:
                menu.addAction(_("View on block explorer"),
                               lambda: [webbrowser.open(URL) for URL in URLs])

        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 2
0
    def _create_menu(self, position) -> None:
        item = self.currentItem()
        if not item:
            return

        column = self.currentColumn()
        column_title = self.headerItem().text(column)
        column_data = item.text(column).strip()

        tx_hash = item.data(InputColumns.INDEX, Roles.TX_HASH)
        have_tx = self.parent()._account.have_transaction_data(tx_hash)

        tx_id = hash_to_hex_str(tx_hash)
        tx_URL = web.BE_URL(self._main_window.config, 'tx', tx_id)

        menu = QMenu()
        menu.addAction(
            _("Copy {}").format(column_title),
            lambda: self._main_window.app.clipboard().setText(column_data))
        details_menu = menu.addAction(
            _("Transaction details"),
            partial(self._show_other_transaction, tx_hash))
        details_menu.setEnabled(have_tx)
        if tx_URL:
            menu.addAction(_("View on block explorer"),
                           lambda: webbrowser.open(tx_URL))
        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 3
0
    def create_menu(self, position: QPoint) -> None:
        self.selectedIndexes()
        item = self.currentItem()
        if not item:
            return
        column = self.currentColumn()
        account_id = item.data(Columns.STATUS, self.ACCOUNT_ROLE)
        tx_hash = item.data(Columns.STATUS, self.TX_ROLE)
        if account_id is None or tx_hash is None:
            return
        if column == 0:
            column_title = "ID"
            column_data = hash_to_hex_str(tx_hash)
        else:
            column_title = self.headerItem().text(column)
            column_data = item.text(column).strip()

        account = self._wallet.get_account(account_id)

        tx_id = hash_to_hex_str(tx_hash)
        tx_URL = web.BE_URL(self.config, 'tx', tx_id)
        height, _conf, _timestamp = self._wallet.get_tx_height(tx_hash)
        tx = account.get_transaction(tx_hash)
        if not tx:
            return  # this happens sometimes on account synch when first starting up.
        is_unconfirmed = height <= 0

        menu = QMenu()
        menu.addAction(
            _("Copy {}").format(column_title),
            lambda: self._main_window.app.clipboard().setText(column_data))
        if column in self.editable_columns:
            # We grab a fresh reference to the current item, as it has been deleted in a
            # reported issue.
            menu.addAction(
                _("Edit {}").format(column_title),
                lambda: self.currentItem() and self.editItem(
                    self.currentItem(), column))
        menu.addAction(_("Details"),
                       lambda: self._main_window.show_transaction(account, tx))
        if is_unconfirmed and tx:
            child_tx = account.cpfp(tx, 0)
            if child_tx:
                menu.addAction(
                    _("Child pays for parent"),
                    lambda: self._main_window.cpfp(account, tx, child_tx))
        entry = self._account.get_transaction_entry(tx_hash)
        if entry.flags & TxFlags.PaysInvoice:
            invoice_row = self._account.invoices.get_invoice_for_tx_hash(
                tx_hash)
            invoice_id = invoice_row.invoice_id if invoice_row is not None else None
            action = menu.addAction(
                read_QIcon(ICON_NAME_INVOICE_PAYMENT), _("View invoice"),
                partial(self._show_invoice_window, invoice_id))
            action.setEnabled(invoice_id is not None)

        if tx_URL:
            menu.addAction(_("View on block explorer"),
                           lambda: webbrowser.open(tx_URL))
        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 4
0
    def _event_create_menu(self, position):
        selected_indexes = self.selectedIndexes()
        if not len(selected_indexes):
            return
        # This is an index on the sort/filter model, translate it to the base model.
        base_index = get_source_index(selected_indexes[0], HistoryItemModel)
        transformed_index = selected_indexes[0]

        row = base_index.row()
        column = base_index.column()
        line = self._data[row]
        # Does this even happen?
        if not line.tx_hash:
            return

        if column == 0:
            column_title = "ID"
            column_data = line.tx_hash
        else:
            column_title = COLUMN_NAMES[column]
            column_data = self.model().data(transformed_index,
                                            Qt.DisplayRole).strip()

        tx_URL = web.BE_URL(self._main_window.config, 'tx', line.tx_hash)
        tx = self._wallet.get_transaction(line.tx_hash)
        if not tx:
            # this happens sometimes on wallet synch when first starting up.
            return
        is_unconfirmed = line.height <= 0

        menu = QMenu()
        menu.addAction(
            _("Copy {}").format(column_title),
            lambda: app_state.app.clipboard().setText(column_data))

        if column == DESCRIPTION_COLUMN:
            # We grab a fresh reference to the current item, as it has been deleted in a
            # reported issue.
            menu.addAction(
                _("Edit {}").format(column_title),
                partial(self.edit, transformed_index))
        label = self._wallet.get_label(line.tx_hash) or None
        menu.addAction(_("Details"),
                       lambda: self._main_window.show_transaction(tx, label))

        if is_unconfirmed and tx:
            child_tx = self._wallet.cpfp(tx, 0)
            if child_tx:
                menu.addAction(_("Child pays for parent"),
                               partial(self._main_window.cpfp, tx, child_tx))

        pr_key = self._wallet.invoices.paid.get(line.tx_hash)
        if pr_key:
            menu.addAction(read_QIcon("seal"), _("View invoice"),
                           partial(self._main_window.show_invoice, pr_key))
        if tx_URL:
            menu.addAction(_("View on block explorer"),
                           lambda: webbrowser.open(tx_URL))
        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 5
0
    def create_menu(self, position):
        self.selectedIndexes()
        item = self.currentItem()
        if not item:
            return
        column = self.currentColumn()
        edit_data = item.data(0, Qt.UserRole)
        if not edit_data:
            return
        account_id, tx_hash = edit_data
        if column == 0:
            column_title = "ID"
            column_data = hash_to_hex_str(tx_hash)
        else:
            column_title = self.headerItem().text(column)
            column_data = item.text(column).strip()

        account = self._wallet.get_account(account_id)

        tx_id = hash_to_hex_str(tx_hash)
        tx_URL = web.BE_URL(self.config, 'tx', tx_id)
        height, _conf, _timestamp = account.get_tx_height(tx_hash)
        tx = account.get_transaction(tx_hash)
        if not tx:
            return  # this happens sometimes on account synch when first starting up.
        is_unconfirmed = height <= 0
        pr_key = account.invoices.paid.get(tx_hash)

        menu = QMenu()
        menu.addAction(
            _("Copy {}").format(column_title),
            lambda: self._main_window.app.clipboard().setText(column_data))
        if column in self.editable_columns:
            # We grab a fresh reference to the current item, as it has been deleted in a
            # reported issue.
            menu.addAction(
                _("Edit {}").format(column_title),
                lambda: self.currentItem() and self.editItem(
                    self.currentItem(), column))
        label = account.get_transaction_label(tx_hash) or None
        menu.addAction(
            _("Details"),
            lambda: self._main_window.show_transaction(account, tx, label))
        if is_unconfirmed and tx:
            child_tx = account.cpfp(tx, 0)
            if child_tx:
                menu.addAction(
                    _("Child pays for parent"),
                    lambda: self._main_window.cpfp(account, tx, child_tx))
        if pr_key:
            menu.addAction(read_QIcon("seal"), _("View invoice"),
                           lambda: self._main_window.show_invoice(pr_key))
        if tx_URL:
            menu.addAction(_("View on block explorer"),
                           lambda: webbrowser.open(tx_URL))
        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 6
0
    def _event_create_menu(self, position):
        account_id = self._account_id

        menu = QMenu()

        # What the user clicked on.
        menu_index = self.indexAt(position)
        menu_source_index = get_source_index(menu_index, _ItemModel)

        if menu_source_index.row() != -1:
            menu_line = self._data[menu_source_index.row()]
            menu_column = menu_source_index.column()
            column_title = self._headers[menu_column]
            if menu_column == 0:
                copy_text = get_key_text(menu_line)
            else:
                copy_text = str(menu_source_index.model().data(
                    menu_source_index, Qt.DisplayRole)).strip()
            menu.addAction(
                _("Copy {}").format(column_title),
                lambda: self._main_window.app.clipboard().setText(copy_text))

        # The row selection.
        selected_indexes = self.selectedIndexes()
        if len(selected_indexes):
            # This is an index on the sort/filter model, translate it to the base model.
            selected = []
            for selected_index in selected_indexes:
                base_index = get_source_index(selected_index, _ItemModel)

                row = base_index.row()
                column = base_index.column()
                line = self._data[row]
                selected.append(
                    (row, column, line, selected_index, base_index))

            is_multisig = isinstance(self._account, MultisigAccount)

            rows = set(v[0] for v in selected)
            multi_select = len(rows) > 1

            if not multi_select:
                row, column, line, selected_index, base_index = selected[0]
                key_id = line.keyinstance_id
                menu.addAction(
                    _('Details'),
                    lambda: self._main_window.show_key(self._account, key_id))
                if column == LABEL_COLUMN:
                    menu.addAction(
                        _("Edit {}").format(column_title),
                        lambda: self.edit(selected_index))
                menu.addAction(
                    _("Request payment"), lambda: self._main_window.
                    _receive_view.receive_at_id(key_id))
                if self._account.can_export():
                    menu.addAction(
                        _("Private key"),
                        lambda: self._main_window.show_private_key(
                            self._account, key_id))
                if not is_multisig and not self._account.is_watching_only():
                    menu.addAction(
                        _("Sign/verify message"),
                        lambda: self._main_window.sign_verify_message(
                            self._account, key_id))
                    menu.addAction(
                        _("Encrypt/decrypt message"),
                        lambda: self._main_window.encrypt_message(
                            self._account, key_id))

                explore_menu = menu.addMenu(_("View on block explorer"))

                keyinstance = self._account.get_keyinstance(key_id)
                addr_URL = script_URL = None
                if keyinstance.script_type != ScriptType.NONE:
                    script_template = self._account.get_script_template_for_id(
                        key_id)
                    if isinstance(script_template, Address):
                        addr_URL = web.BE_URL(self._main_window.config, 'addr',
                                              script_template)

                    scripthash = scripthash_hex(
                        script_template.to_script_bytes())
                    script_URL = web.BE_URL(self._main_window.config, 'script',
                                            scripthash)

                addr_action = explore_menu.addAction(
                    _("By address"), partial(webbrowser.open, addr_URL))
                if not addr_URL:
                    addr_action.setEnabled(False)
                script_action = explore_menu.addAction(
                    _("By script"), partial(webbrowser.open, script_URL))
                if not script_URL:
                    script_action.setEnabled(False)

                for script_type, script in self._account.get_possible_scripts_for_id(
                        key_id):
                    scripthash = scripthash_hex(bytes(script))
                    script_URL = web.BE_URL(self._main_window.config, 'script',
                                            scripthash)
                    if script_URL:
                        explore_menu.addAction(
                            _("As {scripttype}").format(
                                scripttype=script_type.name),
                            partial(webbrowser.open, script_URL))

                if isinstance(self._account, StandardAccount):
                    keystore = self._account.get_keystore()
                    if isinstance(keystore, Hardware_KeyStore):

                        def show_key():
                            self._main_window.run_in_thread(
                                keystore.plugin.show_key, self._account,
                                key_id)

                        menu.addAction(
                            _("Show on {}").format(keystore.plugin.device),
                            show_key)

            # freeze = self._main_window.set_frozen_state
            key_ids = [
                line.keyinstance_id
                for (row, column, line, selected_index, base_index) in selected
            ]
            # if any(self._account.is_frozen_address(addr) for addr in addrs):
            #     menu.addAction(_("Unfreeze"), partial(freeze, self._account, addrs, False))
            # if not all(self._account.is_frozen_address(addr) for addr in addrs):
            #     menu.addAction(_("Freeze"), partial(freeze, self._account, addrs, True))

            coins = self._account.get_spendable_coins(
                domain=key_ids, config=self._main_window.config)
            if coins:
                menu.addAction(_("Spend from"),
                               partial(self._main_window.spend_coins, coins))

        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 7
0
    def create_menu(self, position):
        is_multisig = isinstance(self.wallet, Multisig_Wallet)
        can_delete = self.wallet.can_delete_address()
        selected = self.selectedItems()
        multi_select = len(selected) > 1
        addrs = [item.data(0, Qt.UserRole) for item in selected]
        if not addrs:
            return
        addrs = [addr for addr in addrs if isinstance(addr, Address)]

        menu = QMenu()

        if not multi_select:
            item = self.itemAt(position)
            col = self.currentColumn()
            if not item:
                return
            if not addrs:
                item.setExpanded(not item.isExpanded())
                return
            addr = addrs[0]

            column_title = self.headerItem().text(col)
            if col == 0:
                copy_text = addr.to_string()
            else:
                copy_text = item.text(col).strip()
            menu.addAction(
                _("Copy {}").format(column_title),
                lambda: self.parent.app.clipboard().setText(copy_text))
            menu.addAction(_('Details'),
                           lambda: self.parent.show_address(addr))
            if col in self.editable_columns:
                menu.addAction(
                    _("Edit {}").format(column_title),
                    lambda: self.editItem(item, col))
            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.encrypt_message(addr))
            if can_delete:
                menu.addAction(_("Remove from wallet"),
                               lambda: self.parent.remove_address(addr))
            addr_URL = web.BE_URL(self.config, 'addr', addr)
            if addr_URL:
                menu.addAction(_("View on block explorer"),
                               lambda: webbrowser.open(addr_URL))

            keystore = self.wallet.get_keystore()
            if self.wallet.wallet_type == 'standard' and isinstance(
                    keystore, Hardware_KeyStore):

                def show_address():
                    self.parent.run_in_thread(keystore.plugin.show_address,
                                              self.wallet, addr)

                menu.addAction(
                    _("Show on {}").format(keystore.plugin.device),
                    show_address)

        freeze = self.parent.set_frozen_state
        if any(self.wallet.is_frozen_address(addr) for addr in addrs):
            menu.addAction(_("Unfreeze"), partial(freeze, addrs, False))
        if not all(self.wallet.is_frozen_address(addr) for addr in addrs):
            menu.addAction(_("Freeze"), partial(freeze, addrs, True))

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

        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 8
0
    def _event_create_menu(self, position):
        menu = QMenu()

        # What the user clicked on.
        menu_index = self.indexAt(position)
        menu_source_index = get_source_index(menu_index, _ItemModel)

        if menu_source_index.row() != -1:
            menu_line = self._data[menu_source_index.row()]
            menu_column = menu_source_index.column()
            column_title = self._headers[menu_column]
            if menu_column == 0:
                copy_text = menu_line.address.to_string()
            else:
                copy_text = str(menu_source_index.model().data(
                    menu_source_index, Qt.DisplayRole)).strip()
            menu.addAction(
                _("Copy {}").format(column_title),
                lambda: self._parent.app.clipboard().setText(copy_text))

        # The row selection.
        selected_indexes = self.selectedIndexes()
        if len(selected_indexes):
            # This is an index on the sort/filter model, translate it to the base model.
            selected = []
            for selected_index in selected_indexes:
                base_index = get_source_index(selected_index, _ItemModel)

                row = base_index.row()
                column = base_index.column()
                line = self._data[row]
                selected.append(
                    (row, column, line, selected_index, base_index))

            is_multisig = isinstance(self._wallet, Multisig_Wallet)
            can_delete = self._wallet.can_delete_address()

            rows = set(v[0] for v in selected)
            multi_select = len(rows) > 1

            if not multi_select:
                row, column, line, selected_index, base_index = selected[0]
                addr = line.address
                menu.addAction(
                    _('Details'),
                    lambda: self._parent.show_address(self._wallet, addr))
                if column == LABEL_COLUMN:
                    menu.addAction(
                        _("Edit {}").format(column_title),
                        lambda: self.edit(selected_index))
                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(
                            self._wallet, addr))
                if not is_multisig and not self._wallet.is_watching_only():
                    menu.addAction(
                        _("Sign/verify message"),
                        lambda: self._parent.sign_verify_message(
                            self._wallet, addr))
                    menu.addAction(_("Encrypt/decrypt message"),
                                   lambda: self.encrypt_message(addr))
                if can_delete:
                    menu.addAction(_("Remove from wallet"),
                                   lambda: self._parent.remove_address(addr))
                addr_URL = web.BE_URL(self._parent.config, 'addr', addr)
                if addr_URL:
                    menu.addAction(_("View on block explorer"),
                                   lambda: webbrowser.open(addr_URL))

                keystore = self._wallet.get_keystore()
                if self._wallet.wallet_type == 'standard':
                    if isinstance(keystore, Hardware_KeyStore):

                        def show_address():
                            self._parent.run_in_thread(
                                keystore.plugin.show_address, self._wallet,
                                addr)

                        menu.addAction(
                            _("Show on {}").format(keystore.plugin.device),
                            show_address)

            freeze = self._parent.set_frozen_state
            addrs = [
                line.address
                for (row, column, line, selected_index, base_index) in selected
            ]
            if any(self._wallet.is_frozen_address(addr) for addr in addrs):
                menu.addAction(_("Unfreeze"),
                               partial(freeze, self._wallet, addrs, False))
            if not all(self._wallet.is_frozen_address(addr) for addr in addrs):
                menu.addAction(_("Freeze"),
                               partial(freeze, self._wallet, addrs, True))

            coins = self._wallet.get_spendable_coins(
                domain=addrs, config=self._parent.config)
            if coins:
                menu.addAction(_("Spend from"),
                               partial(self._parent.spend_coins, coins))

        menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 9
0
    def _event_create_menu(self, position):
        menu = QMenu()

        # What the user clicked on.
        menu_index = self.indexAt(position)
        menu_source_index = get_source_index(menu_index, _ItemModel)

        if menu_source_index.row() != -1:
            menu_line = self._data[menu_source_index.row()]
            menu_column = menu_source_index.column()
            column_title = self._headers[menu_column]
            if menu_column == 0:
                copy_text = hash_to_hex_str(menu_line.hash)
            else:
                copy_text = str(
                    menu_source_index.model().data(menu_source_index, Qt.DisplayRole)).strip()
            menu.addAction(_("Copy {}").format(column_title),
                lambda: self._main_window.app.clipboard().setText(copy_text))

        # The row selection.
        selected_indexes = self.selectedIndexes()
        if len(selected_indexes):
            # This is an index on the sort/filter model, translate it to the base model.
            selected = []
            for selected_index in selected_indexes:
                base_index = get_source_index(selected_index, _ItemModel)

                row = base_index.row()
                column = base_index.column()
                line = self._data[row]
                selected.append((row, column, line, selected_index, base_index))

            rows = set(v[0] for v in selected)
            multi_select = len(rows) > 1

            if not multi_select:
                row, column, line, selected_index, base_index = selected[0]
                menu.addAction(_('Details'), lambda: self._main_window.show_transaction(
                    self._account, self._account.get_transaction(line.hash)))

                entry = self._account.get_transaction_entry(line.hash)
                if entry.flags & TxFlags.PaysInvoice:
                    menu.addAction(self._invoice_icon, _("View invoice"),
                        partial(self._show_invoice_window, line.hash))
                line_URL = web.BE_URL(self._main_window.config, 'tx', hash_to_hex_str(line.hash))
                if line_URL:
                    menu.addAction(_("View on block explorer"), lambda: webbrowser.open(line_URL))

                menu.addSeparator()
                if column == LABEL_COLUMN:
                    menu.addAction(_("Edit {}").format(column_title),
                        lambda: self.edit(selected_index))

                if entry.flags & TxFlags.STATE_UNCLEARED_MASK != 0:
                    if entry.flags & TxFlags.PaysInvoice:
                        broadcast_action = menu.addAction(self._invoice_icon, _("Pay invoice"),
                            lambda: self._pay_invoice(line.hash))

                        row = self._account.invoices.get_invoice_for_tx_hash(line.hash)
                        if row is None:
                            # The associated invoice has been deleted.
                            broadcast_action.setEnabled(False)
                        elif row.flags & PaymentFlag.UNPAID == 0:
                            # The associated invoice has already been paid.
                            broadcast_action.setEnabled(False)
                        elif has_expired(row.date_expires):
                            # The associated invoice has expired.
                            broadcast_action.setEnabled(False)
                    else:
                        menu.addAction(_("Broadcast"),
                            lambda: self._broadcast_transaction(line.hash))

                    menu.addSeparator()
                    menu.addAction(_("Remove from account"),
                        partial(self._delete_transaction, line.hash))

        menu.exec_(self.viewport().mapToGlobal(position))