mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
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
This commit is contained in:
parent
bcea43dc6a
commit
cd22485f9b
8 changed files with 62 additions and 15 deletions
|
@ -5,6 +5,7 @@ actions-cancel = Cancel
|
||||||
actions-choose = Choose
|
actions-choose = Choose
|
||||||
actions-close = Close
|
actions-close = Close
|
||||||
actions-copy = Copy
|
actions-copy = Copy
|
||||||
|
actions-create-copy = Create Copy
|
||||||
actions-custom-study = Custom Study
|
actions-custom-study = Custom Study
|
||||||
actions-decks = Decks
|
actions-decks = Decks
|
||||||
actions-delete = Delete
|
actions-delete = Delete
|
||||||
|
@ -49,6 +50,9 @@ actions-update-notetype = Update Notetype
|
||||||
actions-update-config = Update Config
|
actions-update-config = Update Config
|
||||||
actions-card-info = Card Info
|
actions-card-info = Card Info
|
||||||
actions-previous-card-info = Previous 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
|
## Flags
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ browsing-interval = Interval
|
||||||
browsing-last-card = Last Card
|
browsing-last-card = Last Card
|
||||||
browsing-learning = (learning)
|
browsing-learning = (learning)
|
||||||
browsing-line-size = <b>Line Size</b>:
|
browsing-line-size = <b>Line Size</b>:
|
||||||
browsing-manage-note-types = Manage Note Types...
|
browsing-manage-note-types = Manage Note Types
|
||||||
browsing-move-cards = Move Cards
|
browsing-move-cards = Move Cards
|
||||||
browsing-move-cards-to-deck = Move cards to deck:
|
browsing-move-cards-to-deck = Move cards to deck:
|
||||||
browsing-new = (new)
|
browsing-new = (new)
|
||||||
|
|
|
@ -20,16 +20,16 @@ notetypes-card-1-name = Card 1
|
||||||
notetypes-card-2-name = Card 2
|
notetypes-card-2-name = Card 2
|
||||||
notetypes-add = Add: { $val }
|
notetypes-add = Add: { $val }
|
||||||
notetypes-add-note-type = Add Note Type
|
notetypes-add-note-type = Add Note Type
|
||||||
notetypes-cards = Cards...
|
notetypes-cards = Cards
|
||||||
notetypes-clone = Clone: { $val }
|
notetypes-clone = Clone: { $val }
|
||||||
notetypes-copy = { $val } copy
|
notetypes-copy = { $val } copy
|
||||||
notetypes-create-scalable-images-with-dvisvgm = Create scalable images with dvisvgm
|
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-note-type-and-all = Delete this note type and all its cards?
|
||||||
notetypes-delete-this-unused-note-type = Delete this unused note type?
|
notetypes-delete-this-unused-note-type = Delete this unused note type?
|
||||||
notetypes-fields = Fields...
|
notetypes-fields = Fields
|
||||||
notetypes-footer = Footer
|
notetypes-footer = Footer
|
||||||
notetypes-header = Header
|
notetypes-header = Header
|
||||||
notetypes-note-types = Note Types
|
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-please-add-another-note-type-first = Please add another note type first.
|
||||||
notetypes-type = Type
|
notetypes-type = Type
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
qt-accel-about = &About...
|
qt-accel-about = &About
|
||||||
qt-accel-browse-and-install = &Browse and Install...
|
qt-accel-browse-and-install = &Browse and Install...
|
||||||
qt-accel-cards = &Cards
|
qt-accel-cards = &Cards
|
||||||
qt-accel-check-database = &Check Database
|
qt-accel-check-database = &Check Database
|
||||||
qt-accel-check-media = Check &Media...
|
qt-accel-check-media = Check &Media
|
||||||
qt-accel-edit = &Edit
|
qt-accel-edit = &Edit
|
||||||
qt-accel-exit = E&xit
|
qt-accel-exit = E&xit
|
||||||
qt-accel-export = &Export...
|
qt-accel-export = &Export...
|
||||||
|
@ -13,7 +13,7 @@ qt-accel-find = &Find
|
||||||
qt-accel-find-and-replace = Find and Re&place...
|
qt-accel-find-and-replace = Find and Re&place...
|
||||||
qt-accel-find-duplicates = Find &Duplicates...
|
qt-accel-find-duplicates = Find &Duplicates...
|
||||||
qt-accel-go = &Go
|
qt-accel-go = &Go
|
||||||
qt-accel-guide = &Guide...
|
qt-accel-guide = &Guide
|
||||||
qt-accel-help = &Help
|
qt-accel-help = &Help
|
||||||
qt-accel-import = &Import...
|
qt-accel-import = &Import...
|
||||||
qt-accel-info = &Info...
|
qt-accel-info = &Info...
|
||||||
|
@ -21,12 +21,12 @@ qt-accel-invert-selection = &Invert Selection
|
||||||
qt-accel-next-card = &Next Card
|
qt-accel-next-card = &Next Card
|
||||||
qt-accel-note = N&ote
|
qt-accel-note = N&ote
|
||||||
qt-accel-notes = &Notes
|
qt-accel-notes = &Notes
|
||||||
qt-accel-open-addons-folder = &Open Add-ons Folder...
|
qt-accel-open-addons-folder = &Open Add-ons Folder
|
||||||
qt-accel-preferences = &Preferences...
|
qt-accel-preferences = &Preferences
|
||||||
qt-accel-previous-card = &Previous Card
|
qt-accel-previous-card = &Previous Card
|
||||||
qt-accel-select-all = Select &All
|
qt-accel-select-all = Select &All
|
||||||
qt-accel-select-notes = Select &Notes
|
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-switch-profile = &Switch Profile
|
||||||
qt-accel-tools = &Tools
|
qt-accel-tools = &Tools
|
||||||
qt-accel-undo = &Undo
|
qt-accel-undo = &Undo
|
||||||
|
|
|
@ -54,6 +54,20 @@ class AddCards(QMainWindow):
|
||||||
gui_hooks.add_cards_did_init(self)
|
gui_hooks.add_cards_did_init(self)
|
||||||
self.show()
|
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:
|
def setupEditor(self) -> None:
|
||||||
self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self, True)
|
self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self, True)
|
||||||
self.editor.web.eval("noteEditorPromise.then(() => activateStickyShortcuts());")
|
self.editor.web.eval("noteEditorPromise.then(() => activateStickyShortcuts());")
|
||||||
|
|
|
@ -40,6 +40,7 @@ from aqt.undo import UndoActionsInfo
|
||||||
from aqt.utils import (
|
from aqt.utils import (
|
||||||
HelpPage,
|
HelpPage,
|
||||||
KeyboardModifiersPressed,
|
KeyboardModifiersPressed,
|
||||||
|
add_ellipsis_to_action_label,
|
||||||
current_window,
|
current_window,
|
||||||
ensure_editor_saved,
|
ensure_editor_saved,
|
||||||
getTag,
|
getTag,
|
||||||
|
@ -183,6 +184,7 @@ class Browser(QMainWindow):
|
||||||
f.actionCreateFilteredDeck.setShortcuts(["Ctrl+G", "Ctrl+Alt+G"])
|
f.actionCreateFilteredDeck.setShortcuts(["Ctrl+G", "Ctrl+Alt+G"])
|
||||||
# notes
|
# notes
|
||||||
qconnect(f.actionAdd.triggered, self.mw.onAddCard)
|
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.actionAdd_Tags.triggered, self.add_tags_to_selected_notes)
|
||||||
qconnect(f.actionRemove_Tags.triggered, self.remove_tags_from_selected_notes)
|
qconnect(f.actionRemove_Tags.triggered, self.remove_tags_from_selected_notes)
|
||||||
qconnect(f.actionClear_Unused_Tags.triggered, self.clear_unused_tags)
|
qconnect(f.actionClear_Unused_Tags.triggered, self.clear_unused_tags)
|
||||||
|
@ -229,6 +231,8 @@ class Browser(QMainWindow):
|
||||||
gui_hooks.browser_menus_did_init(self)
|
gui_hooks.browser_menus_did_init(self)
|
||||||
self.mw.maybeHideAccelerators(self)
|
self.mw.maybeHideAccelerators(self)
|
||||||
|
|
||||||
|
add_ellipsis_to_action_label(f.actionCopy)
|
||||||
|
|
||||||
def closeEvent(self, evt: QCloseEvent) -> None:
|
def closeEvent(self, evt: QCloseEvent) -> None:
|
||||||
if self._closeEventHasCleanedUp:
|
if self._closeEventHasCleanedUp:
|
||||||
evt.accept()
|
evt.accept()
|
||||||
|
@ -479,6 +483,7 @@ class Browser(QMainWindow):
|
||||||
self._update_flags_menu()
|
self._update_flags_menu()
|
||||||
self._update_toggle_mark_action()
|
self._update_toggle_mark_action()
|
||||||
self._update_toggle_suspend_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.action_Info.setEnabled(self.table.has_current())
|
||||||
self.form.actionPreviousCard.setEnabled(self.table.has_previous())
|
self.form.actionPreviousCard.setEnabled(self.table.has_previous())
|
||||||
self.form.actionNextCard.setEnabled(self.table.has_next())
|
self.form.actionNextCard.setEnabled(self.table.has_next())
|
||||||
|
@ -582,6 +587,10 @@ class Browser(QMainWindow):
|
||||||
# Misc menu options
|
# 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
|
@no_arg_trigger
|
||||||
@skip_if_selection_is_empty
|
@skip_if_selection_is_empty
|
||||||
@ensure_editor_saved
|
@ensure_editor_saved
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/anki.png</normaloff>:/icons/anki.png</iconset>
|
<normaloff>:/icons/anki.png</normaloff>:/icons/anki.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
@ -144,12 +144,12 @@
|
||||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="horizontalHeaderHighlightSections">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||||
<number>20</number>
|
<number>20</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderHighlightSections">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
@ -209,7 +209,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>750</width>
|
<width>750</width>
|
||||||
<height>21</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuEdit">
|
<widget class="QMenu" name="menuEdit">
|
||||||
|
@ -283,6 +283,7 @@
|
||||||
<string>qt_accel_notes</string>
|
<string>qt_accel_notes</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionAdd"/>
|
<addaction name="actionAdd"/>
|
||||||
|
<addaction name="actionCopy"/>
|
||||||
<addaction name="actionExport"/>
|
<addaction name="actionExport"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionAdd_Tags"/>
|
<addaction name="actionAdd_Tags"/>
|
||||||
|
@ -661,6 +662,14 @@
|
||||||
<string notr="true">Ctrl+7</string>
|
<string notr="true">Ctrl+7</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionCopy">
|
||||||
|
<property name="text">
|
||||||
|
<string>actions_create_copy</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Ctrl+Shift+C</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="icons.qrc"/>
|
<include location="icons.qrc"/>
|
||||||
|
|
|
@ -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:
|
def supportText() -> str:
|
||||||
import platform
|
import platform
|
||||||
import time
|
import time
|
||||||
|
|
Loading…
Reference in a new issue