From 0c3fad73869469da6bf0ef5e94a2a06a616d8f47 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 15:28:43 +0200 Subject: [PATCH 01/11] Add unused add_button method --- qt/aqt/models.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index 13426a306..faf4fd71e 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -72,6 +72,12 @@ class Models(QDialog): f.modelsList.setCurrentRow(0) maybeHideClose(box) + def add_button(self, label: str, func: Callable[Any, None]) -> None: + box = self.form.buttonBox + + button = box.addButton(_(label), QDialogButtonBox.ActionRole) + qconnect(button.clicked, func) + def onRename(self) -> None: nt = self.current_notetype() txt = getText(_("New name:"), default=nt["name"]) From 0d1b90e51254f9724967841d90e51668b62664a2 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 31 Aug 2020 13:35:01 +0200 Subject: [PATCH 02/11] Add gui_hook models_did_init_buttons --- qt/tools/genhooks_gui.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index 7a0abb44f..ce491c294 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -685,9 +685,12 @@ hooks = [ ), # Model ################### + Hook(name="models_advanced_will_show", args=["advanced: QDialog"],), Hook( - name="models_advanced_will_show", - args=["advanced: QDialog"], + name="models_did_init_buttons", + args=["buttons: List[Tuple[str, Callable[[Models], None]]]", "models: Models"], + return_type="buttons: List[Tuple[str, Callable[[Models], None]]]", + doc="""Allows adding buttons to the Model dialog""", ), # Stats ################### From ad27e0149a3f4c9d99226b0a29591cc69a68fb45 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 15:52:02 +0200 Subject: [PATCH 03/11] Add usage in models.py --- qt/aqt/models.py | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index faf4fd71e..e267f08d5 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -2,7 +2,7 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html from operator import itemgetter -from typing import Any, List, Optional, Sequence +from typing import Any, List, Tuple, Callable, Optional, Sequence import aqt.clayout from anki import stdmodels @@ -49,20 +49,29 @@ class Models(QDialog): self.model = None f = self.form box = f.buttonBox - t = QDialogButtonBox.ActionRole - b = box.addButton(_("Add"), t) - qconnect(b.clicked, self.onAdd) - b = box.addButton(_("Rename"), t) - qconnect(b.clicked, self.onRename) - b = box.addButton(_("Delete"), t) - qconnect(b.clicked, self.onDelete) + + default_buttons = [ + ("Add", self.onAdd), + ("Rename", self.onRename), + ("Delete", self.onDelete), + ("Fields...", self.onFields), + ("Cards...", self.onCards), + ("Options...", self.onAdvanced), + ] + if self.fromMain: - b = box.addButton(_("Fields..."), t) - qconnect(b.clicked, self.onFields) - b = box.addButton(_("Cards..."), t) - qconnect(b.clicked, self.onCards) - b = box.addButton(_("Options..."), t) - qconnect(b.clicked, self.onAdvanced) + default_buttons.extends([ + ("Fields...", self.onFields), + ("Cards...", self.onCards), + ]) + + default_buttons.append(("Options...", self.onAdvanced)) + gui_hooks.models_did_init_buttons(default_buttons, self) + + for label, func in buttons: + button = box.addButton(_(label), QDialogButtonBox.ActionRole) + qconnect(button.clicked, func) + qconnect(f.modelsList.itemDoubleClicked, self.onRename) def on_done(fut) -> None: @@ -72,12 +81,6 @@ class Models(QDialog): f.modelsList.setCurrentRow(0) maybeHideClose(box) - def add_button(self, label: str, func: Callable[Any, None]) -> None: - box = self.form.buttonBox - - button = box.addButton(_(label), QDialogButtonBox.ActionRole) - qconnect(button.clicked, func) - def onRename(self) -> None: nt = self.current_notetype() txt = getText(_("New name:"), default=nt["name"]) From 633d769490ed792da531794ca06b4587a70ff156 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 16:57:20 +0200 Subject: [PATCH 04/11] Add compiled hook model_did_init_buttons --- qt/aqt/gui_hooks.py | 50 ++++++++++++++++++++++++++++++++++++++++ qt/tools/genhooks_gui.py | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index fd4b93f4b..6247e0369 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -17,6 +17,7 @@ from anki.hooks import runFilter, runHook from anki.models import NoteType from aqt.qt import QDialog, QEvent, QMenu from aqt.tagedit import TagEdit +from aqt.models import Models # New hook/filter handling ############################################################################## @@ -1869,6 +1870,55 @@ class _ModelsAdvancedWillShowHook: models_advanced_will_show = _ModelsAdvancedWillShowHook() +class _ModelsDidInitButtonsFilter: + """Allows adding buttons to the Model dialog""" + + _hooks: List[ + Callable[ + [List[Tuple[str, Callable[[Models], None]]], Models], + List[Tuple[str, Callable[[Models], None]]], + ] + ] = [] + + def append( + self, + cb: Callable[ + [List[Tuple[str, Callable[[Models], None]]], Models], + List[Tuple[str, Callable[[Models], None]]], + ], + ) -> None: + """(buttons: List[Tuple[str, Callable[[Models], None]]], models: Models)""" + self._hooks.append(cb) + + def remove( + self, + cb: Callable[ + [List[Tuple[str, Callable[[Models], None]]], Models], + List[Tuple[str, Callable[[Models], None]]], + ], + ) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def count(self) -> int: + return len(self._hooks) + + def __call__( + self, buttons: List[Tuple[str, Callable[[Models], None]]], models: Models + ) -> List[Tuple[str, Callable[[Models], None]]]: + for filter in self._hooks: + try: + buttons = filter(buttons, models) + except: + # if the hook fails, remove it + self._hooks.remove(filter) + raise + return buttons + + +models_did_init_buttons = _ModelsDidInitButtonsFilter() + + class _OverviewDidRefreshHook: """Allow to update the overview window. E.g. add the deck name in the title.""" diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index ce491c294..d12f3487d 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -689,7 +689,7 @@ hooks = [ Hook( name="models_did_init_buttons", args=["buttons: List[Tuple[str, Callable[[Models], None]]]", "models: Models"], - return_type="buttons: List[Tuple[str, Callable[[Models], None]]]", + return_type="List[Tuple[str, Callable[[Models], None]]]", doc="""Allows adding buttons to the Model dialog""", ), # Stats From ea787c73a5b24da40d6b329d113d4f77f59af8f7 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 17:10:56 +0200 Subject: [PATCH 05/11] Fix uninitialized buttons object --- qt/aqt/models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index e267f08d5..114657351 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -66,9 +66,8 @@ class Models(QDialog): ]) default_buttons.append(("Options...", self.onAdvanced)) - gui_hooks.models_did_init_buttons(default_buttons, self) - for label, func in buttons: + for label, func in gui_hooks.models_did_init_buttons(default_buttons, self): button = box.addButton(_(label), QDialogButtonBox.ActionRole) qconnect(button.clicked, func) From 3287c42aceaadf007e5c26d2c884cbdbc35ab1a4 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 17:40:01 +0200 Subject: [PATCH 06/11] Don't import models in gui_hooks to avoid circular import --- qt/aqt/gui_hooks.py | 30 ++++++++++++++++++++---------- qt/tools/genhooks_gui.py | 4 ++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index 6247e0369..0e1e82b4b 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -17,7 +17,6 @@ from anki.hooks import runFilter, runHook from anki.models import NoteType from aqt.qt import QDialog, QEvent, QMenu from aqt.tagedit import TagEdit -from aqt.models import Models # New hook/filter handling ############################################################################## @@ -1875,26 +1874,35 @@ class _ModelsDidInitButtonsFilter: _hooks: List[ Callable[ - [List[Tuple[str, Callable[[Models], None]]], Models], - List[Tuple[str, Callable[[Models], None]]], + [ + "List[Tuple[str, Callable[[aqt.models.Models], None]]]", + "aqt.models.Models", + ], + List[Tuple[str, Callable[[aqt.models.Models], None]]], ] ] = [] def append( self, cb: Callable[ - [List[Tuple[str, Callable[[Models], None]]], Models], - List[Tuple[str, Callable[[Models], None]]], + [ + "List[Tuple[str, Callable[[aqt.models.Models], None]]]", + "aqt.models.Models", + ], + List[Tuple[str, Callable[[aqt.models.Models], None]]], ], ) -> None: - """(buttons: List[Tuple[str, Callable[[Models], None]]], models: Models)""" + """(buttons: List[Tuple[str, Callable[[aqt.models.Models], None]]], models: aqt.models.Models)""" self._hooks.append(cb) def remove( self, cb: Callable[ - [List[Tuple[str, Callable[[Models], None]]], Models], - List[Tuple[str, Callable[[Models], None]]], + [ + "List[Tuple[str, Callable[[aqt.models.Models], None]]]", + "aqt.models.Models", + ], + List[Tuple[str, Callable[[aqt.models.Models], None]]], ], ) -> None: if cb in self._hooks: @@ -1904,8 +1912,10 @@ class _ModelsDidInitButtonsFilter: return len(self._hooks) def __call__( - self, buttons: List[Tuple[str, Callable[[Models], None]]], models: Models - ) -> List[Tuple[str, Callable[[Models], None]]]: + self, + buttons: List[Tuple[str, Callable[[aqt.models.Models], None]]], + models: aqt.models.Models, + ) -> List[Tuple[str, Callable[[aqt.models.Models], None]]]: for filter in self._hooks: try: buttons = filter(buttons, models) diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index d12f3487d..9267ff92d 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -688,8 +688,8 @@ hooks = [ Hook(name="models_advanced_will_show", args=["advanced: QDialog"],), Hook( name="models_did_init_buttons", - args=["buttons: List[Tuple[str, Callable[[Models], None]]]", "models: Models"], - return_type="List[Tuple[str, Callable[[Models], None]]]", + args=["buttons: List[Tuple[str, Callable[[aqt.models.Models], None]]]", "models: aqt.models.Models"], + return_type="List[Tuple[str, Callable[[aqt.models.Models], None]]]", doc="""Allows adding buttons to the Model dialog""", ), # Stats From 90f0df2a527bd8378a4cfeda8eefa707555bf903 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 17:44:11 +0200 Subject: [PATCH 07/11] Remove duplicated buttons --- qt/aqt/models.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index 114657351..6af0eefa1 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -54,13 +54,10 @@ class Models(QDialog): ("Add", self.onAdd), ("Rename", self.onRename), ("Delete", self.onDelete), - ("Fields...", self.onFields), - ("Cards...", self.onCards), - ("Options...", self.onAdvanced), ] if self.fromMain: - default_buttons.extends([ + default_buttons.extend([ ("Fields...", self.onFields), ("Cards...", self.onCards), ]) From a1b5acd46a3f93f141d95f3a39c80306d1f9a9ec Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 18:18:11 +0200 Subject: [PATCH 08/11] Fix type signature: models is passed because it's a method --- qt/aqt/gui_hooks.py | 29 +++++++++-------------------- qt/aqt/models.py | 7 ++++--- qt/tools/genhooks_gui.py | 7 +++++-- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/qt/aqt/gui_hooks.py b/qt/aqt/gui_hooks.py index 0e1e82b4b..65b16e5f7 100644 --- a/qt/aqt/gui_hooks.py +++ b/qt/aqt/gui_hooks.py @@ -1874,35 +1874,26 @@ class _ModelsDidInitButtonsFilter: _hooks: List[ Callable[ - [ - "List[Tuple[str, Callable[[aqt.models.Models], None]]]", - "aqt.models.Models", - ], - List[Tuple[str, Callable[[aqt.models.Models], None]]], + [List[Tuple[str, Callable[[], None]]], "aqt.models.Models"], + List[Tuple[str, Callable[[], None]]], ] ] = [] def append( self, cb: Callable[ - [ - "List[Tuple[str, Callable[[aqt.models.Models], None]]]", - "aqt.models.Models", - ], - List[Tuple[str, Callable[[aqt.models.Models], None]]], + [List[Tuple[str, Callable[[], None]]], "aqt.models.Models"], + List[Tuple[str, Callable[[], None]]], ], ) -> None: - """(buttons: List[Tuple[str, Callable[[aqt.models.Models], None]]], models: aqt.models.Models)""" + """(buttons: List[Tuple[str, Callable[[], None]]], models: aqt.models.Models)""" self._hooks.append(cb) def remove( self, cb: Callable[ - [ - "List[Tuple[str, Callable[[aqt.models.Models], None]]]", - "aqt.models.Models", - ], - List[Tuple[str, Callable[[aqt.models.Models], None]]], + [List[Tuple[str, Callable[[], None]]], "aqt.models.Models"], + List[Tuple[str, Callable[[], None]]], ], ) -> None: if cb in self._hooks: @@ -1912,10 +1903,8 @@ class _ModelsDidInitButtonsFilter: return len(self._hooks) def __call__( - self, - buttons: List[Tuple[str, Callable[[aqt.models.Models], None]]], - models: aqt.models.Models, - ) -> List[Tuple[str, Callable[[aqt.models.Models], None]]]: + self, buttons: List[Tuple[str, Callable[[], None]]], models: aqt.models.Models + ) -> List[Tuple[str, Callable[[], None]]]: for filter in self._hooks: try: buttons = filter(buttons, models) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index 6af0eefa1..a4a005ae0 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -54,15 +54,16 @@ class Models(QDialog): ("Add", self.onAdd), ("Rename", self.onRename), ("Delete", self.onDelete), + ("Options...", self.onAdvanced), ] if self.fromMain: - default_buttons.extend([ + from_main_buttons = [ ("Fields...", self.onFields), ("Cards...", self.onCards), - ]) + ] - default_buttons.append(("Options...", self.onAdvanced)) + default_buttons[-1:-1] = from_main_buttons for label, func in gui_hooks.models_did_init_buttons(default_buttons, self): button = box.addButton(_(label), QDialogButtonBox.ActionRole) diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index 9267ff92d..81b69a7e2 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -688,8 +688,11 @@ hooks = [ Hook(name="models_advanced_will_show", args=["advanced: QDialog"],), Hook( name="models_did_init_buttons", - args=["buttons: List[Tuple[str, Callable[[aqt.models.Models], None]]]", "models: aqt.models.Models"], - return_type="List[Tuple[str, Callable[[aqt.models.Models], None]]]", + args=[ + "buttons: List[Tuple[str, Callable[[], None]]]", + "models: aqt.models.Models", + ], + return_type="List[Tuple[str, Callable[[], None]]]", doc="""Allows adding buttons to the Model dialog""", ), # Stats From 89caa6ef7580d47c8da19009a543c4900aa5e956 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 23 Aug 2020 19:05:40 +0200 Subject: [PATCH 09/11] Remove unnecessary import --- qt/aqt/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index a4a005ae0..056d5733c 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -2,7 +2,7 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html from operator import itemgetter -from typing import Any, List, Tuple, Callable, Optional, Sequence +from typing import Any, List, Optional, Sequence import aqt.clayout from anki import stdmodels From 5e4324accb68ca3e449109468c4f55b3d6d95960 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 31 Aug 2020 13:40:42 +0200 Subject: [PATCH 10/11] Address broken translations and increase readibility of button insertion --- qt/aqt/models.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index 056d5733c..00465738f 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -51,22 +51,21 @@ class Models(QDialog): box = f.buttonBox default_buttons = [ - ("Add", self.onAdd), - ("Rename", self.onRename), - ("Delete", self.onDelete), - ("Options...", self.onAdvanced), + (_("Add"), self.onAdd), + (_("Rename"), self.onRename), + (_("Delete"), self.onDelete), ] if self.fromMain: - from_main_buttons = [ - ("Fields...", self.onFields), - ("Cards...", self.onCards), - ] + default_buttons.extend([ + (_("Fields..."), self.onFields), + (_("Cards..."), self.onCards), + ]) - default_buttons[-1:-1] = from_main_buttons + default_buttons.append((_("Options..."), self.onAdvanced)) for label, func in gui_hooks.models_did_init_buttons(default_buttons, self): - button = box.addButton(_(label), QDialogButtonBox.ActionRole) + button = box.addButton(label, QDialogButtonBox.ActionRole) qconnect(button.clicked, func) qconnect(f.modelsList.itemDoubleClicked, self.onRename) From 2f68293c741be09a5beff1d7bbf3fa9941e5f2d2 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 31 Aug 2020 13:50:38 +0200 Subject: [PATCH 11/11] Some minor reformatting to satisfy black --- qt/aqt/models.py | 10 ++++++---- qt/tools/genhooks_gui.py | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index 00465738f..538442e25 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -57,10 +57,12 @@ class Models(QDialog): ] if self.fromMain: - default_buttons.extend([ - (_("Fields..."), self.onFields), - (_("Cards..."), self.onCards), - ]) + default_buttons.extend( + [ + (_("Fields..."), self.onFields), + (_("Cards..."), self.onCards), + ] + ) default_buttons.append((_("Options..."), self.onAdvanced)) diff --git a/qt/tools/genhooks_gui.py b/qt/tools/genhooks_gui.py index 81b69a7e2..1d7b3336b 100644 --- a/qt/tools/genhooks_gui.py +++ b/qt/tools/genhooks_gui.py @@ -685,7 +685,10 @@ hooks = [ ), # Model ################### - Hook(name="models_advanced_will_show", args=["advanced: QDialog"],), + Hook( + name="models_advanced_will_show", + args=["advanced: QDialog"], + ), Hook( name="models_did_init_buttons", args=[