def create_menu(self, position): from electrum_grlc.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.item_from_index(item).text() for item in selected] menu = QMenu() if not multi_select: idx = self.indexAt(position) if not idx.isValid(): return item = self.item_from_index(idx) if not item: return addr = addrs[0] addr_column_title = self.std_model.horizontalHeaderItem( self.Columns.LABEL).text() addr_idx = idx.sibling(idx.row(), self.Columns.LABEL) self.add_copy_menu(menu, idx) 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: webopen(addr_URL)) if not self.wallet.is_frozen_address(addr): menu.addAction( _("Freeze"), lambda: self.parent. set_frozen_state_of_addresses([addr], True)) else: menu.addAction( _("Unfreeze"), lambda: self.parent. set_frozen_state_of_addresses([addr], False)) coins = self.wallet.get_spendable_coins(addrs) if coins: menu.addAction(_("Spend from"), lambda: self.parent.utxo_list.set_spend_list(coins)) run_hook('receive_menu', menu, addrs, self.wallet) menu.exec_(self.viewport().mapToGlobal(position))
def __init__(self, text=None, *, config: SimpleConfig): ButtonsTextEdit.__init__(self, text) self.config = config self.setReadOnly(True) icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png" self.addButton(icon, self.qr_show, _("Show as QR code")) run_hook('show_text_edit', self)
def close_window(self, window: ElectrumWindow): if window in self.windows: self.windows.remove(window) self.build_tray_menu() # save wallet path of last open window if not self.windows: self.config.save_last_wallet(window.wallet) run_hook('on_close_window', window) self.daemon.stop_wallet(window.wallet.storage.path)
def __init__(self, text="", allow_multi=False, *, config: SimpleConfig): ButtonsTextEdit.__init__(self, text) Logger.__init__(self) self.allow_multi = allow_multi self.config = config self.setReadOnly(False) 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 __init__(self, parent=None, msg=None): msg = msg or _('Please enter your password') WindowModalDialog.__init__(self, parent, _("Enter Password")) self.pw = pw = PasswordLineEdit() 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 update(self): tx = self.tx self._update_amount_label() if self.not_enough_funds: text = self.main_window.get_text_not_enough_funds_mentioning_frozen( ) self.toggle_send_button(False, message=text) return if not tx: return fee = tx.get_fee() assert fee is not None self.fee_label.setText(self.main_window.format_amount_and_units(fee)) x_fee = run_hook('get_tx_extra_fee', self.wallet, tx) if x_fee: x_fee_address, x_fee_amount = x_fee self.extra_fee_label.setVisible(True) self.extra_fee_value.setVisible(True) self.extra_fee_value.setText( self.main_window.format_amount_and_units(x_fee_amount)) amount = tx.output_value( ) if self.output_value == '!' else self.output_value tx_size = tx.estimated_size() fee_warning_tuple = self.wallet.get_tx_fee_warning(invoice_amt=amount, tx_size=tx_size, fee=fee) if fee_warning_tuple: allow_send, long_warning, short_warning = fee_warning_tuple self.toggle_send_button(allow_send, message=long_warning) else: self.toggle_send_button(True)
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( self.ROLE_CONTACT_KEY) 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.parent.import_contacts()) menu.addAction(_("Export file"), lambda: self.parent.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.place_text_on_clipboard(column_data, title=column_title)) 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: [webopen(u) for u in URLs]) run_hook('create_contact_menu', menu, selected_keys) menu.exec_(self.viewport().mapToGlobal(position))
def __init__(self, *, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'): set_language(config.get('language', get_default_language())) BaseElectrumGui.__init__(self, config=config, daemon=daemon, plugins=plugins) Logger.__init__(self) self.logger.info( f"Qt GUI starting up... Qt={QtCore.QT_VERSION_STR}, PyQt={QtCore.PYQT_VERSION_STR}" ) # Uncomment this call to verify objects are being properly # GC-ed when windows are closed #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer, # ElectrumWindow], interval=5)]) QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads) if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"): QtCore.QCoreApplication.setAttribute( QtCore.Qt.AA_ShareOpenGLContexts) if hasattr(QGuiApplication, 'setDesktopFileName'): QGuiApplication.setDesktopFileName('electrum-grlc.desktop') self.gui_thread = threading.current_thread() self.windows = [] # type: List[ElectrumWindow] self.efilter = OpenFileEventFilter(self.windows) self.app = QElectrumApplication(sys.argv) self.app.installEventFilter(self.efilter) self.app.setWindowIcon(read_QIcon("electrum-grlc.png")) self._cleaned_up = False # timer self.timer = QTimer(self.app) self.timer.setSingleShot(False) self.timer.setInterval(500) # msec self.network_dialog = None self.lightning_dialog = None self.watchtower_dialog = None self.network_updated_signal_obj = QNetworkUpdatedSignalObject() self._num_wizards_in_progress = 0 self._num_wizards_lock = threading.Lock() self.dark_icon = self.config.get("dark_icon", False) self.tray = None self._init_tray() self.app.new_window_signal.connect(self.start_new_window) self.app.quit_signal.connect(self.app.quit, Qt.QueuedConnection) self.set_dark_theme_if_needed() run_hook('init_qt', self)
def create_menu(self, position): items = self.selected_in_column(0) if len(items) > 1: keys = [item.data(ROLE_KEY) for item in items] menu = QMenu(self) menu.addAction(_("Delete requests"), lambda: self.parent.delete_requests(keys)) menu.exec_(self.viewport().mapToGlobal(position)) return idx = self.indexAt(position) # TODO use siblingAtColumn when min Qt version is >=5.11 item = self.item_from_index(idx.sibling(idx.row(), self.Columns.DATE)) if not item: return key = item.data(ROLE_KEY) req = self.wallet.get_request(key) if req is None: self.update() return menu = QMenu(self) self.add_copy_menu(menu, idx) if req.is_lightning(): menu.addAction( _("Copy Request"), lambda: self.parent.do_copy(req.invoice, title='Lightning Request')) else: URI = self.wallet.get_request_URI(req) menu.addAction( _("Copy Request"), lambda: self.parent.do_copy(URI, title='Garlicoin URI')) menu.addAction( _("Copy Address"), lambda: self.parent.do_copy(req.get_address(), title='Garlicoin Address')) #if 'view_url' in req: # menu.addAction(_("View in web browser"), lambda: webopen(req['view_url'])) menu.addAction(_("Delete"), lambda: self.parent.delete_requests([key])) run_hook('receive_list_menu', self.parent, menu, key) menu.exec_(self.viewport().mapToGlobal(position))
def update(self): if self.maybe_defer_update(): return current_key = self.get_role_data_for_current_item( col=self.Columns.NAME, role=self.ROLE_CONTACT_KEY) self.model().clear() self.update_headers(self.__class__.headers) set_current = None for key in sorted(self.parent.contacts.keys()): contact_type, name = self.parent.contacts[key] items = [QStandardItem(x) for x in (name, key)] items[self.Columns.NAME].setEditable(contact_type != 'openalias') items[self.Columns.ADDRESS].setEditable(False) items[self.Columns.NAME].setData(key, self.ROLE_CONTACT_KEY) row_count = self.model().rowCount() self.model().insertRow(row_count, items) if key == current_key: idx = self.model().index(row_count, self.Columns.NAME) set_current = QPersistentModelIndex(idx) self.set_current_idx(set_current) # FIXME refresh loses sort order; so set "default" here: self.sortByColumn(self.Columns.NAME, Qt.AscendingOrder) self.filter() run_hook('update_contacts_tab', self)