URI: 
       tfix #6210: show_onchain/lightning_invoice dialogs - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 211118ae8113a26e2e966a0c108f5091647381b0
   DIR parent 4004b8085f6c9971c30a7981d791adc7ac8ea191
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sat,  6 Jun 2020 11:55:33 +0200
       
       fix #6210: show_onchain/lightning_invoice dialogs
       
       Diffstat:
         M electrum/gui/qt/history_list.py     |       5 +++--
         M electrum/gui/qt/invoice_list.py     |      15 +++++++++------
         M electrum/gui/qt/main_window.py      |     104 ++++++++++++++++++-------------
       
       3 files changed, 73 insertions(+), 51 deletions(-)
       ---
   DIR diff --git a/electrum/gui/qt/history_list.py b/electrum/gui/qt/history_list.py
       t@@ -664,8 +664,9 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
                        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])
       +        for key in invoice_keys:
       +            invoice = self.parent.wallet.get_invoice(key)
       +            menu.addAction(_("View invoice"), lambda: self.parent.show_onchain_invoice(invoice))
                if tx_URL:
                    menu.addAction(_("View on block explorer"), lambda: webopen(tx_URL))
                menu.exec_(self.viewport().mapToGlobal(position))
   DIR diff --git a/electrum/gui/qt/invoice_list.py b/electrum/gui/qt/invoice_list.py
       t@@ -99,16 +99,14 @@ class InvoiceList(MyTreeView):
                self.std_model.clear()
                self.update_headers(self.__class__.headers)
                for idx, item in enumerate(self.parent.wallet.get_invoices()):
       -            if item.type == PR_TYPE_LN:
       +            if item.is_lightning():
                        key = item.rhash
                        icon_name = 'lightning.png'
       -            elif item.type == PR_TYPE_ONCHAIN:
       +            else:
                        key = item.id
                        icon_name = 'bitcoin.png'
                        if item.bip70:
                            icon_name = 'seal.png'
       -            else:
       -                raise Exception('Unsupported type')
                    status = self.parent.wallet.get_invoice_status(item)
                    status_str = item.get_status_str(status)
                    message = item.message
       t@@ -154,10 +152,15 @@ class InvoiceList(MyTreeView):
                if not item or not item_col0:
                    return
                key = item_col0.data(ROLE_REQUEST_ID)
       +        invoice = self.parent.wallet.get_invoice(key)
                menu = QMenu(self)
                self.add_copy_menu(menu, idx)
       -        invoice = self.parent.wallet.get_invoice(key)
       -        menu.addAction(_("Details"), lambda: self.parent.show_invoice(key))
       +        if invoice.is_lightning():
       +            menu.addAction(_("Details"), lambda: self.parent.show_lightning_invoice(invoice))
       +        else:
       +            if len(invoice.outputs) == 1:
       +                menu.addAction(_("Copy Address"), lambda: self.parent.do_copy(invoice.get_address(), title='Bitcoin Address'))
       +            menu.addAction(_("Details"), lambda: self.parent.show_onchain_invoice(invoice))
                status = wallet.get_invoice_status(invoice)
                if status == PR_UNPAID:
                    menu.addAction(_("Pay"), lambda: self.parent.do_pay_invoice(invoice))
   DIR diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
       t@@ -63,7 +63,7 @@ from electrum.util import (format_time, format_satoshis, format_fee_satoshis,
                                   InvalidBitcoinURI, maybe_extract_bolt11_invoice, NotEnoughFunds,
                                   NoDynamicFeeEstimates, MultipleSpendMaxTxOutputs)
        from electrum.invoices import PR_TYPE_ONCHAIN, PR_TYPE_LN, PR_DEFAULT_EXPIRATION_WHEN_CREATING
       -from electrum.invoices import PR_PAID, PR_FAILED, pr_expiration_values, LNInvoice
       +from electrum.invoices import PR_PAID, PR_FAILED, pr_expiration_values, LNInvoice, OnchainInvoice
        from electrum.transaction import (Transaction, PartialTxInput,
                                          PartialTransaction, PartialTxOutput)
        from electrum.address_synchronizer import AddTransactionException
       t@@ -75,6 +75,7 @@ from electrum.exchange_rate import FxThread
        from electrum.simple_config import SimpleConfig
        from electrum.logging import Logger
        from electrum.lnutil import ln_dummy_address
       +from electrum.lnaddr import lndecode, LnDecodeException
        
        from .exception_window import Exception_Hook
        from .amountedit import AmountEdit, BTCAmountEdit, FreezableLineEdit, FeerateEdit
       t@@ -1813,7 +1814,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
        
            def parse_lightning_invoice(self, invoice):
                """Parse ln invoice, and prepare the send tab for it."""
       -        from electrum.lnaddr import lndecode, LnDecodeException
                try:
                    lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
                except Exception as e:
       t@@ -1969,54 +1969,72 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
                self.contact_list.update()
                self.update_completions()
        
       -    def show_invoice(self, key):
       -        invoice = self.wallet.get_invoice(key)
       -        if invoice is None:
       -            self.show_error('Cannot find payment request in wallet.')
       -            return
       -        bip70 = invoice.bip70
       -        if bip70:
       -            pr = paymentrequest.PaymentRequest(bytes.fromhex(bip70))
       +    def show_onchain_invoice(self, invoice: OnchainInvoice):
       +        amount_str = self.format_amount(invoice.amount) + ' ' + self.base_unit()
       +        d = WindowModalDialog(self, _("Onchain Invoice"))
       +        vbox = QVBoxLayout(d)
       +        grid = QGridLayout()
       +        grid.addWidget(QLabel(_("Amount") + ':'), 1, 0)
       +        grid.addWidget(QLabel(amount_str), 1, 1)
       +        if len(invoice.outputs) == 1:
       +            grid.addWidget(QLabel(_("Address") + ':'), 2, 0)
       +            grid.addWidget(QLabel(invoice.get_address()), 2, 1)
       +        else:
       +            outputs_str = '\n'.join(map(lambda x: x.address + ' : ' + self.format_amount(x.value)+ self.base_unit(), invoice.outputs))
       +            grid.addWidget(QLabel(_("Outputs") + ':'), 2, 0)
       +            grid.addWidget(QLabel(outputs_str), 2, 1)
       +        grid.addWidget(QLabel(_("Description") + ':'), 3, 0)
       +        grid.addWidget(QLabel(invoice.message), 3, 1)
       +        if invoice.exp:
       +            grid.addWidget(QLabel(_("Expires") + ':'), 4, 0)
       +            grid.addWidget(QLabel(format_time(invoice.exp + invoice.time)), 4, 1)
       +        if invoice.bip70:
       +            pr = paymentrequest.PaymentRequest(bytes.fromhex(invoice.bip70))
                    pr.verify(self.contacts)
       -            self.show_bip70_details(pr)
       +            grid.addWidget(QLabel(_("Requestor") + ':'), 5, 0)
       +            grid.addWidget(QLabel(pr.get_requestor()), 5, 1)
       +            grid.addWidget(QLabel(_("Signature") + ':'), 6, 0)
       +            grid.addWidget(QLabel(pr.get_verify_status()), 6, 1)
       +            def do_export():
       +                key = pr.get_id()
       +                name = str(key) + '.bip70'
       +                fn = self.getSaveFileName(_("Save invoice to file"), name, filter="*.bip70")
       +                if not fn:
       +                    return
       +                with open(fn, 'wb') as f:
       +                    data = f.write(pr.raw)
       +                self.show_message(_('BIP70 invoice saved as' + ' ' + fn))
       +            exportButton = EnterButton(_('Export'), do_export)
       +            buttons = Buttons(exportButton, CloseButton(d))
       +        else:
       +            buttons = Buttons(CloseButton(d))
       +        vbox.addLayout(grid)
       +        vbox.addLayout(buttons)
       +        d.exec_()
        
       -    def show_bip70_details(self, pr: 'paymentrequest.PaymentRequest'):
       -        key = pr.get_id()
       -        d = WindowModalDialog(self, _("BIP70 Invoice"))
       +    def show_lightning_invoice(self, invoice: LNInvoice):
       +        lnaddr = lndecode(invoice.invoice, expected_hrp=constants.net.SEGWIT_HRP)
       +        d = WindowModalDialog(self, _("Lightning Invoice"))
                vbox = QVBoxLayout(d)
                grid = QGridLayout()
       -        grid.addWidget(QLabel(_("Requestor") + ':'), 0, 0)
       -        grid.addWidget(QLabel(pr.get_requestor()), 0, 1)
       +        grid.addWidget(QLabel(_("Node ID") + ':'), 0, 0)
       +        grid.addWidget(QLabel(lnaddr.pubkey.serialize().hex()), 0, 1)
                grid.addWidget(QLabel(_("Amount") + ':'), 1, 0)
       -        outputs_str = '\n'.join(map(lambda x: self.format_amount(x.value)+ self.base_unit() + ' @ ' + x.address, pr.get_outputs()))
       -        grid.addWidget(QLabel(outputs_str), 1, 1)
       -        expires = pr.get_expiration_date()
       -        grid.addWidget(QLabel(_("Memo") + ':'), 2, 0)
       -        grid.addWidget(QLabel(pr.get_memo()), 2, 1)
       -        grid.addWidget(QLabel(_("Signature") + ':'), 3, 0)
       -        grid.addWidget(QLabel(pr.get_verify_status()), 3, 1)
       -        if expires:
       +        amount_str = self.format_amount(invoice.amount) + ' ' + self.base_unit()
       +        grid.addWidget(QLabel(amount_str), 1, 1)
       +        grid.addWidget(QLabel(_("Description") + ':'), 2, 0)
       +        grid.addWidget(QLabel(invoice.message), 2, 1)
       +        grid.addWidget(QLabel(_("Hash") + ':'), 3, 0)
       +        grid.addWidget(QLabel(lnaddr.paymenthash.hex()), 3, 1)
       +        if invoice.exp:
                    grid.addWidget(QLabel(_("Expires") + ':'), 4, 0)
       -            grid.addWidget(QLabel(format_time(expires)), 4, 1)
       +            grid.addWidget(QLabel(format_time(invoice.time + invoice.exp)), 4, 1)
                vbox.addLayout(grid)
       -        def do_export():
       -            name = str(key) + '.bip70'
       -            fn = self.getSaveFileName(_("Save invoice to file"), name, filter="*.bip70")
       -            if not fn:
       -                return
       -            with open(fn, 'wb') as f:
       -                data = f.write(pr.raw)
       -            self.show_message(_('Invoice saved as' + ' ' + fn))
       -        exportButton = EnterButton(_('Save'), do_export)
       -        # note: "delete" disabled as invoice is saved with a different key in wallet.invoices that we do not have here
       -        # def do_delete():
       -        #     if self.question(_('Delete invoice?')):
       -        #         self.wallet.delete_invoice(key)
       -        #         self.history_list.update()
       -        #         self.invoice_list.update()
       -        #         d.close()
       -        # deleteButton = EnterButton(_('Delete'), do_delete)
       -        vbox.addLayout(Buttons(exportButton, CloseButton(d)))
       +        invoice_e = ShowQRTextEdit()
       +        invoice_e.addCopyButton(self.app)
       +        invoice_e.setText(invoice.invoice)
       +        vbox.addWidget(invoice_e)
       +        vbox.addLayout(Buttons(CloseButton(d),))
                d.exec_()
        
            def create_console_tab(self):