diff --git a/electrum_grs/daemon.py b/electrum_grs/daemon.py index 9e0fee02c36..1c6ec36a0c0 100644 --- a/electrum_grs/daemon.py +++ b/electrum_grs/daemon.py @@ -497,6 +497,7 @@ def load_wallet(self, path, password, *, upgrade=False) -> Optional[Abstract_Wal wallet = self._load_wallet(path, password, upgrade=upgrade, config=self.config) wallet.start_network(self.network) self.add_wallet(wallet) + self.update_recently_opened_wallets(path) return wallet @staticmethod @@ -542,6 +543,7 @@ def delete_wallet(self, path: str) -> bool: self.stop_wallet(path) if os.path.exists(path): os.unlink(path) + self.update_recently_opened_wallets(path, remove=True) return True return False @@ -704,3 +706,14 @@ def update_password_for_directory( self._check_password_for_directory( old_password=old_password, new_password=new_password, wallet_dir=wallet_dir) return True + + def update_recently_opened_wallets(self, wallet_path, *, remove: bool = False): + recent = self.config.RECENTLY_OPEN_WALLET_FILES or [] + if wallet_path in recent: + recent.remove(wallet_path) + if not remove: + recent.insert(0, wallet_path) + recent = [path for path in recent if os.path.exists(path)] + recent = recent[:5] + self.config.RECENTLY_OPEN_WALLET_FILES = recent + util.trigger_callback('recently_opened_wallets_update') diff --git a/electrum_grs/gui/qml/components/controls/InfoTextArea.qml b/electrum_grs/gui/qml/components/controls/InfoTextArea.qml index 7f70c3cf507..203827c9eff 100644 --- a/electrum_grs/gui/qml/components/controls/InfoTextArea.qml +++ b/electrum_grs/gui/qml/components/controls/InfoTextArea.qml @@ -72,7 +72,6 @@ TextHighlightPane { Label { id: infotext Layout.fillWidth: true - width: parent.width wrapMode: Text.Wrap } } diff --git a/electrum_grs/gui/qt/history_list.py b/electrum_grs/gui/qt/history_list.py index 85108676c10..4e2bbec045d 100644 --- a/electrum_grs/gui/qt/history_list.py +++ b/electrum_grs/gui/qt/history_list.py @@ -111,6 +111,10 @@ def get_data_for_role(self, index: QModelIndex, role: Qt.ItemDataRole) -> QVaria window = self.model.window tx_item = self.get_data() is_lightning = tx_item.get('lightning', False) + if not is_lightning and 'txid' not in tx_item: + # this may happen if two lightning tx have the same group id + # and the group does not have an onchain tx + is_lightning = True timestamp = tx_item['timestamp'] short_id = None if is_lightning: diff --git a/electrum_grs/gui/qt/main_window.py b/electrum_grs/gui/qt/main_window.py index d3350d4f7d1..872e9e29c8a 100644 --- a/electrum_grs/gui/qt/main_window.py +++ b/electrum_grs/gui/qt/main_window.py @@ -491,6 +491,10 @@ def on_event_tor_probed(self, is_tor): def on_event_proxy_set(self, *args): self.tor_button.setVisible(False) + @qt_event_listener + def on_event_recently_opened_wallets_update(self, *args): + self.update_recently_opened_menu() + def close_wallet(self): if self.wallet: self.logger.info(f'close_wallet {self.wallet.storage.path}') @@ -498,7 +502,7 @@ def close_wallet(self): @profiler def load_wallet(self, wallet: Abstract_Wallet): - self.update_recently_visited(wallet.storage.path) + self.update_recently_opened_menu() if wallet.has_lightning(): util.trigger_callback('channels_updated', wallet) self.need_update.set() @@ -643,24 +647,15 @@ def backup_wallet(self): self.show_message(msg, title=_("Wallet backup created")) return True - def update_recently_visited(self, filename): - recent = self.config.RECENTLY_OPEN_WALLET_FILES or [] - try: - sorted(recent) - except Exception: - recent = [] - if filename in recent: - recent.remove(filename) - recent.insert(0, filename) - recent = [path for path in recent if os.path.exists(path)] - recent = recent[:5] - self.config.RECENTLY_OPEN_WALLET_FILES = recent + def update_recently_opened_menu(self): + recent = self.config.RECENTLY_OPEN_WALLET_FILES self.recently_visited_menu.clear() - for i, k in enumerate(sorted(recent)): + for i, k in enumerate(recent): b = os.path.basename(k) + def loader(k): return lambda: self.gui_object.new_window(k) - self.recently_visited_menu.addAction(b, loader(k)).setShortcut(QKeySequence("Ctrl+%d"%(i+1))) + self.recently_visited_menu.addAction(b, loader(k)).setShortcut(QKeySequence("Ctrl+%d" % (i+1))) self.recently_visited_menu.setEnabled(bool(len(recent))) def get_wallet_folder(self): diff --git a/electrum_grs/gui/qt/wizard/wallet.py b/electrum_grs/gui/qt/wizard/wallet.py index 9ac85320942..65125cb0446 100644 --- a/electrum_grs/gui/qt/wizard/wallet.py +++ b/electrum_grs/gui/qt/wizard/wallet.py @@ -376,6 +376,9 @@ def on_filename(filename): self.name_e.textChanged.connect(on_filename) self.name_e.setText(relative_path(path)) + def initialFocus(self) -> Optional[QWidget]: + return self.pw_e + def apply(self): if self.wallet_exists: # use full path @@ -986,6 +989,9 @@ def setEnabled(self2, b): self.layout().addLayout(self.pw_layout.layout()) self.layout().addStretch(1) + def initialFocus(self) -> Optional[QWidget]: + return self.pw_layout.new_pw + def apply(self): self.wizard_data['password'] = self.pw_layout.new_password() self.wizard_data['encrypt'] = self.pw_layout.encrypt_cb.isChecked() diff --git a/electrum_grs/gui/qt/wizard/wizard.py b/electrum_grs/gui/qt/wizard/wizard.py index 46d96fbcf80..fa7b53d4244 100644 --- a/electrum_grs/gui/qt/wizard/wizard.py +++ b/electrum_grs/gui/qt/wizard/wizard.py @@ -1,7 +1,7 @@ import copy import threading from abc import abstractmethod -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from PyQt6.QtCore import Qt, QTimer, pyqtSignal, pyqtSlot, QSize, QMetaObject from PyQt6.QtGui import QPixmap @@ -129,7 +129,8 @@ def strt(self): else: viewstate = self.start_wizard() self.load_next_component(viewstate.view, viewstate.wizard_data, viewstate.params) - self.next_button.setFocus() + self.set_default_focus() + # TODO: re-test if needed on macOS self.refresh_gui() # Need for QT on MacOSX. Lame. @@ -174,6 +175,14 @@ def set_icon(self, filename): .scaledToWidth(60, mode=Qt.TransformationMode.SmoothTransformation)) return prior_filename + def set_default_focus(self): + page = self.main_widget.currentWidget() + control = page.initialFocus() + if control and control.isVisible() and control.isEnabled(): + control.setFocus() + else: + self.next_button.setFocus() + def can_go_back(self) -> bool: return len(self._stack) > 0 @@ -222,6 +231,7 @@ def on_next_button_clicked(self): view = self.submit(wd) try: self.load_next_component(view.view, view.wizard_data, view.params) + self.set_default_focus() except Exception as e: self.prev() # rollback the submit above raise e @@ -311,3 +321,7 @@ def on_updated(self, *args): self.updated.emit(self) except RuntimeError: pass + + def initialFocus(self) -> Optional[QWidget]: + """Override to specify a control that should receive initial focus""" + return None