def get_tooltip(self, pos, fee_rate): from electrum_reden.util import fee_levels rate_str = self.window.format_fee_rate(fee_rate) if fee_rate else _( 'unknown') if self.dyn: tooltip = fee_levels[pos] + '\n' + rate_str else: tooltip = 'Fixed rate: ' + rate_str if self.config.has_fee_estimates(): i = self.config.reverse_dynfee(fee_rate) tooltip += '\n' + (_('Low fee') if i < 0 else 'Within %d blocks' % i) return tooltip
def __init__(self, parent=None): super(NetworkAddressWidget, self).__init__(parent) self.ip_edit = QLineEdit() self.port_edit = QSpinBox() self.port_edit.setRange(0, 99999) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.addWidget(QLabel(_('IP:'))) hbox.addWidget(self.ip_edit, stretch=1) hbox.addWidget(QLabel(_('Port:'))) hbox.addWidget(self.port_edit, stretch=1) self.setLayout(hbox)
def callback_PassphraseRequest(self, req): if self.creating_wallet: msg = _("Enter a passphrase to generate this wallet. Each time " "you use this wallet your %s will prompt you for the " "passphrase. If you forget the passphrase you cannot " "access the Reden coins in the wallet.") % self.device else: msg = _("Enter the passphrase to unlock this wallet:") passphrase = self.handler.get_passphrase(msg, self.creating_wallet) if passphrase is None: return self.proto.Cancel() passphrase = bip39_normalize_passphrase(passphrase) return self.proto.PassphraseAck(passphrase=passphrase)
def __init__(self, main_widget, parent=None): super(ProposalEditor, self).__init__(parent) self.main_widget = main_widget self.name_edit = QLineEdit() self.url_edit = QLineEdit() self.start_block_edit = QLineEdit() self.end_block_edit = QLineEdit() self.amount_edit = QLineEdit() self.address_edit = QLineEdit() self.txid_edit = QLineEdit() for i in [self.name_edit, self.url_edit, self.start_block_edit, self.end_block_edit, self.amount_edit, self.address_edit, self.txid_edit]: i.setReadOnly(True) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.main_widget.proxy_model) self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self.mapper.addMapping(self.name_edit, ProposalsModel.NAME) self.mapper.addMapping(self.url_edit, ProposalsModel.URL) self.mapper.addMapping(self.start_block_edit, ProposalsModel.START_BLOCK) self.mapper.addMapping(self.end_block_edit, ProposalsModel.END_BLOCK) self.mapper.addMapping(self.amount_edit, ProposalsModel.AMOUNT) self.mapper.addMapping(self.address_edit, ProposalsModel.ADDRESS) self.mapper.addMapping(self.txid_edit, ProposalsModel.TXID) block_hbox = QHBoxLayout() block_hbox.addWidget(self.start_block_edit) block_hbox.addWidget(QLabel(' - ')) block_hbox.addWidget(self.end_block_edit) self.vote_combo = QComboBox() self.vote_combo.addItem(_('Yes')) self.vote_combo.addItem(_('No')) self.vote_button = QPushButton(_('Vote')) self.vote_button.clicked.connect(self.cast_vote) vote_hbox = util.Buttons(self.vote_combo, self.vote_button) form = QFormLayout() form.addRow(_('Name:'), self.name_edit) form.addRow(_('URL:'), self.url_edit) form.addRow(_('Blocks:'), block_hbox) form.addRow(_('Monthly Payment:'), self.amount_edit) form.addRow(_('Payment Address:'), self.address_edit) form.addRow(_('Fee TxID:'), self.txid_edit) form.addRow(_('Vote:'), vote_hbox) self.setLayout(form)
def populate_modes(self): self.modes.blockSignals(True) self.modes.clear() self.modes.addItem( _("Summary Text PIN (requires dongle replugging)" ) if self.txdata['confirmationType'] == 1 else _("Summary Text PIN is Disabled")) if self.txdata['confirmationType'] > 1: self.modes.addItem(_("Security Card Challenge")) if not self.cfg['pair']: self.modes.addItem(_("Mobile - Not paired")) else: self.modes.addItem(_("Mobile - %s") % self.cfg['pair'][1]) self.modes.blockSignals(False)
def update(self, proposals, main_window): item = self.currentItem() current_proposal = item.data(ProposalsModel.TXID, Qt.UserRole).toString() if item else None self.model.set_proposals(proposals) self.clear() row_count = self.model.rowCount() if row_count < 1: return for r in range(row_count): get_data = lambda col, row=r: self.model.data(self.model.index(row, col)) name = _(str(get_data(ProposalsModel.NAME).toString())) url = _(str(get_data(ProposalsModel.URL).toString())) yes_count = str(get_data(ProposalsModel.YES_COUNT).toString()) no_count = str(get_data(ProposalsModel.NO_COUNT).toString()) start_block = str(get_data(ProposalsModel.START_BLOCK).toString()) end_block = str(get_data(ProposalsModel.END_BLOCK).toString()) amount = str(get_data(ProposalsModel.AMOUNT).toString()) address = str(get_data(ProposalsModel.ADDRESS).toString()) txid = str(get_data(ProposalsModel.TXID).toString()) display_txid = '%s...%s' % (txid[0:8], txid[-8:]) item = QTreeWidgetItem( [name, url, yes_count, no_count, start_block, end_block, amount, address, display_txid] ) item.setFont(ProposalsModel.START_BLOCK, QFont(util.MONOSPACE_FONT)) item.setFont(ProposalsModel.END_BLOCK, QFont(util.MONOSPACE_FONT)) item.setFont(ProposalsModel.ADDRESS, QFont(util.MONOSPACE_FONT)) item.setFont(ProposalsModel.TXID, QFont(util.MONOSPACE_FONT)) if name: item.setData(ProposalsModel.NAME, Qt.UserRole, name) if txid: item.setData(ProposalsModel.TXID, Qt.UserRole, txid) is_my_proposal = False if main_window.masternode_manager.get_proposal(name) is not None: is_my_proposal = True if is_my_proposal: item.setBackground(ProposalsModel.NAME, QBrush(QColor(MY_PROPOSAL_COLOR))) item.setToolTip(ProposalsModel.NAME, _('You created this proposal.')) is_my_address = main_window.wallet.is_mine(address) if is_my_address: item.setBackground(ProposalsModel.ADDRESS, QBrush(QColor(MY_ADDRESS_COLOR))) item.setToolTip(ProposalsModel.ADDRESS, _('You own this address.')) self.addTopLevelItem(item) if current_proposal == name: self.setCurrentItem(item)
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: index = item.data(1, Qt.UserRole) menu.addAction(_("Follow this branch"), lambda: self.parent.follow_branch(index)) menu.exec_(self.viewport().mapToGlobal(position))
def create_menu(self, position): selected = [x.data(0, Qt.UserRole) for x in self.selectedItems()] if not selected: return menu = QMenu() coins = filter(lambda x: self.get_name(x) in selected, self.utxos) menu.addAction(_("Spend"), lambda: self.parent.spend_coins(coins)) if len(selected) == 1: txid = selected[0].split(':')[0] tx = self.wallet.transactions.get(txid) menu.addAction(_("Details"), lambda: self.parent.show_transaction(tx)) menu.exec_(self.viewport().mapToGlobal(position))
def show_network_dialog(self, parent): if not self.daemon.network: parent.show_warning(_( 'You are using Electrum-REDEN in offline mode; restart Electrum-REDEN if you want to get connected' ), title=_('Offline')) return if self.nd: self.nd.on_update() self.nd.show() self.nd.raise_() return self.nd = NetworkDialog(self.daemon.network, self.config, self.network_updated_signal_obj) self.nd.show()
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 Electrum-REDEN"), self.close)
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 __init__(self, win): QWidget.__init__(self) self.win = win self.setWindowTitle('Electrum-REDEN - ' + _('Payment Request')) self.setMinimumSize(800, 250) self.address = '' self.label = '' self.amount = 0 self.setFocusPolicy(Qt.NoFocus) main_box = QHBoxLayout() self.qrw = QRCodeWidget() main_box.addWidget(self.qrw, 1) vbox = QVBoxLayout() main_box.addLayout(vbox) self.address_label = QLabel("") #self.address_label.setFont(QFont(MONOSPACE_FONT)) vbox.addWidget(self.address_label) self.label_label = QLabel("") vbox.addWidget(self.label_label) self.amount_label = QLabel("") vbox.addWidget(self.amount_label) vbox.addStretch(1) self.setLayout(main_box)
def seed_device_dialog(self): msg = _("Choose how to initialize your Digital Bitbox:\n") choices = [ (_("Generate a new random wallet")), (_("Load a wallet from the micro SD card")) ] try: reply = self.handler.win.query_choice(msg, choices) except Exception: return # Back button pushed if reply == 0: self.dbb_generate_wallet() else: if not self.dbb_load_backup(show_msg=False): return self.isInitialized = True
def __init__(self, dialog, model, parent=None): super(ProposalsWidget, self).__init__(parent) self.dialog = dialog self.manager = dialog.manager self.model = model self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(self.model) self.view = QTableView() self.view.setModel(self.proxy_model) self.view.setSortingEnabled(True) self.view.setSelectionMode(QAbstractItemView.SingleSelection) self.view.setSelectionBehavior(QAbstractItemView.SelectRows) header = self.view.horizontalHeader() header.setHighlightSections(False) header.setResizeMode(self.model.NAME, QHeaderView.ResizeToContents) header.setResizeMode(self.model.URL, QHeaderView.Stretch) header.setResizeMode(self.model.ADDRESS, QHeaderView.ResizeToContents) header.setResizeMode(self.model.TXID, QHeaderView.ResizeToContents) self.view.verticalHeader().setVisible(False) self.view.sortByColumn(self.model.NAME, Qt.AscendingOrder) self.view.selectionModel().selectionChanged.connect(self.on_view_selection_changed) self.editor = ProposalEditor(self) vbox = QVBoxLayout() vbox.setContentsMargins(0, 0, 0, 0) vbox.addWidget(QLabel(_('Proposals:'))) vbox.addWidget(self.view) vbox.addWidget(self.editor) self.setLayout(vbox)
def password_dialog(self, pw, grid, pos): vkb_button = QPushButton(_("+")) vkb_button.setFixedWidth(20) vkb_button.clicked.connect(lambda: self.toggle_vkb(grid, pw)) grid.addWidget(vkb_button, pos, 2) self.kb_pos = 2 self.vkb = None
def submit_waiting_proposals(self): """Submit the proposals that are ready to the network.""" # Submit the proposals that are ready. results = [('', '', False)] * len(self.unsubmitted_proposals) def submit_thread(): for i, (proposal_name, txid) in enumerate(self.unsubmitted_proposals): errmsg, success = self.parent.masternode_manager.submit_proposal(proposal_name, save=False) results[i] = (proposal_name, errmsg, success) if success: print_error('Sucessfully submitted proposal "%s"' % proposal_name) else: print_error('Failed to submit proposal "%s": %s' % (proposal_name, errmsg)) return results def on_done(): msg = '' for proposal_name, errmsg, success in results: if success: msg += '<b>' + proposal_name + '</b>' + _(': submitted successfully.') else: msg += '<b>' + proposal_name + '</b>' + _(': failed! "%s"' % errmsg) msg += '\n' QMessageBox.information(self, _('Results'), msg) self.update_unsubmitted_proposals() self.parent.masternode_manager.save() self.waiting_dialog = util.WaitingDialog(self, _('Submitting Proposals...'), submit_thread, on_complete=on_done) self.waiting_dialog.start()
def receive_menu(self, menu, addrs, wallet): if type(wallet) is not Standard_Wallet: return keystore = wallet.get_keystore() if type(keystore) is not self.keystore_class: return if not self.is_mobile_paired(): return if not keystore.is_p2pkh(): return if len(addrs) == 1: def show_address(): change, index = wallet.get_address_index(addrs[0]) keypath = '%s/%d/%d' % (keystore.derivation, change, index) xpub = self.get_client(keystore)._get_xpub(keypath) verify_request_payload = { "type": 'p2pkh', "echo": xpub['echo'], } self.comserver_post_notification(verify_request_payload) menu.addAction(_("Show on %s") % self.device, show_address)
def send_announce(self, alias): """Send an announce for a masternode.""" def send_thread(): return self.manager.send_announce(alias) def on_send_successful(result): errmsg, was_announced = result if was_announced: self.print_msg('Successfully broadcasted MasternodeAnnounce for "%s"' % alias) QMessageBox.information(self, _('Success'), _('Masternode activated successfully.')) else: self.print_error('Failed to broadcast MasternodeAnnounce: %s' % errmsg) QMessageBox.critical(self, _('Error Sending'), _(errmsg)) self.masternodes_widget.refresh_items() self.masternodes_widget.select_masternode(alias) def on_send_error(err): self.print_error('Error sending Masternode Announce message:') # Print traceback information to error log. self.print_error(''.join(traceback.format_tb(err[2]))) self.print_error(''.join(traceback.format_exception_only(err[0], err[1]))) self.masternodes_widget.refresh_items() self.masternodes_widget.select_masternode(alias) self.print_msg('Sending Masternode Announce message...') util.WaitingDialog(self, _('Broadcasting masternode...'), send_thread, on_send_successful, on_send_error)
def create_client(self, device, handler): # disable bridge because it seems to never returns if keepkey is plugged #transport = self._try_bridge(device) or self._try_hid(device) transport = self._try_hid(device) if not transport: self.print_error("cannot connect to device") return self.print_error("connected to device at", device.path) client = self.client_class(transport, handler, self) # Try a ping for device sanity try: client.ping('t') except BaseException as e: self.print_error("ping failed", str(e)) return None if not client.atleast_version(*self.minimum_firmware): msg = (_('Outdated %s firmware for device labelled %s. Please ' 'download the updated firmware from %s') % (self.device, client.label(), self.firmware_URL)) self.print_error(msg) handler.show_error(msg) return None return client
def callback_WordRequest(self, msg): self.step += 1 msg = _("Step %d/24. Enter seed word as explained on " "your %s:") % (self.step, self.device) word = self.handler.get_word(msg) # Unfortunately the device can't handle self.proto.Cancel() return self.proto.WordAck(word=word)
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() dialogs.remove(self)
def create_menu(self, position): item = self.currentItem() if not item: return menu = QMenu() server = item.data(1, Qt.UserRole) menu.addAction(_("Use as server"), lambda: self.set_server(server)) menu.exec_(self.viewport().mapToGlobal(position))
def message_dialog(self, msg): self.clear_dialog() self.dialog = dialog = WindowModalDialog(self.top_level_window(), _("Ledger Status")) l = QLabel(msg) vbox = QVBoxLayout(dialog) vbox.addWidget(l) dialog.show()
def __init__(self, parent): super(SignAnnounceWidget, self).__init__(parent) self.dialog = parent self.manager = parent.manager # Displays the status of the masternode. self.status_edit = QLineEdit() self.status_edit.setReadOnly(True) self.alias_edit = QLineEdit() self.collateral_edit = PrevOutWidget() self.delegate_edit = QLineEdit() self.delegate_edit.setFont(QFont(util.MONOSPACE_FONT)) for i in [self.alias_edit, self.collateral_edit, self.delegate_edit]: i.setReadOnly(True) self.mapper = QDataWidgetMapper() self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self.mapper.setModel(self.dialog.masternodes_widget.proxy_model) model = self.dialog.masternodes_widget.model self.mapper.addMapping(self.alias_edit, model.ALIAS) self.mapper.addMapping(self.collateral_edit, model.VIN, b'string') self.mapper.addMapping(self.delegate_edit, model.DELEGATE) self.sign_button = QPushButton(_('Activate Masternode')) self.sign_button.setEnabled(False) self.sign_button.clicked.connect(self.sign_announce) status_box = QHBoxLayout() status_box.setContentsMargins(0, 0, 0, 0) status_box.addWidget(QLabel(_('Status:'))) status_box.addWidget(self.status_edit, stretch=1) vbox = QVBoxLayout() vbox.addLayout(status_box) form = QFormLayout() form.addRow(_('Alias:'), self.alias_edit) form.addRow(_('Collateral REDEN Output:'), self.collateral_edit) form.addRow(_('Masternode Private Key:'), self.delegate_edit) vbox.addLayout(form) vbox.addLayout(util.Buttons(self.sign_button)) self.setLayout(vbox)
def update_dlg(self): self.modes.setCurrentIndex(self.cfg['mode']) self.modebox.setVisible(True) self.addPair.setText( _("Pair") if not self.cfg['pair'] else _("Re-Pair")) self.addPair.setVisible(self.txdata['confirmationType'] > 2) self.helpmsg.setText( helpTxt[self.cfg['mode'] if self.cfg['mode'] < 2 else 2 if self. cfg['pair'] else 4]) self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] == 1 else 100) self.pairbox.setVisible(False) self.helpmsg.setVisible(True) self.pinbox.setVisible(self.cfg['mode'] == 0) self.cardbox.setVisible(self.cfg['mode'] == 1) self.pintxt.setFocus( True) if self.cfg['mode'] == 0 else self.cardtxt.setFocus(True) self.setMaximumHeight(200)
def create_menu(self, position): menu = QMenu() item = self.itemAt(position) if not item: return key = item.data(0, Qt.UserRole) column = self.currentColumn() column_title = self.headerItem().text(column) column_data = item.text(column) pr = self.parent.invoices.get(key) status = self.parent.invoices.get_status(key) if column_data: menu.addAction(_("Copy %s")%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 catch_exception(self, *args, **kwargs): try: return func(self, *args, **kwargs) except BTChipException as e: if e.sw == 0x6982: raise Exception( _('Your Ledger is locked. Please unlock it.')) else: raise
def filename_field(parent, config, defaultname, select_msg): vbox = QVBoxLayout() vbox.addWidget(QLabel(_("Format"))) gb = QGroupBox("format", parent) b1 = QRadioButton(gb) b1.setText(_("CSV")) b1.setChecked(True) b2 = QRadioButton(gb) b2.setText(_("json")) vbox.addWidget(b1) vbox.addWidget(b2) hbox = QHBoxLayout() directory = config.get('io_dir', os.path.expanduser('~')) path = os.path.join(directory, defaultname) filename_e = QLineEdit() filename_e.setText(path) def func(): text = filename_e.text() _filter = "*.csv" if text.endswith( ".csv") else "*.json" if text.endswith(".json") else None p, __ = QFileDialog.getSaveFileName(None, select_msg, text, _filter) if p: filename_e.setText(p) button = QPushButton(_('File')) button.clicked.connect(func) hbox.addWidget(button) hbox.addWidget(filename_e) vbox.addLayout(hbox) def set_csv(v): text = filename_e.text() text = text.replace(".json", ".csv") if v else text.replace( ".csv", ".json") filename_e.setText(text) b1.clicked.connect(lambda: set_csv(True)) b2.clicked.connect(lambda: set_csv(False)) return vbox, filename_e, b1
def __init__(self, data, parent=None, title="", show_text=False): WindowModalDialog.__init__(self, parent, title) vbox = QVBoxLayout() qrw = QRCodeWidget(data) qscreen = QApplication.primaryScreen() vbox.addWidget(qrw, 1) if show_text: text = QTextEdit() text.setText(data) text.setReadOnly(True) vbox.addWidget(text) hbox = QHBoxLayout() hbox.addStretch(1) config = electrum_reden.get_config() if config: filename = os.path.join(config.path, "qrcode.png") def print_qr(): p = qscreen.grabWindow(qrw.winId()) p.save(filename, 'png') self.show_message(_("QR code saved to file") + " " + filename) def copy_to_clipboard(): p = qscreen.grabWindow(qrw.winId()) QApplication.clipboard().setPixmap(p) self.show_message(_("QR code copied to clipboard")) b = QPushButton(_("Copy")) hbox.addWidget(b) b.clicked.connect(copy_to_clipboard) b = QPushButton(_("Save")) hbox.addWidget(b) b.clicked.connect(print_qr) b = QPushButton(_("Close")) hbox.addWidget(b) b.clicked.connect(self.accept) b.setDefault(True) vbox.addLayout(hbox) self.setLayout(vbox)
def create_view_masternode_tab(self): """Create the tab used to view masternodes.""" desc = ' '.join(['In this tab, you can view your masternodes and fill in required data about them.', 'The collateral payment for a masternode can be specified using the "Choose Collateral" tab.', ]) desc = QLabel(_(desc)) desc.setWordWrap(True) self.masternode_editor = editor = MasternodeEditor() model = self.masternodes_widget.proxy_model self.mapper = mapper = QDataWidgetMapper() editor.alias_edit.textChanged.connect(self.on_editor_alias_changed) mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) mapper.setModel(model) mapper.addMapping(editor.alias_edit, MasternodesModel.ALIAS) mapper.addMapping(editor.status_edit, MasternodesModel.STATUS) editor.vin_edit.setReadOnly(True) mapper.addMapping(editor.vin_edit, MasternodesModel.VIN, b'string') mapper.addMapping(editor.addr_edit, MasternodesModel.ADDR, b'string') mapper.addMapping(editor.delegate_key_edit, MasternodesModel.DELEGATE) mapper.addMapping(editor.protocol_version_edit, MasternodesModel.PROTOCOL_VERSION) self.save_new_masternode_button = QPushButton('Save As New Masternode') self.save_new_masternode_button.clicked.connect(lambda: self.save_current_masternode(as_new=True)) self.save_masternode_button = QPushButton(_('Save Masternode')) self.save_masternode_button.clicked.connect(self.save_current_masternode) self.delete_masternode_button = QPushButton(_('Delete Masternode')) self.delete_masternode_button.clicked.connect(self.delete_current_masternode) vbox = QVBoxLayout() vbox.addWidget(desc) vbox.addWidget(editor) vbox.addStretch(1) vbox.addLayout(util.Buttons(self.delete_masternode_button, self.save_new_masternode_button, self.save_masternode_button)) w = QWidget() w.setLayout(vbox) return w