def create_menu(self, position): idx = self.indexAt(position) item = self.model().itemFromIndex(idx) item_col0 = self.model().itemFromIndex( idx.sibling(idx.row(), self.Columns.DATE)) if not item or not item_col0: return key = item_col0.data(Qt.UserRole) column = idx.column() column_title = self.model().horizontalHeaderItem(column).text() column_data = item.text() status = self.parent.invoices.get_status(key) menu = QMenu(self) if column_data: if column == self.Columns.AMOUNT: column_data = column_data.strip() menu.addAction( _("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data)) menu.addAction(_("Details"), lambda: self.parent.show_invoice(key)) if status == PR_UNPAID: menu.addAction(_("Pay Now"), lambda: self.parent.do_pay_invoice(key)) menu.addAction(_("Delete"), lambda: self.parent.delete_invoice(key)) menu.exec_(self.viewport().mapToGlobal(position))
def create_menu(self, position): idx = self.indexAt(position) item = self.model().itemFromIndex(idx) # TODO use siblingAtColumn when min Qt version is >=5.11 item_addr = self.model().itemFromIndex( idx.sibling(idx.row(), self.Columns.ADDRESS)) if not item_addr: return addr = item_addr.text() req = self.wallet.receive_requests.get(addr) if req is None: self.update() return column = idx.column() column_title = self.model().horizontalHeaderItem(column).text() column_data = item.text() menu = QMenu(self) if column != self.Columns.SIGNATURE: if column == self.Columns.AMOUNT: column_data = column_data.strip() menu.addAction( _("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data)) menu.addAction( _("Copy URI"), lambda: self.parent.view_and_paste( 'URI', '', self.parent.get_request_URI(addr))) menu.addAction(_("Save as BIP70 file"), lambda: self.parent.export_payment_request(addr)) menu.addAction(_("Delete"), lambda: self.parent.delete_payment_request(addr)) run_hook('receive_list_menu', menu, addr) menu.exec_(self.viewport().mapToGlobal(position))
def create_password_layout(self, wallet, is_encrypted, OK_button): if not is_encrypted: msg = _('Your wallet file is NOT encrypted.') else: msg = _('Your wallet file is encrypted.') msg += '\n' + _('Note: If you enable this setting, you will need your hardware device to open your wallet.') msg += '\n' + _('Use this dialog to toggle encryption.') self.playout = PasswordLayoutForHW(msg)
def __init__(self, text="", allow_multi=False): ButtonsTextEdit.__init__(self, text) self.allow_multi = allow_multi self.setReadOnly(0) self.addButton("file.png", self.file_input, _("Read file")) icon = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" self.addButton(icon, self.qr_input, _("Read QR code")) run_hook('scan_text_edit', self)
def add_cosigner_dialog(self, run_next, index, is_valid): title = _("Add Cosigner") + " %d" % index message = ' '.join([ _('Please enter the master public key (xpub) of your cosigner.'), _('Enter their master private key (xprv) if you want to be able to sign for them.' ) ]) return self.text_input(title, message, is_valid)
def get_tooltip(self, pos, fee_rate): mempool = self.config.use_mempool_fees() target, estimate = self.config.get_fee_text(pos, self.dyn, mempool, fee_rate) if self.dyn: return _('Target') + ': ' + target + '\n' + _( 'Current rate') + ': ' + estimate else: return _('Fixed rate') + ': ' + target + '\n' + _( 'Estimate') + ': ' + estimate
def show_xpub_dialog(self, xpub, run_next): msg = ' '.join([ _("Here is your master public key."), _("Please share it with your cosigners.") ]) vbox = QVBoxLayout() layout = SeedLayout(xpub, title=msg, icon=False, for_seed_words=False) vbox.addLayout(layout.layout()) self.exec_layout(vbox, _('Master Public Key')) return None
def export(self): name = 'signed_%s.txn' % ( self.tx.txid()[0:8]) if self.tx.is_complete() else 'unsigned.txn' fileName = self.main_window.getSaveFileName( _("Select where to save your signed transaction"), name, "*.txn") if fileName: with open(fileName, "w+") as f: f.write(json.dumps(self.tx.as_dict(), indent=4) + '\n') self.show_message(_("Transaction exported successfully")) self.saved = True
def create_toolbar_buttons(self): self.period_combo = QComboBox() self.start_button = QPushButton('-') self.start_button.pressed.connect(self.select_start_date) self.start_button.setEnabled(False) self.end_button = QPushButton('-') self.end_button.pressed.connect(self.select_end_date) self.end_button.setEnabled(False) self.period_combo.addItems([_('All'), _('Custom')]) self.period_combo.activated.connect(self.on_combo)
def restore_seed_dialog(self, run_next, test): options = [] if self.opt_ext: options.append('ext') if self.opt_bip39: options.append('bip39') title = _('Enter Seed') message = _( 'Please enter your seed phrase in order to restore your wallet.') return self.seed_input(title, message, test, options)
def confirm_seed_dialog(self, run_next, test): self.app.clipboard().clear() title = _('Confirm Seed') message = ' '.join([ _('Your seed is important!'), _('If you lose your seed, your money will be permanently lost.'), _('To make sure that you have properly saved your seed, please retype it here.' ) ]) seed, is_bip39, is_ext = self.seed_input(title, message, test, None) return seed
def show_qr(self): text = bfh(str(self.tx)) text = base_encode(text, base=43) try: self.main_window.show_qrcode(text, 'Transaction', parent=self) except qrcode.exceptions.DataOverflowError: self.show_error( _('Failed to display QR code.') + '\n' + _('Transaction is too large in size.')) except Exception as e: self.show_error(_('Failed to display QR code.') + '\n' + str(e))
def closeEvent(self, event): if (self.prompt_if_unsaved and not self.saved and not self.question( _('This transaction is not saved. Close anyway?'), title=_("Warning"))): event.ignore() else: event.accept() try: dialogs.remove(self) except ValueError: pass # was not in list already
def send_report(self): try: proxy = self.main_window.network.proxy response = BaseCrashReporter.send_report(self, self.main_window.network.asyncio_loop, proxy) except BaseException as e: self.logger.exception('There was a problem with the automatic reporting') self.main_window.show_critical(_('There was a problem with the automatic reporting:') + '\n' + str(e) + '\n' + _("Please report this issue manually.")) return QMessageBox.about(self, _("Crash report"), response) self.close()
def plot_history_dialog(self): if plot_history is None: self.parent.show_message( _("Can't plot history.") + '\n' + _("Perhaps some dependencies are missing...") + " (matplotlib?)") return try: plt = plot_history(list(self.hm.transactions.values())) plt.show() except NothingToPlotException as e: self.parent.show_message(str(e))
def add_io(self, vbox): vbox.addWidget(QLabel(_("Inputs") + ' (%d)' % len(self.tx.inputs()))) ext = QTextCharFormat() rec = QTextCharFormat() rec.setBackground(QBrush(ColorScheme.GREEN.as_color(background=True))) rec.setToolTip(_("Wallet receive address")) chg = QTextCharFormat() chg.setBackground(QBrush(ColorScheme.YELLOW.as_color(background=True))) chg.setToolTip(_("Wallet change address")) def text_format(addr): if self.wallet.is_mine(addr): return chg if self.wallet.is_change(addr) else rec return ext def format_amount(amt): return self.main_window.format_amount(amt, whitespaces=True) i_text = QTextEditWithDefaultSize() i_text.setFont(QFont(MONOSPACE_FONT)) i_text.setReadOnly(True) cursor = i_text.textCursor() for x in self.tx.inputs(): if x['type'] == 'coinbase': cursor.insertText('coinbase') else: prevout_hash = x.get('prevout_hash') prevout_n = x.get('prevout_n') cursor.insertText(prevout_hash + ":%-4d " % prevout_n, ext) addr = self.wallet.get_txin_address(x) if addr is None: addr = '' cursor.insertText(addr, text_format(addr)) if x.get('value'): cursor.insertText(format_amount(x['value']), ext) cursor.insertBlock() vbox.addWidget(i_text) vbox.addWidget(QLabel(_("Outputs") + ' (%d)' % len(self.tx.outputs()))) o_text = QTextEditWithDefaultSize() o_text.setFont(QFont(MONOSPACE_FONT)) o_text.setReadOnly(True) cursor = o_text.textCursor() for o in self.tx.get_outputs_for_UI(): addr, v = o.address, o.value cursor.insertText(addr, text_format(addr)) if v is not None: cursor.insertText('\t', ext) cursor.insertText(format_amount(v), ext) cursor.insertBlock() vbox.addWidget(o_text)
def create_menu(self, position): menu = QMenu() idx = self.indexAt(position) column = idx.column() or self.Columns.NAME selected_keys = [] for s_idx in self.selected_in_column(self.Columns.NAME): sel_key = self.model().itemFromIndex(s_idx).data(Qt.UserRole) selected_keys.append(sel_key) if not selected_keys or not idx.isValid(): menu.addAction(_("New contact"), lambda: self.parent.new_contact_dialog()) menu.addAction(_("Import file"), lambda: self.import_contacts()) menu.addAction(_("Export file"), lambda: self.export_contacts()) else: column_title = self.model().horizontalHeaderItem(column).text() column_data = '\n'.join(self.model().itemFromIndex(s_idx).text() for s_idx in self.selected_in_column(column)) menu.addAction(_("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data)) if column in self.editable_columns: item = self.model().itemFromIndex(idx) if item.isEditable(): # would not be editable if openalias persistent = QPersistentModelIndex(idx) menu.addAction(_("Edit {}").format(column_title), lambda p=persistent: self.edit(QModelIndex(p))) menu.addAction(_("Pay to"), lambda: self.parent.payto_contacts(selected_keys)) menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(selected_keys)) URLs = [block_explorer_URL(self.config, 'addr', key) for key in filter(is_address, selected_keys)] if URLs: menu.addAction(_("View on block explorer"), lambda: [webbrowser.open(u) for u in URLs]) run_hook('create_contact_menu', menu, selected_keys) menu.exec_(self.viewport().mapToGlobal(position))
def headerData(self, section: int, orientation: Qt.Orientation, role: Qt.ItemDataRole): assert orientation == Qt.Horizontal if role != Qt.DisplayRole: return None fx = self.parent.fx fiat_title = 'n/a fiat value' fiat_acq_title = 'n/a fiat acquisition price' fiat_cg_title = 'n/a fiat capital gains' if fx and fx.show_history(): fiat_title = '%s ' % fx.ccy + _('Value') fiat_acq_title = '%s ' % fx.ccy + _('Acquisition price') fiat_cg_title = '%s ' % fx.ccy + _('Capital Gains') return { HistoryColumns.STATUS_ICON: '', HistoryColumns.STATUS_TEXT: _('Date'), HistoryColumns.BLANK: _(''), HistoryColumns.DESCRIPTION: _('Description'), HistoryColumns.COIN_VALUE: _('Amount'), HistoryColumns.RUNNING_COIN_BALANCE: _('Balance'), HistoryColumns.FIAT_VALUE: fiat_title, HistoryColumns.FIAT_ACQ_PRICE: fiat_acq_title, HistoryColumns.FIAT_CAP_GAINS: fiat_cg_title, HistoryColumns.TXID: 'TXID', }[section]
def export_meta_gui(electrum_window, title, exporter): filter_ = "JSON (*.json);;All files (*)" filename = electrum_window.getSaveFileName( _("Select file to save your {}").format(title), 'electrum_{}.json'.format(title), filter_) if not filename: return try: exporter(filename) except FileExportFailed as e: electrum_window.show_critical(str(e)) else: electrum_window.show_message( _("Your {0} were exported to '{1}'").format(title, str(filename)))
def import_meta_gui(electrum_window, title, importer, on_success): filter_ = "JSON (*.json);;All files (*)" filename = electrum_window.getOpenFileName( _("Open {} file").format(title), filter_) if not filename: return try: importer(filename) except FileImportFailed as e: electrum_window.show_critical(str(e)) else: electrum_window.show_message( _("Your {} were successfully imported").format(title)) on_success()
def build_tray_menu(self): # Avoid immediate GC of old menu when window closed via its action if self.tray.contextMenu() is None: m = QMenu() self.tray.setContextMenu(m) else: m = self.tray.contextMenu() m.clear() for window in self.windows: submenu = m.addMenu(window.wallet.basename()) submenu.addAction(_("Show/Hide"), window.show_or_hide) submenu.addAction(_("Close"), window.close) m.addAction(_("Dark/Light"), self.toggle_tray_icon) m.addSeparator() m.addAction(_("Exit Lynx"), self.close)
def remove_local_tx(self, delete_tx): to_delete = {delete_tx} to_delete |= self.wallet.get_depending_transactions(delete_tx) question = _("Are you sure you want to remove this transaction?") if len(to_delete) > 1: question = (_( "Are you sure you want to remove this transaction and {} child transactions?" ).format(len(to_delete) - 1)) if not self.parent.question(msg=question, title=_("Please confirm")): return for tx in to_delete: self.wallet.remove_transaction(tx) self.wallet.storage.write() # need to update at least: history_list, utxo_list, address_list self.parent.need_update.set()
def __init__(self, parent=None, msg=None): msg = msg or _('Please enter your password') WindowModalDialog.__init__(self, parent, _("Enter Password")) self.pw = pw = QLineEdit() pw.setEchoMode(2) vbox = QVBoxLayout() vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Password')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) vbox.addLayout(Buttons(CancelButton(self), OkButton(self))) self.setLayout(vbox) run_hook('password_dialog', pw, grid, 1)
def create_password_layout(self, wallet, is_encrypted, OK_button): if not wallet.has_password(): msg = _('Your wallet is not protected.') msg += ' ' + _('Use this dialog to add a password to your wallet.') else: if not is_encrypted: msg = _('Your AUDAX coins are password protected. However, your wallet file is not encrypted.') else: msg = _('Your wallet is password protected and encrypted.') msg += ' ' + _('Use this dialog to change your password.') self.playout = PasswordLayout(msg=msg, kind=PW_CHANGE, OK_button=OK_button, wallet=wallet, force_disable_encrypt_cb=not wallet.can_have_keystore_encryption())
def create_menu(self, position): item = self.currentItem() if not item: return is_server = not bool(item.data(0, Qt.UserRole)) menu = QMenu() if is_server: server = item.data(1, Qt.UserRole) menu.addAction(_("Use as server"), lambda: self.parent.follow_server(server)) else: chain_id = item.data(1, Qt.UserRole) menu.addAction(_("Follow this branch"), lambda: self.parent.follow_branch(chain_id)) menu.exec_(self.viewport().mapToGlobal(position))
def insert_utxo(self, idx, x): address = x['address'] height = x.get('height') name = x.get('prevout_hash') + ":%d" % x.get('prevout_n') name_short = x.get( 'prevout_hash')[:16] + '...' + ":%d" % x.get('prevout_n') self.utxo_dict[name] = x label = self.wallet.get_label(x.get('prevout_hash')) amount = self.parent.format_amount(x['value'], whitespaces=True) labels = [name_short, address, label, amount, '%d' % height] utxo_item = [QStandardItem(x) for x in labels] self.set_editability(utxo_item) for i in range(5): utxo_item[i].setFont(QFont(MONOSPACE_FONT)) utxo_item[self.Columns.AMOUNT].setTextAlignment(Qt.AlignRight) utxo_item[self.Columns.HEIGHT].setTextAlignment(Qt.AlignRight) utxo_item[self.Columns.ADDRESS].setData(name, Qt.UserRole) if self.wallet.is_frozen_address(address): utxo_item[self.Columns.ADDRESS].setBackground( ColorScheme.BLUE.as_color(True)) utxo_item[self.Columns.ADDRESS].setToolTip(_('Address is frozen')) if self.wallet.is_frozen_coin(x): utxo_item[self.Columns.OUTPOINT].setBackground( ColorScheme.BLUE.as_color(True)) utxo_item[self.Columns.OUTPOINT].setToolTip( f"{name}\n{_('Coin is frozen')}") else: utxo_item[self.Columns.OUTPOINT].setToolTip(name) self.model().insertRow(idx, utxo_item)
def update(self): inv_list = self.parent.invoices.unpaid_invoices() self.model().clear() self.update_headers(self.__class__.headers) self.header().setSectionResizeMode(self.Columns.REQUESTOR, QHeaderView.Interactive) for idx, pr in enumerate(inv_list): key = pr.get_id() status = self.parent.invoices.get_status(key) if status is None: continue requestor = pr.get_requestor() exp = pr.get_expiration_date() date_str = format_time(exp) if exp else _('Never') labels = [ date_str, requestor, pr.memo, self.parent.format_amount(pr.get_amount(), whitespaces=True), pr_tooltips.get(status, '') ] items = [QStandardItem(e) for e in labels] self.set_editability(items) items[self.Columns.STATUS].setIcon(read_QIcon( pr_icons.get(status))) items[self.Columns.DATE].setData(key, role=Qt.UserRole) items[self.Columns.REQUESTOR].setFont(QFont(MONOSPACE_FONT)) items[self.Columns.AMOUNT].setFont(QFont(MONOSPACE_FONT)) self.model().insertRow(idx, items) self.selectionModel().select(self.model().index(0, 0), QItemSelectionModel.SelectCurrent) if self.parent.isVisible(): b = len(inv_list) > 0 self.setVisible(b) self.parent.invoices_label.setVisible(b) self.filter()
def __init__(self, text=None): ButtonsTextEdit.__init__(self, text) self.setReadOnly(1) icon = "qrcode.png" self.addButton(icon, self.qr_show, _("Show as QR code")) run_hook('show_text_edit', self)
def func_wrapper(*args, **kwargs): run_next = kwargs['run_next'] wizard = args[0] # type: InstallWizard wizard.back_button.setText( _('Back') if wizard.can_go_back() else _('Cancel')) try: out = func(*args, **kwargs) if type(out) is not tuple: out = (out, ) run_next(*out) except GoBack: if wizard.can_go_back(): wizard.go_back() return else: wizard.close() raise
def show_seed_dialog(self, run_next, seed_text): title = _("Your wallet generation seed is:") slayout = SeedLayout(seed=seed_text, title=title, msg=True, options=['ext']) self.exec_layout(slayout) return slayout.is_ext