diff --git a/src/calibre/gui2/dbus_export/demo.py b/src/calibre/gui2/dbus_export/demo.py index 7a67a37233..9ee4dbd4c8 100644 --- a/src/calibre/gui2/dbus_export/demo.py +++ b/src/calibre/gui2/dbus_export/demo.py @@ -28,7 +28,8 @@ class MainWindow(QMainWindow): self.l = QVBoxLayout(w) mb = f.create_window_menubar(self) self.setMenuBar(mb) - m = mb.addMenu('&One') + m = self.menu_one = mb.addMenu('&One') + m.aboutToShow.connect(self.about_to_show_one) s = self.style() for i, icon in zip(xrange(3), map(s.standardIcon, (s.SP_DialogOkButton, s.SP_DialogCancelButton, s.SP_ArrowUp))): ac = m.addAction('One - &%d' % (i + 1)) @@ -41,6 +42,9 @@ class MainWindow(QMainWindow): g = QActionGroup(self) make_checkable(g.addAction(m.addAction('Exclusive 1'))) make_checkable(g.addAction(m.addAction('Exclusive 2')), False) + m.addSeparator() + self.about_to_show_sentinel = m.addAction('This action\'s text should change before menu is shown') + self.as_count = 0 for ac in mb.findChildren(QAction): ac.triggered.connect(self.action_triggered) @@ -49,6 +53,10 @@ class MainWindow(QMainWindow): text = 'Action triggered: %s' % ac.text() self.statusBar().showMessage(text) + def about_to_show_one(self): + self.as_count += 1 + self.about_to_show_sentinel.setText('About to show handled: %d' % self.as_count) + app = QApplication([]) f = factory() mw = MainWindow() diff --git a/src/calibre/gui2/dbus_export/menu.py b/src/calibre/gui2/dbus_export/menu.py index 590d57df38..2c2bdfc1a3 100644 --- a/src/calibre/gui2/dbus_export/menu.py +++ b/src/calibre/gui2/dbus_export/menu.py @@ -228,6 +228,15 @@ class DBusMenu(QObject): ac.toggle() ac.triggered.emit(ac.isCheckable() and ac.isChecked()) + def handle_about_to_show(self, ac): + child_ids = {self.action_to_id(x) for x in ac.menu().actions()} + child_ids.discard(None) + ac_id = self.action_to_id(ac) + ac.menu().aboutToShow.emit() + if ac_id in self.layout_changes or child_ids.intersection(self.action_changes): + return True + return False + class DBusMenuAPI(Object): IFACE = 'com.canonical.dbusmenu' @@ -302,11 +311,23 @@ class DBusMenuAPI(Object): @dbus_method(IFACE, in_signature='i', out_signature='b') def AboutToShow(self, id): - pass + ac = self.menu.id_to_action(id) + if ac is not None and ac.menu() is not None: + return self.menu.handle_about_to_show(ac) + return False @dbus_method(IFACE, in_signature='ai', out_signature='aiai') def AboutToShowGroup(self, ids): - pass + updates_needed = dbus.Array(signature='i') + id_errors = dbus.Array(signature='i') + for ac_id in ids: + ac = self.menu.id_to_action(id) + if ac is not None and ac.menu() is not None: + if self.menu.handle_about_to_show(ac): + updates_needed.append(ac_id) + else: + id_errors.append(ac_id) + return updates_needed, id_errors @dbus_signal(IFACE, 'a(ia{sv})a(ias)') def ItemsPropertiesUpdated(self, updatedProps, removedProps): diff --git a/src/calibre/gui2/dbus_export/utils.py b/src/calibre/gui2/dbus_export/utils.py index ea5efdb3cb..6b1ab1c731 100644 --- a/src/calibre/gui2/dbus_export/utils.py +++ b/src/calibre/gui2/dbus_export/utils.py @@ -14,7 +14,7 @@ from PyQt5.Qt import QSize, QImage, Qt, QKeySequence, QBuffer, QByteArray def log(*args, **kw): kw['file'] = sys.stderr - print('StatusNotifier:', *args, **kw) + print('DBusExport:', *args, **kw) kw['file'].flush() diff --git a/src/calibre/gui2/dbus_export/widgets.py b/src/calibre/gui2/dbus_export/widgets.py index 4de97d3ac5..eb718beb2d 100644 --- a/src/calibre/gui2/dbus_export/widgets.py +++ b/src/calibre/gui2/dbus_export/widgets.py @@ -6,12 +6,17 @@ from __future__ import (unicode_literals, division, absolute_import, __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' -import time +import time, sys from PyQt5.Qt import QObject, QMenuBar, QAction, QEvent UNITY_WINDOW_REGISTRAR = ('com.canonical.AppMenu.Registrar', '/com/canonical/AppMenu/Registrar', 'com.canonical.AppMenu.Registrar') +def log(*args, **kw): + kw['file'] = sys.stderr + print('DBusExport:', *args, **kw) + kw['file'].flush() + class MenuBarAction(QAction): def __init__(self, mb): @@ -92,7 +97,7 @@ class Factory(QObject): self._bus = self.dbus.SessionBus() self._bus.call_on_disconnection(self.bus_disconnected) except Exception as err: - print ('Failed to connect to DBUS session bus, with error:', str(err)) + log('Failed to connect to DBUS session bus, with error:', str(err)) self._bus = False return self._bus or None @@ -106,7 +111,7 @@ class Factory(QObject): self.detect_menu_registrar() except Exception as err: self.menu_registrar = False - print ('Failed to detect window menu registrar, with error:', str(err)) + log('Failed to detect window menu registrar, with error:', str(err)) return bool(self.menu_registrar) def detect_menu_registrar(self):