From cd22485f9b0ccde3abd5c7a3cca9f8cfe9e4d276 Mon Sep 17 00:00:00 2001 From: RumovZ Date: Tue, 7 Dec 2021 23:40:48 +0100 Subject: [PATCH] Add browser action to create note copy (#1535) * Add browser action to create note copy * Use new note and copy instead of using source * Change shortcut due to Qt's Alt-Gr bug * Add separate routine for suffixing action with ... * Remove '...' from some translations The convention is to add an ellipsis if more input is required to perform the action. Whether or not the action opens a new window is not decisive. Sources: https://developer.apple.com/design/human-interface-guidelines/macos/menus/menu-anatomy/ https://docs.microsoft.com/en-us/windows/win32/uxguide/cmd-toolbars --- ftl/core/actions.ftl | 4 ++++ ftl/core/browsing.ftl | 2 +- ftl/core/notetypes.ftl | 6 +++--- ftl/qt/qt-accel.ftl | 12 ++++++------ qt/aqt/addcards.py | 14 ++++++++++++++ qt/aqt/browser/browser.py | 9 +++++++++ qt/aqt/forms/browser.ui | 19 ++++++++++++++----- qt/aqt/utils.py | 11 +++++++++++ 8 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ftl/core/actions.ftl b/ftl/core/actions.ftl index bae306621..f2f3bc0b4 100644 --- a/ftl/core/actions.ftl +++ b/ftl/core/actions.ftl @@ -5,6 +5,7 @@ actions-cancel = Cancel actions-choose = Choose actions-close = Close actions-copy = Copy +actions-create-copy = Create Copy actions-custom-study = Custom Study actions-decks = Decks actions-delete = Delete @@ -49,6 +50,9 @@ actions-update-notetype = Update Notetype actions-update-config = Update Config actions-card-info = Card Info actions-previous-card-info = Previous Card Info +# By convention, the name of a menu action is suffixed with "..." if additional +# input is required before it can be performed. E.g. "Export..." vs. "Delete". +actions-with-ellipsis = { $action }... ## Flags diff --git a/ftl/core/browsing.ftl b/ftl/core/browsing.ftl index 5ffc76973..5ac5597ec 100644 --- a/ftl/core/browsing.ftl +++ b/ftl/core/browsing.ftl @@ -51,7 +51,7 @@ browsing-interval = Interval browsing-last-card = Last Card browsing-learning = (learning) browsing-line-size = Line Size: -browsing-manage-note-types = Manage Note Types... +browsing-manage-note-types = Manage Note Types browsing-move-cards = Move Cards browsing-move-cards-to-deck = Move cards to deck: browsing-new = (new) diff --git a/ftl/core/notetypes.ftl b/ftl/core/notetypes.ftl index 5e993c0c2..6bcea398b 100644 --- a/ftl/core/notetypes.ftl +++ b/ftl/core/notetypes.ftl @@ -20,16 +20,16 @@ notetypes-card-1-name = Card 1 notetypes-card-2-name = Card 2 notetypes-add = Add: { $val } notetypes-add-note-type = Add Note Type -notetypes-cards = Cards... +notetypes-cards = Cards notetypes-clone = Clone: { $val } notetypes-copy = { $val } copy notetypes-create-scalable-images-with-dvisvgm = Create scalable images with dvisvgm notetypes-delete-this-note-type-and-all = Delete this note type and all its cards? notetypes-delete-this-unused-note-type = Delete this unused note type? -notetypes-fields = Fields... +notetypes-fields = Fields notetypes-footer = Footer notetypes-header = Header notetypes-note-types = Note Types -notetypes-options = Options... +notetypes-options = Options notetypes-please-add-another-note-type-first = Please add another note type first. notetypes-type = Type diff --git a/ftl/qt/qt-accel.ftl b/ftl/qt/qt-accel.ftl index e2ac4ae80..b34371101 100644 --- a/ftl/qt/qt-accel.ftl +++ b/ftl/qt/qt-accel.ftl @@ -1,8 +1,8 @@ -qt-accel-about = &About... +qt-accel-about = &About qt-accel-browse-and-install = &Browse and Install... qt-accel-cards = &Cards qt-accel-check-database = &Check Database -qt-accel-check-media = Check &Media... +qt-accel-check-media = Check &Media qt-accel-edit = &Edit qt-accel-exit = E&xit qt-accel-export = &Export... @@ -13,7 +13,7 @@ qt-accel-find = &Find qt-accel-find-and-replace = Find and Re&place... qt-accel-find-duplicates = Find &Duplicates... qt-accel-go = &Go -qt-accel-guide = &Guide... +qt-accel-guide = &Guide qt-accel-help = &Help qt-accel-import = &Import... qt-accel-info = &Info... @@ -21,12 +21,12 @@ qt-accel-invert-selection = &Invert Selection qt-accel-next-card = &Next Card qt-accel-note = N&ote qt-accel-notes = &Notes -qt-accel-open-addons-folder = &Open Add-ons Folder... -qt-accel-preferences = &Preferences... +qt-accel-open-addons-folder = &Open Add-ons Folder +qt-accel-preferences = &Preferences qt-accel-previous-card = &Previous Card qt-accel-select-all = Select &All qt-accel-select-notes = Select &Notes -qt-accel-support-anki = &Support Anki... +qt-accel-support-anki = &Support Anki qt-accel-switch-profile = &Switch Profile qt-accel-tools = &Tools qt-accel-undo = &Undo diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py index 68e1e97af..07b4d2e74 100644 --- a/qt/aqt/addcards.py +++ b/qt/aqt/addcards.py @@ -54,6 +54,20 @@ class AddCards(QMainWindow): gui_hooks.add_cards_did_init(self) self.show() + def set_note(self, note: Note) -> None: + """Set tags, field contents and notetype (and its deck) + according to `note`. + """ + self.notetype_chooser.selected_notetype_id = note.mid + if deck_id := self.col.default_deck_for_notetype(note.mid): + self.deck_chooser.selected_deck_id = deck_id + + new_note = self._new_note() + new_note.fields = note.fields + new_note.tags = note.tags + + self.setAndFocusNote(new_note) + def setupEditor(self) -> None: self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self, True) self.editor.web.eval("noteEditorPromise.then(() => activateStickyShortcuts());") diff --git a/qt/aqt/browser/browser.py b/qt/aqt/browser/browser.py index 1a02ce220..9eda5ed52 100644 --- a/qt/aqt/browser/browser.py +++ b/qt/aqt/browser/browser.py @@ -40,6 +40,7 @@ from aqt.undo import UndoActionsInfo from aqt.utils import ( HelpPage, KeyboardModifiersPressed, + add_ellipsis_to_action_label, current_window, ensure_editor_saved, getTag, @@ -183,6 +184,7 @@ class Browser(QMainWindow): f.actionCreateFilteredDeck.setShortcuts(["Ctrl+G", "Ctrl+Alt+G"]) # notes qconnect(f.actionAdd.triggered, self.mw.onAddCard) + qconnect(f.actionCopy.triggered, self.on_create_copy) qconnect(f.actionAdd_Tags.triggered, self.add_tags_to_selected_notes) qconnect(f.actionRemove_Tags.triggered, self.remove_tags_from_selected_notes) qconnect(f.actionClear_Unused_Tags.triggered, self.clear_unused_tags) @@ -229,6 +231,8 @@ class Browser(QMainWindow): gui_hooks.browser_menus_did_init(self) self.mw.maybeHideAccelerators(self) + add_ellipsis_to_action_label(f.actionCopy) + def closeEvent(self, evt: QCloseEvent) -> None: if self._closeEventHasCleanedUp: evt.accept() @@ -479,6 +483,7 @@ class Browser(QMainWindow): self._update_flags_menu() self._update_toggle_mark_action() self._update_toggle_suspend_action() + self.form.actionCopy.setEnabled(self.table.has_current()) self.form.action_Info.setEnabled(self.table.has_current()) self.form.actionPreviousCard.setEnabled(self.table.has_previous()) self.form.actionNextCard.setEnabled(self.table.has_next()) @@ -582,6 +587,10 @@ class Browser(QMainWindow): # Misc menu options ###################################################################### + def on_create_copy(self) -> None: + if note := self.table.get_current_note(): + aqt.dialogs.open("AddCards", self.mw).set_note(note) + @no_arg_trigger @skip_if_selection_is_empty @ensure_editor_saved diff --git a/qt/aqt/forms/browser.ui b/qt/aqt/forms/browser.ui index 0012b346b..00bb16d03 100644 --- a/qt/aqt/forms/browser.ui +++ b/qt/aqt/forms/browser.ui @@ -17,7 +17,7 @@ - + :/icons/anki.png:/icons/anki.png @@ -144,12 +144,12 @@ false - - false - 20 + + false + true @@ -209,7 +209,7 @@ 0 0 750 - 21 + 22 @@ -283,6 +283,7 @@ qt_accel_notes + @@ -661,6 +662,14 @@ Ctrl+7 + + + actions_create_copy + + + Ctrl+Shift+C + + diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py index f64f72f21..409177b8c 100644 --- a/qt/aqt/utils.py +++ b/qt/aqt/utils.py @@ -847,6 +847,17 @@ def qtMenuShortcutWorkaround(qmenu: QMenu) -> None: ###################################################################### +def add_ellipsis_to_action_label(*actions: QAction) -> None: + """Pass actions to add '...' to their labels, indicating that more input is + required before they can be performed. + + This approach is used so that the same fluent translations can be used on + mobile, where the '...' convention does not exist. + """ + for action in actions: + action.setText(tr.actions_with_ellipsis(action=action.text())) + + def supportText() -> str: import platform import time