forked from bitcoinafterlife/bal-electrum-plugin
fix(qt): auto-close Plugins manager, read-only field styling, RLock-safe heirs persistence
GUI / plugin lifecycle: - Auto-close Electrum's native 'Electrum Plugins' manager dialog after the BAL plugin is hot-enabled. Electrum 4.7.x no longer calls the old init_qt hook, so the close is now triggered from the create_status_bar, init_menubar and load_wallet hooks (fired when reload_windows() recreates the window). - Robust dialog matching (isinstance / class name / localized window title) to cope with zipimport module-identity mismatches. - Robust dismissal of the modal dialog (reject()/done()/close()) with a retry schedule [400, 800, 1500] ms; if it still cannot be closed, fall back to bringing it to the front (showNormal/raise_/activateWindow) so it never lingers hidden in the background. Counting only visible top-levels avoids treating an already-closed dialog as still open. Read-only field styling: - Paint the locked Delivery time / Check Alive date editors and the mining-fee spinbox with a light-grey background (#f0f0f0) so the user can see at a glance that they are not editable outside the 'Build your will' wizard; the styling is cleared when the fields are made editable again. Pickle/RLock crash on 'Build will': - heirs.save() now sanitises the heirs mapping via _json_safe() before handing it to json_db.put(), which deep-copies the value. A live runtime object (holding a threading.RLock) slipping into an heir value previously raised 'TypeError: cannot pickle _thread.RLock object' and aborted the task; such values are now coerced to str and logged with their path. - init_heirs_to_locktime() coerces the locktime to a plain serializable scalar. - log_error() now accepts both a sys.exc_info() triple and a single exception instance, fixing the secondary 'TypeError object is not subscriptable' that masked the real error.
This commit is contained in:
@@ -53,10 +53,10 @@ from PyQt6.QtCore import (QDateTime, QModelIndex, QPersistentModelIndex, Qt,
|
||||
QTimer, pyqtSignal)
|
||||
from PyQt6.QtGui import (QColor, QPainter, QPalette, QStandardItem,
|
||||
QStandardItemModel)
|
||||
from PyQt6.QtWidgets import (QAbstractItemView, QCheckBox, QComboBox,
|
||||
QDateTimeEdit, QGridLayout, QHBoxLayout, QLabel,
|
||||
QLineEdit, QTextEdit, QMenu, QMenuBar, QPushButton,
|
||||
QScrollArea, QSizePolicy, QSpinBox,
|
||||
from PyQt6.QtWidgets import (QAbstractItemView, QAbstractSpinBox, QCheckBox,
|
||||
QComboBox, QDateTimeEdit, QGridLayout, QHBoxLayout,
|
||||
QLabel, QLineEdit, QTextEdit, QMenu, QMenuBar,
|
||||
QPushButton, QScrollArea, QSizePolicy, QSpinBox,
|
||||
QStackedWidget, QStyle, QStyleOptionFrame,
|
||||
QVBoxLayout, QWidget, QDialog)
|
||||
|
||||
@@ -116,18 +116,34 @@ class CheckAliveError(Exception):
|
||||
|
||||
|
||||
def log_error(exec_info, window=None):
|
||||
_logger.error(f"LOG_ERROR: {exec_info}")
|
||||
#tb = traceback.format_exc()
|
||||
try:
|
||||
tb=exec_info[1]
|
||||
_logger.error(tb)
|
||||
except Exception:
|
||||
tb = traceback.format_exc()
|
||||
_logger.error(tb)
|
||||
"""Log an error and optionally show it.
|
||||
|
||||
``exec_info`` may be either a ``sys.exc_info()`` triple
|
||||
``(type, value, traceback)`` or a single exception instance (callers use
|
||||
both forms), so we handle both and always try to log a full traceback.
|
||||
"""
|
||||
_logger.error(f"LOG_ERROR: {exec_info}")
|
||||
exc = None
|
||||
if isinstance(exec_info, BaseException):
|
||||
exc = exec_info
|
||||
elif isinstance(exec_info, (tuple, list)) and len(exec_info) >= 2:
|
||||
# sys.exc_info() form: the exception instance is the 2nd element.
|
||||
exc = exec_info[1]
|
||||
try:
|
||||
if exc is not None:
|
||||
_logger.error(
|
||||
"".join(
|
||||
traceback.format_exception(type(exc), exc, exc.__traceback__)
|
||||
)
|
||||
)
|
||||
else:
|
||||
_logger.error(traceback.format_exc())
|
||||
except Exception:
|
||||
_logger.error(traceback.format_exc())
|
||||
|
||||
if window is not None:
|
||||
window.show_error(exec_info)
|
||||
# show_error expects a human-readable message, not a triple.
|
||||
window.show_error(str(exc) if exc is not None else str(exec_info))
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user