From 6ceb84e70133e6efa4be726ce2b09f0f54105460 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 27 Dec 2016 08:45:37 +0530 Subject: [PATCH] OS X: Fix dynamically generated context menus, such as the sort by menu not working: Fixes #1652694 [Empty Sort By List in Cover Grid Context Menu](https://bugs.launchpad.net/calibre/+bug/1652694) --- src/calibre/gui2/actions/sort.py | 3 +-- src/calibre/gui2/bars.py | 27 +++++++++++++++------ src/calibre/gui2/library/alternate_views.py | 4 --- src/calibre/gui2/library/views.py | 4 --- src/calibre/gui2/main_window.py | 1 + 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/calibre/gui2/actions/sort.py b/src/calibre/gui2/actions/sort.py index fc2467cd13..cc766486dd 100644 --- a/src/calibre/gui2/actions/sort.py +++ b/src/calibre/gui2/actions/sort.py @@ -38,6 +38,7 @@ class SortByAction(InterfaceAction): def genesis(self): self.sorted_icon = QIcon(I('ok.png')) + self.qaction.menu().aboutToShow.connect(self.update_menu) def location_selected(self, loc): self.qaction.setEnabled(loc == 'library') @@ -76,5 +77,3 @@ class SortByAction(InterfaceAction): self.gui.library_view.intelligent_sort(key, True) else: self.gui.library_view.sort_by_named_field(key, ascending) - - diff --git a/src/calibre/gui2/bars.py b/src/calibre/gui2/bars.py index 6713c1ba41..c9a888425f 100644 --- a/src/calibre/gui2/bars.py +++ b/src/calibre/gui2/bars.py @@ -253,6 +253,7 @@ class MenuAction(QAction): # {{{ # MenuBar {{{ + if isosx: # On OS X we need special handling for the application global menu bar and # the context menus, since Qt does not handle dynamic menus or menus in @@ -273,6 +274,15 @@ if isosx: self.clone_changed() self.triggered.connect(self.do_trigger) + def clone_menu(self): + m = self.menu() + m.clear() + for ac in QMenu.actions(self.clone.menu()): + if ac.isSeparator(): + m.addSeparator() + else: + m.addAction(CloneAction(ac, self.parent(), clone_shortcuts=self.clone_shortcuts)) + def clone_changed(self): otext = self.text() self.setText(self.clone.text()) @@ -293,12 +303,17 @@ if isosx: self.setMenu(None) else: m = QMenu(self.text(), self.parent()) - for ac in QMenu.actions(self.clone.menu()): - if ac.isSeparator(): - m.addSeparator() - else: - m.addAction(CloneAction(ac, self.parent(), clone_shortcuts=self.clone_shortcuts)) + m.aboutToShow.connect(self.about_to_show) self.setMenu(m) + self.clone_menu() + + def about_to_show(self): + cm = self.clone.menu() + before = list(QMenu.actions(cm)) + cm.aboutToShow.emit() + after = list(QMenu.actions(cm)) + if before != after: + self.clone_menu() def do_trigger(self, checked=False): if not sip.isdeleted(self.clone): @@ -553,5 +568,3 @@ class BarsManager(QObject): bar.setToolButtonStyle(style) self.donate_button.setIconSize(bar.iconSize()) self.donate_button.setToolButtonStyle(style) - - diff --git a/src/calibre/gui2/library/alternate_views.py b/src/calibre/gui2/library/alternate_views.py index 7cc37fec29..8bf14ef50b 100644 --- a/src/calibre/gui2/library/alternate_views.py +++ b/src/calibre/gui2/library/alternate_views.py @@ -932,10 +932,6 @@ class GridView(QListView): if self.context_menu is None: return from calibre.gui2.main_window import clone_menu - sac = self.gui.iactions['Sort By'] - sort_added = tuple(ac for ac in self.context_menu.actions() if ac is sac.qaction) - if sort_added: - sac.update_menu() m = clone_menu(self.context_menu) if islinux else self.context_menu m.popup(event.globalPos()) event.accept() diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index 12fe79b9a4..c8a8b58d89 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -840,10 +840,6 @@ class BooksView(QTableView): # {{{ def contextMenuEvent(self, event): from calibre.gui2.main_window import clone_menu - sac = self.gui.iactions['Sort By'] - sort_added = tuple(ac for ac in self.context_menu.actions() if ac is sac.qaction) - if sort_added: - sac.update_menu() m = clone_menu(self.context_menu) if islinux else self.context_menu m.popup(event.globalPos()) event.accept() diff --git a/src/calibre/gui2/main_window.py b/src/calibre/gui2/main_window.py index 9723a05145..7f5d94de94 100644 --- a/src/calibre/gui2/main_window.py +++ b/src/calibre/gui2/main_window.py @@ -170,6 +170,7 @@ def clone_menu(menu): # This is needed to workaround a bug in Qt 5.5+ and Unity. When the same # QAction object is used in both a QMenuBar and a QMenu, sub-menus of the # QMenu flicker when rendered under Unity. + def clone_action(ac, parent): if ac.isSeparator(): ans = QAction(parent)