qml: clean up, generalize plugin gui base, enumerate plugins in gui
(still quite crude impl, dynamic enable/disable plugin gui is misaligned with backend)
This commit is contained in:
@@ -217,6 +217,7 @@ Pane {
|
||||
|
||||
Pane {
|
||||
ColumnLayout {
|
||||
x: constants.paddingXXLarge
|
||||
id: pluginsRootLayout
|
||||
}
|
||||
}
|
||||
@@ -232,12 +233,23 @@ Pane {
|
||||
Component {
|
||||
id: pluginHeader
|
||||
RowLayout {
|
||||
property QtObject plugin
|
||||
Layout.leftMargin: -constants.paddingXXLarge
|
||||
property string name
|
||||
property string fullname
|
||||
property bool pluginEnabled
|
||||
Switch {
|
||||
checked: plugin.pluginEnabled
|
||||
checked: pluginEnabled
|
||||
onCheckedChanged: {
|
||||
if (activeFocus)
|
||||
pluginEnabled = checked
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: plugin.name
|
||||
text: fullname
|
||||
}
|
||||
onPluginEnabledChanged: {
|
||||
console.log('!')
|
||||
AppController.setPluginEnabled(name, pluginEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,13 +264,16 @@ Pane {
|
||||
spendUnconfirmed.checked = Config.spendUnconfirmed
|
||||
lnRoutingType.currentIndex = Config.useGossip ? 0 : 1
|
||||
|
||||
var labelsPlugin = AppController.plugin('labels')
|
||||
if (labelsPlugin) {
|
||||
pluginHeader.createObject(pluginsRootLayout, { plugin: labelsPlugin })
|
||||
// console.log(Qt.resolvedUrl(labelsPlugin.settingsComponent()))
|
||||
if (labelsPlugin.settingsComponent()) {
|
||||
var component = Qt.createComponent(Qt.resolvedUrl(labelsPlugin.settingsComponent()))
|
||||
component.createObject(pluginsRootLayout, {plugin: labelsPlugin})
|
||||
var plugins = AppController.plugins
|
||||
for (var i=0; i<plugins.length; i++) {
|
||||
var p = plugins[i]
|
||||
pluginHeader.createObject(pluginsRootLayout, { name: p['name'], fullname: p['fullname'], pluginEnabled: p['enabled'] })
|
||||
var labelsPlugin = AppController.plugin(p['name'])
|
||||
if (labelsPlugin) {
|
||||
if (labelsPlugin.settingsComponent()) {
|
||||
var component = Qt.createComponent(Qt.resolvedUrl(labelsPlugin.settingsComponent()))
|
||||
component.createObject(pluginsRootLayout, { plugin: labelsPlugin })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,6 @@ ApplicationWindow
|
||||
property bool _lockDialogShown: false
|
||||
|
||||
onActiveChanged: {
|
||||
console.log('active='+active)
|
||||
if (!active) {
|
||||
// deactivated
|
||||
_lastActive = Date.now()
|
||||
|
||||
40
electrum/gui/qml/plugins.py
Normal file
40
electrum/gui/qml/plugins.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, QObject
|
||||
|
||||
from electrum.i18n import _
|
||||
from electrum.logging import get_logger
|
||||
|
||||
class PluginQObject(QObject):
|
||||
logger = get_logger(__name__)
|
||||
|
||||
pluginChanged = pyqtSignal()
|
||||
busyChanged = pyqtSignal()
|
||||
pluginEnabledChanged = pyqtSignal()
|
||||
|
||||
_busy = False
|
||||
|
||||
def __init__(self, plugin, parent: 'ElectrumGuiApplication'):
|
||||
super().__init__(parent)
|
||||
self.plugin = plugin
|
||||
self.app = parent
|
||||
|
||||
@pyqtProperty(str, notify=pluginChanged)
|
||||
def name(self): return self._name
|
||||
|
||||
@pyqtProperty(bool, notify=busyChanged)
|
||||
def busy(self): return self._busy
|
||||
|
||||
@pyqtProperty(bool, notify=pluginEnabledChanged)
|
||||
def pluginEnabled(self): return self.plugin.is_enabled()
|
||||
|
||||
@pluginEnabled.setter
|
||||
def pluginEnabled(self, enabled):
|
||||
if enabled != self.plugin.is_enabled():
|
||||
self.logger.debug(f'can {self.plugin.can_user_disable()}, {self.plugin.is_available()}')
|
||||
if not self.plugin.can_user_disable() and not enabled:
|
||||
return
|
||||
if enabled:
|
||||
self.app.plugins.enable(self.plugin.name)
|
||||
else:
|
||||
self.app.plugins.disable(self.plugin.name)
|
||||
self.pluginEnabledChanged.emit()
|
||||
|
||||
@@ -3,7 +3,7 @@ import queue
|
||||
import time
|
||||
import os
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QUrl, QLocale, qInstallMessageHandler, QTimer
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty, QObject, QUrl, QLocale, qInstallMessageHandler, QTimer
|
||||
from PyQt5.QtGui import QGuiApplication, QFontDatabase
|
||||
from PyQt5.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine
|
||||
|
||||
@@ -34,6 +34,8 @@ notification = None
|
||||
class QEAppController(QObject):
|
||||
userNotify = pyqtSignal(str)
|
||||
|
||||
_dummy = pyqtSignal()
|
||||
|
||||
def __init__(self, qedaemon, plugins):
|
||||
super().__init__()
|
||||
self.logger = get_logger(__name__)
|
||||
@@ -134,15 +136,37 @@ class QEAppController(QObject):
|
||||
|
||||
@pyqtSlot(str, result=QObject)
|
||||
def plugin(self, plugin_name):
|
||||
self.logger.warning(f'now {self._plugins.count()} plugins loaded')
|
||||
self.logger.debug(f'now {self._plugins.count()} plugins loaded')
|
||||
plugin = self._plugins.get(plugin_name)
|
||||
self.logger.debug(f'plugin with name {plugin_name} is {str(type(plugin))}')
|
||||
if plugin:
|
||||
if plugin and hasattr(plugin,'so'):
|
||||
return plugin.so
|
||||
else:
|
||||
self.logger.debug('None!')
|
||||
return None
|
||||
|
||||
@pyqtProperty('QVariant', notify=_dummy)
|
||||
def plugins(self):
|
||||
s = []
|
||||
for item in self._plugins.descriptions:
|
||||
self.logger.info(item)
|
||||
s.append({
|
||||
'name': item,
|
||||
'fullname': self._plugins.descriptions[item]['fullname'],
|
||||
'enabled': bool(self._plugins.get(item))
|
||||
})
|
||||
|
||||
self.logger.debug(f'{str(s)}')
|
||||
return s
|
||||
|
||||
@pyqtSlot(str, bool)
|
||||
def setPluginEnabled(self, plugin, enabled):
|
||||
if enabled:
|
||||
self._plugins.enable(plugin)
|
||||
else:
|
||||
self._plugins.disable(plugin)
|
||||
|
||||
|
||||
class ElectrumQmlApplication(QGuiApplication):
|
||||
|
||||
_valid = True
|
||||
@@ -190,10 +214,11 @@ class ElectrumQmlApplication(QGuiApplication):
|
||||
self.fixedFont = 'Monospace' # hope for the best
|
||||
|
||||
self.context = self.engine.rootContext()
|
||||
self.plugins = plugins
|
||||
self._qeconfig = QEConfig(config)
|
||||
self._qenetwork = QENetwork(daemon.network, self._qeconfig)
|
||||
self.daemon = QEDaemon(daemon)
|
||||
self.appController = QEAppController(self.daemon, plugins)
|
||||
self.appController = QEAppController(self.daemon, self.plugins)
|
||||
self._maxAmount = QEAmount(is_max=True)
|
||||
self.context.setContextProperty('AppController', self.appController)
|
||||
self.context.setContextProperty('Config', self._qeconfig)
|
||||
|
||||
@@ -6,35 +6,23 @@ from electrum.i18n import _
|
||||
from electrum.plugin import hook
|
||||
|
||||
from electrum.gui.qml.qewallet import QEWallet
|
||||
from electrum.gui.qml.plugins import PluginQObject
|
||||
|
||||
from .labels import LabelsPlugin
|
||||
|
||||
class Plugin(LabelsPlugin):
|
||||
|
||||
class QSignalObject(QObject):
|
||||
pluginChanged = pyqtSignal()
|
||||
pluginEnabledChanged = pyqtSignal()
|
||||
class QSignalObject(PluginQObject):
|
||||
labelsChanged = pyqtSignal()
|
||||
busyChanged = pyqtSignal()
|
||||
uploadSuccess = pyqtSignal()
|
||||
uploadFailed = pyqtSignal()
|
||||
downloadSuccess = pyqtSignal()
|
||||
downloadFailed = pyqtSignal()
|
||||
|
||||
_busy = False
|
||||
_name = _('LabelSync Plugin')
|
||||
|
||||
def __init__(self, plugin, parent = None):
|
||||
super().__init__(parent)
|
||||
self.plugin = plugin
|
||||
|
||||
@pyqtProperty(str, notify=pluginChanged)
|
||||
def name(self): return _('Labels Plugin')
|
||||
|
||||
@pyqtProperty(bool, notify=busyChanged)
|
||||
def busy(self): return self._busy
|
||||
|
||||
@pyqtProperty(bool, notify=pluginEnabledChanged)
|
||||
def pluginEnabled(self): return self.plugin.is_enabled()
|
||||
def __init__(self, plugin, parent):
|
||||
super().__init__(plugin, parent)
|
||||
|
||||
@pyqtSlot(result=str)
|
||||
def settingsComponent(self): return '../../../plugins/labels/Labels.qml'
|
||||
@@ -78,7 +66,7 @@ class Plugin(LabelsPlugin):
|
||||
|
||||
@hook
|
||||
def load_wallet(self, wallet):
|
||||
self.logger.info(f'load_wallet hook for wallet {str(type(wallet))}')
|
||||
self.logger.debug(f'plugin enabled for wallet "{str(wallet)}"')
|
||||
self.start_wallet(wallet)
|
||||
|
||||
def push_async(self):
|
||||
@@ -130,8 +118,7 @@ class Plugin(LabelsPlugin):
|
||||
|
||||
@hook
|
||||
def init_qml(self, gui: 'ElectrumGui'):
|
||||
self.logger.debug('init_qml hook called')
|
||||
self.logger.debug(f'gui={str(type(gui))}')
|
||||
self.logger.debug(f'init_qml hook called, gui={str(type(gui))}')
|
||||
self._app = gui.app
|
||||
# important: QSignalObject needs to be parented, as keeping a ref
|
||||
# in the plugin is not enough to avoid gc
|
||||
|
||||
Reference in New Issue
Block a user