Browse Source

qt plugins dialog: fix caching "settings" button

shesek reported on IRC:
> the button widget for opening plugins configuration gets cached in `settings_widgets`
> even after the plugin is disabled and re-enabled, which causes it to call `settings_dialog()`
> on the previous plugin instance that got unloaded instead of the new one.
master
SomberNight 4 years ago
parent
commit
4d8fcded4b
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 16
      electrum/gui/qt/main_window.py
  2. 22
      electrum/plugin.py

16
electrum/gui/qt/main_window.py

@ -52,7 +52,7 @@ import electrum
from electrum import (keystore, ecc, constants, util, bitcoin, commands, from electrum import (keystore, ecc, constants, util, bitcoin, commands,
paymentrequest) paymentrequest)
from electrum.bitcoin import COIN, is_address from electrum.bitcoin import COIN, is_address
from electrum.plugin import run_hook from electrum.plugin import run_hook, BasePlugin
from electrum.i18n import _ from electrum.i18n import _
from electrum.util import (format_time, format_satoshis, format_fee_satoshis, from electrum.util import (format_time, format_satoshis, format_fee_satoshis,
format_satoshis_plain, format_satoshis_plain,
@ -2939,13 +2939,17 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
settings_widgets = {} settings_widgets = {}
def enable_settings_widget(p, name, i): def enable_settings_widget(p: Optional['BasePlugin'], name: str, i: int):
widget = settings_widgets.get(name) widget = settings_widgets.get(name) # type: Optional[QWidget]
if not widget and p and p.requires_settings(): if widget and not p:
# plugin got disabled, rm widget
grid.removeWidget(widget)
widget.setParent(None)
settings_widgets.pop(name)
elif widget is None and p and p.requires_settings() and p.is_enabled():
# plugin got enabled, add widget
widget = settings_widgets[name] = p.settings_widget(d) widget = settings_widgets[name] = p.settings_widget(d)
grid.addWidget(widget, i, 1) grid.addWidget(widget, i, 1)
if widget:
widget.setEnabled(bool(p and p.is_enabled()))
def do_toggle(cb, name, i): def do_toggle(cb, name, i):
p = plugins.toggle(name) p = plugins.toggle(name)

22
electrum/plugin.py

@ -43,6 +43,7 @@ from .logging import get_logger, Logger
if TYPE_CHECKING: if TYPE_CHECKING:
from .plugins.hw_wallet import HW_PluginBase, HardwareClientBase, HardwareHandlerBase from .plugins.hw_wallet import HW_PluginBase, HardwareClientBase, HardwareHandlerBase
from .keystore import Hardware_KeyStore from .keystore import Hardware_KeyStore
from .wallet import Abstract_Wallet
_logger = get_logger(__name__) _logger = get_logger(__name__)
@ -107,7 +108,7 @@ class Plugins(DaemonThread):
def count(self): def count(self):
return len(self.plugins) return len(self.plugins)
def load_plugin(self, name): def load_plugin(self, name) -> 'BasePlugin':
if name in self.plugins: if name in self.plugins:
return self.plugins[name] return self.plugins[name]
full_name = f'electrum.plugins.{name}.{self.gui_name}' full_name = f'electrum.plugins.{name}.{self.gui_name}'
@ -129,14 +130,14 @@ class Plugins(DaemonThread):
def close_plugin(self, plugin): def close_plugin(self, plugin):
self.remove_jobs(plugin.thread_jobs()) self.remove_jobs(plugin.thread_jobs())
def enable(self, name): def enable(self, name: str) -> 'BasePlugin':
self.config.set_key('use_' + name, True, True) self.config.set_key('use_' + name, True, True)
p = self.get(name) p = self.get(name)
if p: if p:
return p return p
return self.load_plugin(name) return self.load_plugin(name)
def disable(self, name): def disable(self, name: str) -> None:
self.config.set_key('use_' + name, False, True) self.config.set_key('use_' + name, False, True)
p = self.get(name) p = self.get(name)
if not p: if not p:
@ -145,11 +146,11 @@ class Plugins(DaemonThread):
p.close() p.close()
self.logger.info(f"closed {name}") self.logger.info(f"closed {name}")
def toggle(self, name): def toggle(self, name: str) -> Optional['BasePlugin']:
p = self.get(name) p = self.get(name)
return self.disable(name) if p else self.enable(name) return self.disable(name) if p else self.enable(name)
def is_available(self, name, w): def is_available(self, name: str, wallet: 'Abstract_Wallet') -> bool:
d = self.descriptions.get(name) d = self.descriptions.get(name)
if not d: if not d:
return False return False
@ -161,7 +162,7 @@ class Plugins(DaemonThread):
self.logger.warning(f'Plugin {name} unavailable: {repr(e)}') self.logger.warning(f'Plugin {name} unavailable: {repr(e)}')
return False return False
requires = d.get('requires_wallet_type', []) requires = d.get('requires_wallet_type', [])
return not requires or w.wallet_type in requires return not requires or wallet.wallet_type in requires
def get_hardware_support(self): def get_hardware_support(self):
out = [] out = []
@ -270,7 +271,7 @@ class BasePlugin(Logger):
def on_close(self): def on_close(self):
pass pass
def requires_settings(self): def requires_settings(self) -> bool:
return False return False
def thread_jobs(self): def thread_jobs(self):
@ -285,8 +286,11 @@ class BasePlugin(Logger):
def can_user_disable(self): def can_user_disable(self):
return True return True
def settings_dialog(self): def settings_widget(self, window):
pass raise NotImplementedError()
def settings_dialog(self, window):
raise NotImplementedError()
class DeviceUnpairableError(UserFacingException): pass class DeviceUnpairableError(UserFacingException): pass

Loading…
Cancel
Save