Commit Graph

2288 Commits

Author SHA1 Message Date
Arthur Milchior
7ea862931c NF: NoteTypeID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
6ac1e6477e NF: DeckID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
b8f715ffea NF: default_deck_id as a constant
Otherwise it's not clear what this 1 represents
2021-03-26 11:14:08 +10:00
Arthur Milchior
3b6802530d NF: currentDeckID factorize odid or did 2021-03-26 11:14:08 +10:00
Arthur Milchior
986efeed19 NF: CardID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
6ac540927a NF: NoteID type 2021-03-26 11:14:08 +10:00
Damien Elmes
e34412a4b2
Merge pull request #1090 from glutanimate/filtered-deck-dialog-hooks
Add hooks to the filtered deck dialog
2021-03-26 10:28:23 +10:00
Damien Elmes
9aece2a7b8 rework translation handling
Instead of generating a fluent.proto file with a giant enum, create
a .json file representing the translations that downstream consumers
can use for code generation.

This enables the generation of a separate method for each translation,
with a docstring that shows the actual text, and any required arguments
listed in the function signature.

The codebase is still using the old enum for now; updating it will need
to come in future commits, and the old enum will need to be kept
around, as add-ons are referencing it.

Other changes:

- move translation code into a separate crate
- store the translations on a per-file/module basis, which will allow
us to avoid sending 1000+ strings on each JS page load in the future
- drop the undocumented support for external .ftl files, that we weren't
using
- duplicate strings in translation files are now checked for at build
time
- fix i18n test failing when run outside Bazel
- drop slog dependency in i18n module
2021-03-26 09:41:32 +10:00
Glutanimate
6a1c85d62e Run isort 2021-03-25 04:46:22 +01:00
Glutanimate
feaa32b751 Supply deck ID in hook, so that add-ons may update deck config dict
(for newly created filtered decks where the deck ID is not yet set
in the FilteredDeckForUpdate object)
2021-03-25 02:33:15 +01:00
Glutanimate
e9b18c14f2 Fix (?) operation output type hint 2021-03-25 02:28:58 +01:00
Glutanimate
713c8f619d Add three filtered deck dialog hooks
Similar to deckconf hooks
2021-03-25 02:28:01 +01:00
Damien Elmes
4b5944f181 move markdown dep into pylib 2021-03-24 22:19:14 +10:00
Damien Elmes
d382b33585 rework filtered deck screen & search errors
- Filtered deck creation now happens as an atomic operation, and is
undoable.
- The logic for initial search text, normalizing searches and so on
has been pushed into the backend.
- Use protobuf to pass the filtered deck to the updated dialog, so
we don't need to deal with untyped JSON.
- Change the "revise your search?" prompt to be a simple info box -
user has access to cancel and build buttons, and doesn't need a separate
prompt. Tweak the wording so the 'show excluded' button should be more
obvious.
- Filtered decks have a time appended to them instead of a number,
primarily because it's easier to implement. No objections going back to
the old behaviour if someone wants to contribute a clean patch.
The standard de-duplication will happen if two decks are created in the
same minute with the same name.
- Tweak the default sort order, and start with two searches. The UI
will still hide the second search by default, but by starting with two,
the frontend doesn't need logic for creating the starting text.
- Search errors now have their own error type, instead of using
InvalidInput, as that was intended mainly for bad API calls. The markdown
conversion is done when the error is converted from the backend, allowing
errors to printed as a string without any special handling by the calling
code.

TODO: when building a new filtered deck, update_active() is clobbering
the undo log when the overview is refreshed
2021-03-24 22:04:35 +10:00
Damien Elmes
181cda1979 rename&simplify the deck/config type aliases
- QueueConfig is only used by the scheduler
- DeckConfig was being used in places that Config should have been used
- Add "Dict" to the name so that the bare name is free for use with a
stronger type.
2021-03-24 16:29:02 +10:00
Damien Elmes
5a1b00b6e6 dyndeckconf -> filtered_deck 2021-03-24 13:17:12 +10:00
Damien Elmes
12597e1094 support undo of filtered deck build/empty 2021-03-24 12:56:06 +10:00
RumovZ
76b4b7f6b1 Add context action 'Update with Current Search' 2021-03-23 11:20:46 +01:00
Damien Elmes
5d67265658 tweak AbortAddonImport docstring 2021-03-23 19:31:24 +10:00
Damien Elmes
2d48479f4f
Merge pull request #1086 from glutanimate/abort-addon-import-exception
Add an exception that allows add-ons to abort early
2021-03-23 19:28:13 +10:00
Damien Elmes
3199dcb54d add hook to modify browser row content 2021-03-23 19:13:52 +10:00
Damien Elmes
9c456dd7b0 only declare rows deleted if they're the result of a NotFound error
If it's some other error like the DB suddenly becoming accessible,
we don't want to scare the user into thinking their data was deleted,
and we want to know what the error was without popping up tens of
message boxes for each row.
2021-03-23 19:04:15 +10:00
Damien Elmes
5fd79d9246
Merge pull request #1082 from RumovZ/backend-rows
Backend rows
2021-03-23 18:31:42 +10:00
Glutanimate
fa6a0a1283 Add an exception that allows add-ons to abort early 2021-03-22 14:53:04 +01:00
Damien Elmes
84b0c8ba88 switch DeckID to a NewType
Not sure at this point whether this will buy us much in the Python
codebase over a simple int alias, but let's give it a go.
2021-03-22 23:43:54 +10:00
Damien Elmes
01161c8ed2 use perform_op() for deck creation 2021-03-22 23:17:07 +10:00
Damien Elmes
0123a382ec deck rename with perform_op() 2021-03-22 20:38:51 +10:00
RumovZ
a6fb72780a Show tooltip on browser cells
Oftentimes, a cell's text is too long to be fully displayed inside the
table, so show it as a tooltip.
2021-03-22 09:31:07 +01:00
Damien Elmes
6a11c0398c use perform_op() for deck drag&drop 2021-03-22 18:23:56 +10:00
Damien Elmes
b1f4ea562a remove the default question fade
Fading was primarily motivated by wanting to prevent ugly redraw,
but we wait for both MathJax and images now.
2021-03-22 12:11:00 +10:00
Damien Elmes
c3145977f0 delay scrolling to answer until images load 2021-03-22 12:05:18 +10:00
Damien Elmes
87801668e9 fix .csv import not using faster QPlainTextEdit 2021-03-22 11:26:49 +10:00
Damien Elmes
ba1742aee2 fix text not appearing after .apkg import 2021-03-22 11:24:53 +10:00
Damien Elmes
1a7562e554 fix profile dumping on platforms other than Macs
https://github.com/ankitects/anki/pull/1082#issuecomment-803660818
2021-03-22 09:44:06 +10:00
RumovZ
a27308dc9c Readd browser.model.getCard()
Actually, the new model has no truck with card objects, but since it may
hold an invalid id, it takes responsibility for catching the exception.
2021-03-21 18:44:31 +01:00
Damien Elmes
7d8f19e6e4 merge in Henrik's TS/Svelte refactor with some changes
- The previous commits moved the majority of the remaining global css
into components; move the remaining @emotion/css references into
ticks.scss and the styling of the Graph.svelte. This is not as elegant
as the emotion solution, but builds a whole lot faster, and most of
our styling can be scoped to a component anyway.
- Leave the .html files in ts/ for now. AnkiMobile uses them, and
AnkiDroid likely will in the future too. In the long run we'll likely
move to loading the JS into an existing page instead of loading a
separate page, but at that point we can just exclude the .html file from
copy_files_into_group() without affecting other clients.

Closes #1074
2021-03-21 23:01:18 +10:00
Damien Elmes
a581c082f6 switch from rollup to esbuild
brings the 2+ second bundle on a module like the graphs down to 90ms
2021-03-21 16:06:36 +10:00
RumovZ
a5be72742c Add BrowserRow to ignored classes 2021-03-20 16:06:26 +01:00
RumovZ
922fccee58 Use backend rows in browser.py 2021-03-20 12:03:26 +01:00
Damien Elmes
4c61c92806 speed up tag drag&drop and finish tag tidyup
approx 4x speedup when reparenting 10-15 tags and their children at once
2021-03-19 19:45:21 +10:00
Damien Elmes
9c2bff5b6d change bulk_update() into find_and_replace_tag()
Now behaves the same way as standard find&replace:
- Will match substrings
- Regexs can be used to match multiple items; we no longer split
input on spaces.
- The find&replace dialog has been updated to add tags to the field
list.
2021-03-19 19:45:21 +10:00
Damien Elmes
08895c58d9 introduce separate routine to remove tags from specific notes
We were (ab)using the bulk update routine to do deletions, but that
code was really intended to be used for finding&replacing, where an
exact match is not a requirement.
2021-03-19 19:45:21 +10:00
Damien Elmes
05876f1299 cache card list cell content
Qt is pretty enthusiastic about redrawing the card list when any sort
of activity occurs, and by serving blank cells while the DB was busy,
we were getting ugly flashes, and cells getting stuck blank.

Resolve the issue by calculating a row up front and caching it, then
serving stale content when updates are blocked.
2021-03-19 19:45:21 +10:00
Damien Elmes
09076da937 make tag deletion undoable, and speed it up
- ~4x faster than before on tag tree with 30k notes
- remove the separate clear_tag() backend method
2021-03-19 19:45:21 +10:00
Damien Elmes
157b74b671 make tag renaming undoable, and speed it up
~3x speedup when renaming a tag that's on 25k notes
2021-03-19 19:45:21 +10:00
Damien Elmes
2d8e45b6da tidy up flag/mark code 2021-03-19 19:45:21 +10:00
Damien Elmes
0331d8b588 make reposition undoable 2021-03-19 19:45:21 +10:00
Damien Elmes
846e7cd4aa tweak hook names 2021-03-19 19:45:21 +10:00
Damien Elmes
de668441b5 clear_unused_tags and browser redraw improvements
- clear_unused_tags() is now undoable, and returns the number of removed
notes
- add a new mw.query_op() helper for immutable queries
- decouple "freeze/unfreeze ui state" hooks from the "interface update
required" hook, so that the former is fired even on error, and can be
made re-entrant
- use a 'block_updates' flag in Python, instead of setUpdatesEnabled(),
as the latter has the side-effect of preventing child windows like
tooltips from appearing, and forces a full redrawn when updates are
enabled again. The new behaviour leads to the card list blanking out
when a long-running op is running, but in the future if we cache the
cell values we can just display them from the cache instead.
- we were indiscriminately saving the note with saveNow(), due to the
call to saveTags(). Changed so that it only saves when the tags field
is focused.
- drain the "on_done" queue on main before launching a new background
task, to lower the chances of something in on_done making a small query
to the DB and hanging until a long op finishes
- the duplicate check in the editor was executed after the webview loads,
leading to it hanging until the sidebar finishes loading. Run it at
set_note() time instead, so that the editor loads first.
- don't throw an error when a long-running op started with with_progress()
finishes after the window it was launched from has closed
- don't throw an error when the browser is closed before the sidebar
has finished loading
2021-03-19 19:45:21 +10:00
Damien Elmes
7d6fd48a6f fix mypy treating Qt objects as inheriting from Any
Before this change, mypy would fail to catch mistakes like
mw.does_not_exist(). Also fix a couple of bugs this has uncovered.
2021-03-19 19:45:21 +10:00
Damien Elmes
0c59c8b591 fix a bunch of qt typing issues uncovered by the following commit 2021-03-19 19:45:21 +10:00
Damien Elmes
75a0f165c6 fix opening the browser in an empty collection case
_onRowChanged() no longer exists, and super-frustratingly mypy doesn't
seem to notice references to missing properties on mw or mw.browser
2021-03-19 19:45:21 +10:00
Damien Elmes
f71446ddf5 decorator for saveNow(), mkII
Mostly @RumovZ's work from https://github.com/ankitects/anki/pull/1066,
with a workaround for the issue encountered on
6e0e17b2b9

Fix is to use pyqtSlot() to specify the slot signature, as described
on https://stackoverflow.com/questions/44371451/python-pyqt-qt-qmenu-qaction-syntax

Also renamed saveNow() for PEP8, but have not updated all the existing
calls to use the decorator yet - might be easiest to do at the same time
as perform_op() calls are added.
2021-03-19 19:45:21 +10:00
Damien Elmes
71456b0825 remove the processEvents() call in progress window
Relic from when we were processing UI events via the sqlite progress
handler.
2021-03-19 19:45:21 +10:00
Damien Elmes
949584d3fa don't show busy cursor immediately
Setting it straight away causes the cursor to flash on quick operations,
like saving the current note. Delay it for 300ms, which should hopefully
be long enough to not get in the way, but short enough to give indication
that long-running requests are being processed.
2021-03-19 19:45:21 +10:00
Damien Elmes
7171a24e16 redraw sidebar in response to perform_op() changes 2021-03-19 19:45:21 +10:00
Damien Elmes
017005a4f8 various redraw fixes
- need to drop cardObjs cache when updating cells
- stop listening on editor_did_* hooks. unfocus_field and typing_timer
are covered by operation_did_execute on note save already, and the
user potentially has editors open in other windows as well
- distinguish between card queue refresh and note text redraw in review
screen again
- update preview window when note updated
- defer setUpdatesEnabled(True) until we receive focus again, as it
causes cells to redraw. We might want to use our own flag to prevent
updating in the model instead of using Qt for this
2021-03-19 19:45:21 +10:00
Damien Elmes
3f87f7bf5c don't update review screen immediately on note changes
The redraw causes an ugly flash, and it will result in audio being
replayed over and over as the user types.
2021-03-19 19:45:21 +10:00
Damien Elmes
3ad86f1852 prevent editor from refreshing itself after a save
- add after_hooks arg to perform_op()
- when refreshing browse screen, just redraws cells, and handle
editor update in Browser instead of the model
2021-03-19 19:45:21 +10:00
Damien Elmes
6b0fe4b381 undoable ops now return changes directly; add new *_ops.py files
- Introduced a new transact() method that wraps the return value
in a separate struct that describes the changes that were made.
- Changes are now gathered from the undo log, so we don't need to
guess at what was changed - eg if update_note() is called with identical
note contents, no changes are returned. Card changes will only be set
if cards were actually generated by the update_note() call, and tag
will only be set if a new tag was added.
- mw.perform_op() has been updated to expect the op to return the changes,
or a structure with the changes in it, and it will use them to fire the
change hook, instead of fetching the changes from undo_status(), so there
is no risk of race conditions.
- the various calls to mw.perform_op() have been split into separate
files like card_ops.py. Aside from making the code cleaner, this works
around a rather annoying issue with mypy. Because we run it with
no_strict_optional, mypy is happy to accept an operation that returns None,
despite the type signature saying it requires changes to be returned.
Turning no_strict_optional on for the whole codebase is not practical
at the moment, but we can enable it for individual files.

Still todo:
- The cursor keeps moving back to the start of a field when typing -
we need to ignore the refresh hook when we are the initiator.
- The busy cursor icon should probably be delayed a few hundreds ms.
- Still need to think about a nicer way of handling saveNow()
- op_made_changes(), op_affects_study_queue() might be better embedded
as properties in the object instead
2021-03-19 19:45:21 +10:00
Damien Elmes
30c7cf1fdd fade out webview when pending updates; do some reviewer updates immediately
Issues that need fixing:
- when the editor saves the note with perform_op(), if it isn't modified,
no new undo entry is created, and perform_op then returns the changes
made by the previous operation instead
- the approach of fetching the last action in a subsequent backend
method is unsound, as another queued operation may sneak in first before
we have a chance to query the result - it would be better if it were
returned in a single atomic action
- redrawing the current card while editing is likely to make sound
autoplay annoyingly, and it has an unpleasant redraw. We may be better off
fading it out instead

Side note: the editor cursor moves to the start of the field when the
note is updated in another window - it might be nicer to have it move
the cursor to the end instead.
2021-03-19 19:45:21 +10:00
Damien Elmes
0a5be6543e experiment with replacing requireReset with updates on focus-in
- This avoids the need for a separate screen, though we may want to
slightly fade out the display when information is stale.
- Means the browser can delay updates just like the main window does.
2021-03-19 19:45:21 +10:00
Damien Elmes
1e849316be more reset refactoring
'card modified' covers the common case where we need to rebuild the
study queue, but is also set when changing the card flags. We want to
avoid a queue rebuild in that case, as it causes UI flicker, and may
result in a different card being shown. Note marking doesn't trigger
a queue build, but still causes flicker, and may return the user back
to the front side when they were looking at the answer.

I still think entity-based change tracking is the simplest in the
common case, but to solve the above, I've introduced an enum describing
the last operation that was taken. This currently is not trying to list
out all possible operations, and just describes the ones we want to
special-case.

Other changes:

- Fire the old 'state_did_reset' hook after an operation is performed,
so legacy code can refresh itself after an operation is performed.
- Fire the new `operation_did_execute` hook when mw.reset() is called,
so that as the UI is updated to the use the new hook, it will still
be able to refresh after legacy code calls mw.reset()
- Update the deck browser, overview and review screens to listen to
the new hook, instead of relying on the main window to call moveToState()
- Add a 'set flag' backend action, so we can distinguish it from a
normal card update.
- Drop the separate added/modified entries in the change list in
favour of a single entry per entity.
- Add typing to mw.state
- Tweak perform_op()
- Convert a few more actions to use perform_op()
2021-03-19 19:45:21 +10:00
Damien Elmes
112cbe8b59 experiment with finer-scoped reset in perform_op()
Basic proof of concept, where the 'delete note' operation in the
reviewer has been updated to use mw.perform_op(). Instead of manually
calling .reset() afterwards, a summary of the changes is returned as
part of the undo status query, and various parts of the GUI can listen
to gui_hooks.operation_did_execute and decide whether they want to
redraw based on the scope of the changes. This should allow the sidebar
to selectively redraw just the tags area in the future for example.

Currently we're just listing out all possible areas that might be changed;
in the future we could theoretically inspect the specific changes in the
undo log to provide a more accurate report (avoiding refreshing the tags
list when no tags were added for example).

You can test it out by opening the browse screen while studying, and
then deleting the current card - the browser should update to show (deleted)
on the cards due the earlier change.

If going ahead with this, aside from updating all the screens that currently
listen for resets, some thought will be required on how we can integrate
it with legacy code that expects to called when resets are made, and expects
to call .reset() when it makes changes.

Thoughts?
2021-03-19 19:45:21 +10:00
Damien Elmes
e364b36dc4 experiment with preserving search when resetting
Up until now, we've been forcing a new search whenever reset is called.
The primary reason was that the card list display routines did not expect
a card or note to have been removed. By updating the model to show
"(deleted)" when a card or note is missing, we no longer have to repeat
the search.

This has a few advantages:

- Searches, especially complex ones, can be slow to execute. When we
perform them after every operation like a delete, it can make Anki feel
sluggish.
- The fact that notes have been deleted becomes more obvious - some users
found it easy to miss the "deleted" pop-up in the past.

This change does not just affect deletions, as many other operations
trigger a reset as well. In the past, when using 'set due date' in the
review screen for example, it caused an ugly flicker in the browser screen,
and could be slow when the current search couldn't be quickly redone.

The disadvantage of this approach is that the displayed content may
not reflect the specified search, which has the potential to be confusing.
But if that turns out to be a problem, it could be (partly) alleviated by
displaying a refresh button next to the search bar when the search may
need to be refreshed.

Feedback welcome!
2021-03-19 19:45:21 +10:00
Damien Elmes
6f9e1d62ec deck deletion in deck list was not resetting state 2021-03-19 19:45:20 +10:00
Damien Elmes
6a119d92fb
Merge pull request #1071 from RumovZ/sidebar-del
Only delete by key when selected items have same type
2021-03-15 13:27:31 +10:00
RumovZ
35fa58730c Improve grouping of sidebar methods 2021-03-13 09:45:06 +01:00
RumovZ
53665f0cf4 Use same constraints for deleting by key press ...
... as for deleting via context menu, i.e., delete key does nothing if
not all selected items are of the same type.
2021-03-13 09:31:56 +01:00
Damien Elmes
44dc3f494c avoid hanging UI when undoing in browse screen 2021-03-12 18:54:08 +10:00
Damien Elmes
57a05a2ae3 undo in background, and show progress window 2021-03-12 17:54:56 +10:00
Damien Elmes
d92f1499ff experiment with perform_op() wrapper
Fixes #1065, and gives us similar functionality to #1066
2021-03-12 17:54:13 +10:00
Damien Elmes
2ffc055487 'change deck' now undoable 2021-03-12 16:27:57 +10:00
Damien Elmes
24762261d9 make 'forget card' undoable; remove checkpoint() in set_due_date 2021-03-12 16:13:50 +10:00
Damien Elmes
9ba02b5ca6 fix set due date not remembering default in browse screen 2021-03-12 15:47:11 +10:00
Damien Elmes
6e0e17b2b9 Revert "Merge pull request #1066 from RumovZ/editor-save-dec"
This reverts commit a0c47243b6, reversing
changes made to 0ab87b7339.

@RumoVZ this broke a bunch of operations like 'select notes' and
'set due date'. When the triggered signal is connected to a function,
PyQt looks at the function signature to decide what arguments to pass
it. The wrapper was using *args, so PyQt passes in an extra argument,
which the underlying function didn't expect.

I tried settting __signature__ on the wrapper, but PyQT seems to
ignore it, so we may either need to check all of the existing calls
and add the ignored extra arguments, or create a separate wrapper for
such cases.
2021-03-12 15:44:19 +10:00
Damien Elmes
c1316bb65f 'set due date' now undoable 2021-03-12 14:50:31 +10:00
Damien Elmes
ad973bb701 split out common scheduler code into base.py, use scheduler/ dir
Also move the legacy aliases into a separate file
2021-03-12 14:07:52 +10:00
RumovZ
538afd94bc Add decorator to save editor in sidebar 2021-03-11 22:25:18 +01:00
RumovZ
9bf93573da Add decorator to save editor in browser 2021-03-11 22:24:24 +01:00
RumovZ
f4c2fe6485 Merge branch 'master' into sidebar-tools 2021-03-11 12:08:32 +01:00
Damien Elmes
e20c5ed9c5 deck drag&drop undo 2021-03-11 20:02:16 +10:00
RumovZ
c11a394753 Remove prompt when deleting from deckbrowser 2021-03-11 10:28:23 +01:00
RumovZ
5d93832713 Run background tasks with progress 2021-03-11 10:04:58 +01:00
RumovZ
f1dd010489 Remove deck remove prompt but show card count 2021-03-11 09:52:11 +01:00
RumovZ
3219bb2539 Remove prompt when deleting saved searches 2021-03-11 09:20:41 +01:00
RumovZ
337ef0ae21 Show count of affected notes after tag renaming 2021-03-11 09:17:22 +01:00
RumovZ
186a0202ea Show tooltip instead of prompt for removing tags 2021-03-11 09:14:50 +01:00
bluegreenmagick
38ae2f2b06 Clicking the expander icon should not trigger click event
Expander icon does not change currentIndex
2021-03-11 09:04:24 +09:00
RumovZ
8e9331e424 Fix repainting in case of tag renaming exception 2021-03-10 21:50:46 +01:00
RumovZ
bc7043c384 Store name prefix of sidebar items 2021-03-10 16:38:29 +01:00
Damien Elmes
e122f8ae0d undo support for deck adding/removing
Work in progress - still to do:
- renames appear as 'Update Deck' - easiest way to solve it would
be to have a separate backend method for renames
- drag&drop of decks not yet undoable
- since the undo status is updated after the backend method ends,
the older checkpoint() calls need to be replaced with an
update_undo_status() at the end of the call - if we just remove the
checkpoint, then the menu doesn't get updated
2021-03-10 23:50:11 +10:00
RumovZ
602ffa67a7 Update about screen 2021-03-10 11:34:28 +01:00
RumovZ
0c2ac4ba04 Merge branch 'master' into sidebar-tools 2021-03-10 10:34:36 +01:00
RumovZ
ffbb0b7c07 Disable renaming models and templates ...
... but add context action CLayout for templates.
2021-03-10 10:14:06 +01:00
Damien Elmes
6b1dd9ee19 expand backend Preferences and make undoable
- moved 'default to current deck when adding' into prefs
- move some profile options into the collection config, so they're
undoable and will sync. There is (currently) no automatic migration
from the old profile settings, meaning users will need to set the
options again if they've customized them.
- tidy up preferences.py
- drop the deleteMedia option that was not exposed in the UI
2021-03-10 18:51:03 +10:00
Damien Elmes
24ad7c1f35 inline scheduling settings into preferences 2021-03-10 14:11:59 +10:00
Damien Elmes
ce243c2cae Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:

- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.

It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.

To address these points:

- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-10 11:53:27 +10:00
Damien Elmes
3d0ddc8539 make flag changes in the reviewer undoable
This splits update_card() into separate undoable/non-undoable ops
like the change to notes in b4396b94abdeba3347d30025c5c0240d991006c9

It means that actions get a blanket 'Update Card' description - in the
future we'll probably want to either add specific actions to the backend,
or allow an enum or string to be passed in to describe the op.

Other changes:
- card.flush() can no longer be used to add new cards. Card creation
is only supposed to be done in response to changes in a note's fields,
and this functionality was only exposed because the card generation
hadn't been migrated to the backend at that point. As far as I'm aware,
only Arthur's "copy notes" add-on used this functionality, and that should
be an easy fix - when the new note is added, the associated cards will
be generated, and they can then be retrieved with note.cards()
- tidy ups/PEP8
2021-03-10 11:53:27 +10:00
Damien Elmes
d4765a301f coalesce note updates; avoid unnecessary saving due to mtime changes 2021-03-10 11:53:27 +10:00
Damien Elmes
f1a1b0891e make mark toggling undoable
- note.flush() behaves like before, as otherwise actions or add-ons
that perform bulk flushing would end up creating an undo entry for
each note
- added col.update_note() to opt in to the new behaviour
- tidy up the names of some related routines
2021-03-10 11:53:27 +10:00
Damien Elmes
bec77fd420 undo support for bulk tag add/remove 2021-03-10 11:47:53 +10:00
Damien Elmes
49a1970399 note deletion undo; refactoring
- transact() now automatically clears card queues unless an op
opts-out (and currently only AnswerCard does). This means there's no
risk of forgetting to clear the queues in an operation, or when undoing/
redoing
- CollectionOp->UndoableOp
- clear queues when redoing "answer card", instead of clearing redo
when clearing queues
2021-03-10 11:47:53 +10:00
Damien Elmes
605ad1c9ee remove unnecessary setMod() calls 2021-03-10 11:47:53 +10:00
Damien Elmes
57d7e3e2ab commit immediately when there's no active checkpoint
Reviews and operations on the backend that support undoing can now be
committed immediately, so they will not be lost in the event of a crash.

This required tweaks to a few places:

- don't set collection mtime on save() unless changes were made in
Python, as otherwise we end up accidentally clearing the backend undo
queue
- autosave() is now run on every reset()
- garbage collection now runs in a timer, instead of relying on
autosave() to be run periodically
2021-03-10 11:47:53 +10:00
Damien Elmes
40aff4447a undo support for note adding 2021-03-10 11:47:53 +10:00
Damien Elmes
105ce94dd4 undo unbury/unsuspend 2021-03-10 11:47:53 +10:00
Damien Elmes
41779c1aad implement bury/suspend undo 2021-03-10 11:47:53 +10:00
Damien Elmes
b466f0ce90 rework undo
- use dataclasses for the review/checkpoint undo cases, instead of the
nasty ad-hoc list structure
- expose backend review undo to Python, and hook it into GUI
- redo is not currently exposed on the GUI, and the backend can only
cope with reviews done by the new scheduler at the moment
- the initial undo prototype code was bumping mtime/usn on undo, but
that was not ideal, as it was breaking the queue handling which expected
the mtime to match. The original rationale for bumping mtime/usn was
to avoid problems with syncing, but various operations like removing
a revlog can't be synced anyway - so we just need to ensure we clear the
undo queue prior to syncing
2021-03-10 11:47:53 +10:00
Damien Elmes
b9c4b2bdbe
Merge pull request #1046 from hgiesel/sticky
Sticky icons in the editor window
2021-03-10 11:43:51 +10:00
Damien Elmes
1e7405296f
Merge pull request #1050 from BlueGreenMagick/choose-addon-to-update
Choose addon to update
2021-03-10 11:41:50 +10:00
RumovZ
9a844591fe Ensure mouse is at current index before searching
Thus, no search will be triggered when clicking an expansion indicator
as this doesn't update the current element. However, if the indicator
belongs to the current item, a search will be triggered anyway.
2021-03-09 20:36:15 +01:00
RumovZ
a9ea7e39ae Disable expand on double click in search mode 2021-03-09 20:18:12 +01:00
bluegreenmagick
4cde93ed74 don't show routine update when not update_enabled 2021-03-09 22:27:28 +09:00
bluegreenmagick
29076ec9ec add context menu to open ankiweb page 2021-03-09 22:19:03 +09:00
bluegreenmagick
c11feda0eb add bool_to_check and checked method 2021-03-09 22:19:03 +09:00
bluegreenmagick
01d8dc20f1 fix check issues in ChooseAddonsToUpdateList 2021-03-09 22:19:03 +09:00
bluegreenmagick
e73e0bec34 save chooseaddonupdate check state 2021-03-09 22:19:03 +09:00
Henrik Giesel
e03bfd2923 Refactor bridgeCommand and silence false "uncaught msg" log 2021-03-09 13:43:11 +01:00
Henrik Giesel
cd26901f3d Make sure topleft buttons are rounded too, prefer Bootstrap's rounded class 2021-03-09 13:43:11 +01:00
Henrik Giesel
6fbd82f2f8 Change signature of editor onBridgeCmd to Any instead of None 2021-03-09 13:43:11 +01:00
Henrik Giesel
da0317cb85 Replace pin icon with lock icon
Credit goes out to @kleinerpirat
2021-03-09 13:43:11 +01:00
Henrik Giesel
ebf423bc9c Remove Change Tracker again 2021-03-09 13:43:11 +01:00
Henrik Giesel
8593ab3c4c Connect icons to sticky fields values 2021-03-09 13:37:56 +01:00
Henrik Giesel
d13bd1096d Remove explicit popperjs again, because it's included in bootstrap.bundle 2021-03-09 13:37:56 +01:00
Henrik Giesel
31cba30873 Include the bootstrap icons in the editor view 2021-03-09 13:37:56 +01:00
Henrik Giesel
a66b0fbd84 Fix positioning of buttons 2021-03-09 13:37:56 +01:00
Henrik Giesel
f2cc85a3bc Include bootstrap in editor 2021-03-09 13:37:56 +01:00
Henrik Giesel
aeda64a890 Add bootstrap, bootstrap-icons, and popperjs 2021-03-09 13:37:56 +01:00
RumovZ
3f772ce0fe Add shortcuts for sidebar tools 2021-03-09 11:19:44 +01:00
RumovZ
28402c7015 Improve toolbar styling for macOS 2021-03-09 08:50:01 +01:00
RumovZ
08c09bcb0f Remove edit mode 2021-03-08 11:55:15 +01:00
RumovZ
8d9072193c Enable drag for all sidebar items ...
... and set valid drop targets dynamically based on the current
selection.
2021-03-08 11:35:39 +01:00
RumovZ
f07890c178 Ask before removing tags from collection 2021-03-07 11:40:11 +01:00
RumovZ
6c4d6457fb Simplify multi deletion confirmation strings 2021-03-07 11:05:43 +01:00
RumovZ
f72daacae4 Only show edit actions with conform selection 2021-03-07 11:05:28 +01:00
RumovZ
23777eed67 Fix repainting in case of tree building exception 2021-03-07 09:47:17 +01:00
RumovZ
cce1b1f702 Remove context action dict
Now that almost all actions can be triggered from outside the context
menu and are available for more than one item type, it's easier to check
for available actions dynamically.
2021-03-05 12:22:49 +01:00
RumovZ
39dad049cd Fix children check in context tree actions 2021-03-05 10:27:44 +01:00
Benjamin K
5d880f6e31 Clean up imports 2021-03-04 19:55:35 +01:00
Benjamin K
a066cee326 The old delimiter is now kept, when cancel button is clicked 2021-03-04 19:39:43 +01:00
RumovZ
513e7bdfb4 Enable deleting via delete key 2021-03-04 18:31:35 +01:00
RumovZ
1f500c1fb8 Enable Enter/Return search in all modes ...
... but don't trigger search if the key closes the editor.
Also get rid of the on_click of the saved searches root which has
already been removed on main.
2021-03-04 17:40:12 +01:00
RumovZ
4ab9e6caef Ask for confirmation when overwriting saved search 2021-03-04 17:22:03 +01:00
RumovZ
6930ea24a9 Adjust sidebar tool icons to smaller size 2021-03-04 17:20:10 +01:00
RumovZ
5c6eea0d80 Make renamed item current (don't just select) 2021-03-03 23:00:37 +01:00
RumovZ
7d3d6edb26 Remove renaming dialogues from sidebar ...
... in favour of in-line editing. This is simpler and more ergonomic for
the user (and the programmer) but doesn't allow for editing parents
through text input (in the case of tags and decks).
2021-03-03 21:57:39 +01:00
RumovZ
bcc8a5ac3a Enable renaming templates from the sidebar 2021-03-03 18:09:53 +01:00
RumovZ
aa4576dd42 Enable renaming notetypes 2021-03-03 15:18:50 +01:00
RumovZ
65a2796a0e Enable group expanding/collapsing
Also, only show expand/collapse actions if they will have an effect.
2021-03-03 11:44:42 +01:00
RumovZ
61e61376a2 Make SidebarItem._is_extended a property 2021-03-03 11:43:31 +01:00
RumovZ
e2940de4a4 Escape backslashes in re.sub()'s repl 2021-03-03 09:20:02 +01:00
RumovZ
c0d77896da Add DECK_CURRENT as a SidebarItemType
Thus, disable renaming, deleting etc. for the current deck item.
As a consequence, editable is no longer needed as a field of SidebarItem
as it can be derived from its type.
2021-03-03 09:15:36 +01:00
bluegreenmagick
69006b5872 add dialog to choose addons to update 2021-03-03 10:34:43 +09:00
RumovZ
adaea7227e Select and scroll to renamed/added sidebar item 2021-03-02 23:13:34 +01:00
RumovZ
25d57574c9 Enable removal of multiple tags from the sidebar 2021-03-02 11:05:16 +01:00
RumovZ
e29bd4479b Make clickable dyndeck labels fixed in size 2021-03-01 11:26:52 +01:00
RumovZ
f4aeb0c097 Enable deleting multiple saved searches 2021-03-01 09:41:41 +01:00
RumovZ
e199bf0b47 Fix repainting when renaming tag via dialogue 2021-03-01 08:45:33 +01:00
RumovZ
30e7d705b6 Enable extended selection in edit mode 2021-03-01 08:45:03 +01:00
Damien Elmes
e218604708 monospace font in html editor
https://forums.ankiweb.net/t/change-default-font-of-html-edit-mode-to-a-monospaced-font/7833
2021-03-01 10:16:12 +10:00
Damien Elmes
32af54cd4d catch attempts to nest under a filtered deck; don't show traceback 2021-03-01 09:58:12 +10:00
Damien Elmes
5564fd9e13
Merge pull request #1040 from RumovZ/deck-name-err
Catch deck rename errors and localise warnings
2021-03-01 09:40:55 +10:00
RumovZ
e83f0fef0f Fix Qt types 2021-02-28 22:36:31 +01:00
RumovZ
dc1711b630 Always return False from rename_node
setData expects a result but due to the asynchrony of the editor it
might not be known, yet.
2021-02-28 22:36:21 +01:00
RumovZ
1b8cebb8c5 Enable in-place editing of sidebar tags 2021-02-28 21:50:21 +01:00
RumovZ
d0b916a2ff Enable in-place editing of saved searches 2021-02-28 21:13:26 +01:00
RumovZ
0b83828508 Enable in-place editing of sidebar deck items 2021-02-28 21:03:19 +01:00
RumovZ
88c69665f3 Add support for multi deck deletion in python 2021-02-26 19:52:34 +01:00
RumovZ
2c25645975 Place sidebar tools right of search bar 2021-02-26 13:04:30 +01:00
RumovZ
92cbf168f6 Catch DeckIsFilteredError directly on frontend 2021-02-26 11:32:40 +01:00
Damien Elmes
b8acf11f3e remove left-click on saved searches
Multiple users have thought it was a bug rather than an intentional
feature, and it breaks double-clicking:

https://forums.ankiweb.net/t/anki-2-1-41-beta/7305/51
2021-02-26 18:48:32 +10:00
Damien Elmes
d666b7e5b0 fix browser appearance defaults
https://forums.ankiweb.net/t/small-bug-in-the-browser-appearance-window/7806
2021-02-26 18:46:09 +10:00
Damien Elmes
bfd452c120
Merge pull request #1039 from RumovZ/dyndeck-hint
Clickable hint in dyndeck dialogue for unmovable cards
2021-02-26 18:02:51 +10:00
RumovZ
f5981e94bf Add group search context action 2021-02-25 21:24:11 +01:00
RumovZ
172133299b Handle search on event level
Instead of assigning each sidebar item a lambda, add a field for search
representation and handle searching in event handler.
2021-02-25 19:57:12 +01:00
RumovZ
47e1e62967 Make search first (default) mode 2021-02-25 19:28:29 +01:00
RumovZ
4a1e995934 Add edit mode in sidebar 2021-02-25 13:12:51 +01:00
RumovZ
0889972bb0 Save last sidebar tool 2021-02-25 12:20:54 +01:00
RumovZ
fd784adc31 Add select and search modes to sidebar 2021-02-25 11:06:59 +01:00
RumovZ
17afcb094f Add toolbar to sidebar 2021-02-25 11:05:04 +01:00
RumovZ
9d3da3b844 Add icons for sidebar tools 2021-02-25 11:02:17 +01:00
bluegreenmagick
c7d8700054 StudyDeck without add button 2021-02-25 07:34:01 +09:00
RumovZ
1dca43f409 Fix #1024 – catch deck rename errors 2021-02-24 13:59:38 +01:00
RumovZ
8e43b29816 Localise RenameDeckError 2021-02-24 13:57:44 +01:00
RumovZ
e95c2fa6ce Fix type hints in dyndeckconf 2021-02-24 11:24:27 +01:00
RumovZ
234ca4d496 Refactor dyndeckconf/on_hint_button 2021-02-24 11:14:33 +01:00
RumovZ
d6b1c0cf3a Give dyndeck hint unique styling 2021-02-23 23:34:05 +01:00
RumovZ
ae88f7e593 Add clickable hint to dyndeckconf 2021-02-23 23:14:11 +01:00
RumovZ
5a37b8e2af Add direct col reference to dyndeckconf 2021-02-23 22:31:04 +01:00
Henrik Giesel
8aa8174d4b Fix scrollbar issue in anki-editable component in two ways
- using :host-context(.nightMode) allows for applying the nightmode
  scroll bar inside the component
- apply max-width: 100% to all element within editable, not just images
2021-02-23 15:52:20 +01:00
Damien Elmes
f41ec183c2
Merge pull request #1034 from abdnh/clayout-cloze-shortcuts
Shortcuts to preview clozes in card layout screen
2021-02-22 10:07:16 +10:00
abdo
39f3b6ce93 Shortcuts to preview clozes in card layout screen
Assign Alt+{number} to select cloze cards.
2021-02-21 14:46:53 +03:00
Damien Elmes
13f5ee1ddc tweak update message
- Since we need to show this to new users until AnkiDroid is updated,
use a wording that doesn't seem so out of place to new users.
- Avoid mentioning syncing, since the user may not sync, and the
modSchema() call will allow the user to confirm anyway.
- Let the user know they can change their mind about AnkiDroid by
visiting the preferences.
2021-02-21 19:47:26 +10:00
Damien Elmes
5ae66af5d2 rework v2 scheduler upgrade; drop downgrade
- Rework V2 upgrade so that it no longer resets cards in learning,
or empties filtered decks.
- V1 users will receive a message at the top of the deck list
encouraging them to upgrade, and they can upgrade directly from that
screen.
- The setting in the preferences screen has been removed, so users
will need to use an older Anki version if they wish to switch back to
V1.
- Prevent V2 exports with scheduling from being importable into a V1
collection - the code was previously allowing this when it shouldn't
have been.
- New collections still default to v1 at the moment.

Also add helper to get map of decks and deck configs, as there were
a few places in the codebase where that was required.
2021-02-21 15:50:41 +10:00
bluegreenmagick
d6eac551b1 change _on_click_current to _on_click_index
fix bug where clicking on a blank space below sidebar item
would still trigger currentIndex item's click event
2021-02-20 22:58:02 +09:00
Damien Elmes
2941503bea tweak getFile() arguments in editor to be more readable 2021-02-19 10:18:40 +10:00
Damien Elmes
654f4d65f7 disable card shifting in reposition by default
https://forums.ankiweb.net/t/uncheck-shift-position-of-existing-cards-by-default/7550
2021-02-19 10:09:01 +10:00
Damien Elmes
ab1e59a04d use add-on id if name is blank
https://forums.ankiweb.net/t/support-for-rtl-layout-in-ankiweb-add-on-page/7522
2021-02-16 11:12:05 +10:00
Henrik Giesel
adb002f05f Remove unused imports 2021-02-12 02:16:05 +01:00
Henrik Giesel
87febe489e Allow for passing in custom note type and template 2021-02-12 02:12:03 +01:00
Henrik Giesel
270cef63f4 Allow for passing in custom note types for rendering ephemeral cards 2021-02-12 01:53:03 +01:00
Damien Elmes
6e9dfefb24 Revert "Use new note.ephemeral_card method in clayout"
This partially reverts commit 2483ef4517.
2021-02-12 10:05:46 +10:00
Damien Elmes
35840221bb tweak search wording and tidy up API
- SearchTerm -> SearchNode
- Operator -> Joiner; share between messages
- build_search_string() supports specifying AND/OR as a convenience
- group_searches() makes it easier to negate
2021-02-11 19:57:19 +10:00
Damien Elmes
59ccfe5918 more search bikeshedding
While implementing the overdue search, I realised it would be nice to
be able to construct a search string with OR and NOT searches without
having to construct each part individually with build_search_string().

Changes:

- Extends SearchTerm to support a text search, which will be parsed
by the backend. This allows us to do things like wrap text in a group
or NOT node.
- Because SearchTerm->Node conversion can now fail with a parsing error,
it's switched over to TryFrom
- Switch concatenate_searches and replace_search_term to use SearchTerms,
so that they too don't require separate string building steps.
- Remove the unused normalize_search()
- Remove negate_search, as this is now an operation on a Node, and
users can wrap their search in SearchTerm(negated=...)
- Remove the match_any and negate args from build_search_string

Having done all this work, I've just realised that perhaps the original
JSON idea was more feasible than I first thought - if we wrote it out
to a string and re-parsed it, we would be able to leverage the existing
checks that occur at parsing stage.
2021-02-11 17:11:17 +10:00
Damien Elmes
5c69bccfcf switch some existing code to use SearchTerm(negated=...) 2021-02-11 10:55:02 +10:00
Damien Elmes
397cff9194 split due into 'due today' and 'overdue' 2021-02-11 10:49:36 +10:00
Damien Elmes
67d612926c Revert "experiment with using right click for AND/OR/NOT"
This reverts commit 9048a1ff3c and
manually comments out the setSelectionMode() call.

Switching back to the old behaviour until issues can be worked through.
https://forums.ankiweb.net/t/anki-2-1-41-beta/7305/24
2021-02-11 10:14:26 +10:00
Damien Elmes
2a585c5e5a Revert "add escape hatch for new clicking behaviour, in case it causes problems"
This reverts commit 678756c3e9.
2021-02-11 10:10:45 +10:00
Damien Elmes
88c002f4eb convert qt strings to f-strings with flynt
Also revealed an incorrect type def in editor.py that mypy wasn't
noticing before :-(
2021-02-11 10:09:06 +10:00
Damien Elmes
bb29ce88f3 minor code cleanups with pyupgrade
- pyupgrade --py38-plus --keep-runtime-typing --keep-percent-format
- third-party mpv and winpaths excluded
2021-02-11 09:43:40 +10:00
Damien Elmes
4d373f4aa3 catch TTS runtime error 2021-02-10 16:30:51 +10:00
Damien Elmes
678756c3e9 add escape hatch for new clicking behaviour, in case it causes problems 2021-02-09 19:29:59 +10:00
Damien Elmes
9ce4b21935 add markdown flag for deck description
Needed so we can display consistently, and gradually transition over
2021-02-09 18:47:19 +10:00
Damien Elmes
cf5e04b011 tweak sidebar appearance
- draw a border between sidebar and main area
- tweak padding

Testing is a pain, because you need to check day mode on the
three platforms, and night mode as well. If you can do it better, PRs
are welcome :-)
2021-02-09 16:23:44 +10:00
Damien Elmes
63b369b8a6 add 'untagged', and make clicking on 'tags' show all tagged cards 2021-02-09 12:50:35 +10:00
Damien Elmes
9048a1ff3c experiment with using right click for AND/OR/NOT
This frees up Ctrl/Shift+left click to behave like in a typical GUI
app. On a Mac users can either two finger click, or Command+click in
conjunction with one of the other modifiers.

https://github.com/ankitects/anki/issues/1011
2021-02-09 11:39:47 +10:00
Damien Elmes
68c4b10dcd move update_search into sidebar.py; fix setFilter()
No idea why neither mypy nor pylint are not noticing
"set_filter_then_search" does not exist. Python tooling. :-(
2021-02-09 10:50:39 +10:00
Damien Elmes
09dfbfe2b9 Partially revert "don't select contiguously with shift+click"
I thought this could work, but users (including myself!) are used to
being able to shift+click to select a region, and this behaviour is
surprising. We're also doing potentially expensive searches for each
extra selected item. I think we may need to switch this behaviour to
the right mouse button instead.

This partially reverts commit c91d21e18e.
2021-02-09 10:37:21 +10:00
Damien Elmes
2a0bc15a0b move flags above card state; change stage label for consistency 2021-02-09 09:54:46 +10:00
Damien Elmes
180efbc578 recent -> today
'Current deck' has moved, and by removing 'due tomorrow', we can drop
the 'today' suffix on the rest of the items.

The keys of the existing translations have not been changed, so
existing translations will not break, but will need to be manually
updated to make them shorter.
2021-02-09 09:50:59 +10:00
Damien Elmes
13aa6f99e4 fix rename/delete on current deck 2021-02-09 09:38:37 +10:00
Damien Elmes
c91d21e18e don't select contiguously with shift+click; enable multiple selection
https://github.com/ankitects/anki/issues/1011
2021-02-09 09:33:32 +10:00
Damien Elmes
7972fa6493 remove 'any flag'; make clicking on flags root do the same thing 2021-02-08 22:52:37 +10:00
Damien Elmes
202cf38446 fix wrong item type being used for recent items 2021-02-08 22:50:48 +10:00
Damien Elmes
05074f2cc1 make decks root search collection; move current deck
Also use explicit 'deck:*' search, to make it more obvious what is
happening
2021-02-08 22:48:45 +10:00
Damien Elmes
a8ddb65e1c add ability to force interval reset
- use trailing ! to force a reset
- use - instead of ..
- tweak i18n messages and error handling
2021-02-08 22:33:27 +10:00
Damien Elmes
b9635ce936 nest NoteWithEmptyCards 2021-02-08 19:11:16 +10:00
Damien Elmes
aa82bb172d add small amount of padding to sidebar
https://forums.ankiweb.net/t/anki-2-1-41-beta/7305/3
2021-02-08 19:01:54 +10:00
Damien Elmes
4ac62f8848 fix media check not updating progress 2021-02-08 16:46:57 +10:00
Damien Elmes
6ac35b30c1 Media check suffered from the same text box slowdown as the importing screen 2021-02-08 16:42:21 +10:00
Damien Elmes
c23b01978d nest progress messages and remove Python wrapper class
The progress messages are only really intended to be consumed by Anki.
If consumption by add-ons was expected, we'd be better off keeping the
wrapper, as the API for oneofs in Python is quite awkward to use.
2021-02-08 16:40:27 +10:00
Damien Elmes
f434cff36f remember last input for 'set due'; add string config; nest config types 2021-02-08 14:10:05 +10:00
Damien Elmes
b56580a8c0 fix rsbackend compat issues 2021-02-08 09:51:51 +10:00
Damien Elmes
6aab9feec1 add (unused) reschedule option back to avoid breaking fastbar 2021-02-08 09:51:40 +10:00
Damien Elmes
704b5e581a Rework reschedule tool
The old rescheduling dialog's two options have been split into two
separate menu items, "Forget", and "Set Due Date"

For cards that are not review cards, "Set Due Date" behaves like the
old reschedule option, changing the cards into a review card, and
and setting both the interval and due date to the provided number of
days.

When "Set Due Date" is applied to a review card, it no longer resets
the card's interval. Instead, it looks at how much the provided number
of days will change the original interval, and adjusts the interval by
that amount, so that cards that are answered earlier receive a smaller
next interval, and cards that are answered after a longer delay receive
a bonus.

For example, imagine a card was answered on day 5, and given an interval
of 10 days, so it has a due date of day 15.

- if on day 10 the due date is changed to day 12 (today+2), the card
is being scheduled 3 days earlier than it was supposed to be, so the
interval will be adjusted to 7 days.
- and if on day 10 the due date is changed to day 20, the interval will
be changed from 10 days to 15 days.

There is no separate option to reset the interval of a review card, but
it can be accomplished by forgetting the card(s), and then setting the
desired due date.

Other notes:

- Added the action to the review screen as well.
- Set the shortcut to Ctrl+Shift+D, and changed the existing Delete
Tags shortcut to Ctrl+Alt+Shift+A.
2021-02-07 21:57:51 +10:00
Damien Elmes
b7c72bca4c fix backup not being taken before full download 2021-02-06 19:01:48 +10:00
Damien Elmes
3cd311191a add opus to supported audio list and sort 2021-02-06 15:11:24 +10:00
Damien Elmes
e30b7fc36a handle remote links in ts pages
Required to avoid loading remote links embedded in deck descriptions
in the webview
2021-02-06 15:03:21 +10:00
Damien Elmes
5662939b70 fix filter saving failing when savedFilters is not set 2021-02-05 22:38:44 +10:00
Damien Elmes
efd8c527a6 use 'contains' instead of 'prefix' search in tag completer 2021-02-05 21:14:35 +10:00
Damien Elmes
dfe3c457e5 use top level defs for protobuf enum cases
While mypy can understand nested references like ConfigBool.Key.COLLAPSE_RECENT,
PyCharm doesn't understand the metaclass syntax, and shows the definitions
as invalid.
2021-02-05 19:26:13 +10:00
Damien Elmes
bb30e8f7bc use constants for other color references
str_color/qcolor() doesn't appear to have been used by any add-ons
except one of mine, so changing the signature should be safe
2021-02-05 18:58:22 +10:00
Damien Elmes
b8d67cdad5 move remaining Filter button items into sidebar
- Closes #976
- Added helper to apply arbitrary colour to an icon.
- Fix #979 - low res icons in night mode.
- The icons and colours are not perfect - please feel free to send
through a PR if you can improve them.
- Convert colors dictionary into module consts, so we can
use code completion.
- Added "Edited Today" and "Due Tomorrow"
- Rename camelCase attribute to snake_case and tweak the wording
of some enum constants. We've already broken compatibility with the
major sidebar add-ons, so we may as well make these changes while we
can.
- Removed Filter button. Currently there is no exposed way to toggle
the Sidebar off - wonder if we still need it?
2021-02-05 18:58:22 +10:00
Damien Elmes
bd730a012e replace sidebar filter shortcut with existing Filter button shortcut 2021-02-05 14:32:56 +10:00
Damien Elmes
8af82b4594 exclude Mac dylib from '...' 2021-02-04 20:41:08 +10:00
Damien Elmes
a602f0342c fix Qt translations in macOS packaged build 2021-02-04 20:28:25 +10:00
Damien Elmes
3c1fa68460 turn top bar dark when night mode enabled on macOS 2021-02-04 19:19:56 +10:00
Damien Elmes
39c6429fe2 fix broken card styling fix :-) 2021-02-03 22:32:55 +10:00
Damien Elmes
7e8886c352 fix broken card styling 2021-02-03 22:22:12 +10:00
Damien Elmes
168963460f update to latest mypy_protobuf
The handling of enum types has improved - we no longer need to import
separate types at typechecking time.
2021-02-03 13:31:52 +10:00
Damien Elmes
86f8cba22c
Merge pull request #972 from hgiesel/ephemeral
Move ephemeral card functionality from clayout to Note class
2021-02-03 13:10:00 +10:00
Damien Elmes
e683e5c4d7
Merge pull request #973 from hgiesel/mathjaxerror
Render error if MathJax raises error
2021-02-03 13:09:12 +10:00
Henrik Giesel
e5587ffa59 Move copy_page to ts/copy.bzl and rename to copy_files_into_group 2021-02-02 18:20:11 +01:00
Henrik Giesel
803d6fbd3b Render error if MathJax raises error 2021-02-02 18:11:16 +01:00
Henrik Giesel
22a5db8ace Remove unused imports 2021-02-02 17:13:35 +01:00
Henrik Giesel
2483ef4517 Use new note.ephemeral_card method in clayout 2021-02-02 16:47:25 +01:00
Damien Elmes
4a5ef69068 add remaining types and disable missing types on (almost) all aqt 2021-02-03 00:00:29 +10:00
Damien Elmes
6426edb0ac more typing updates 2021-02-02 23:31:55 +10:00
Damien Elmes
4b112950b8
Merge pull request #971 from abdnh/sidebar-checkpoints
Add checkpoints for sidebar drag & drop routines
2021-02-02 22:28:53 +10:00
Damien Elmes
33319e1691
Merge pull request #970 from RumovZ/cleanup-967
Cleanup 967
2021-02-02 22:03:43 +10:00
abdo
2754464147 Add checkpoints for sidebar drag & drop routines
Also save note and reset browser model
2021-02-02 14:58:44 +03:00
Damien Elmes
7e22bc16bc fix: Qt translations not working
Will need to manually confirm this is working in the bundled builds
2021-02-02 21:12:28 +10:00
RumovZ
2499f2ae34 Remove standard button translations 2021-02-02 11:57:35 +01:00
Damien Elmes
4330ab58f5 auto-expand items while dragging 2021-02-02 20:14:14 +10:00
Damien Elmes
a50601ed46 add tag drag & drop support 2021-02-02 20:14:04 +10:00
Damien Elmes
dd54c10e71
Merge pull request #968 from abdnh/sidebar-expand-matches
Expand sidebar match trees one level
2021-02-02 19:03:04 +10:00
Damien Elmes
467064f873 collapsed->expanded in other tag uses for consistency 2021-02-02 18:52:57 +10:00
Damien Elmes
52b256663f collapsed->expanded in TagTreeNode 2021-02-02 18:52:57 +10:00
RumovZ
14775445df Add docstring to browser.__ini__ 2021-02-02 09:48:55 +01:00
RumovZ
c3ae1a3049 Disallow untyped defs for dyndeckconf 2021-02-02 09:40:05 +01:00
RumovZ
16462941ab Remove actionCreateFilteredDeck2 and use modifier 2021-02-02 09:29:09 +01:00
Damien Elmes
0bf2538989 remove sidebar margins 2021-02-02 16:35:42 +10:00
Damien Elmes
7fc32db0c9 fix: slowdowns after import; hard to read popup
QTextEdit() will pin the CPU at 100% for seconds to minutes when
fed a large string to display - work around it by switching to
QPlainTextEdit().

Also strip HTML before showing the user - easier to read, and less
text to display. And turn off word wrap, as it makes it easier to skim,
and further reduces the work the widget needs to do.

https://forums.ankiweb.net/t/big-issue-where-anki-gets-slow-when-you-import-this-deck/7050
2021-02-02 15:49:47 +10:00
abdo
ee1ed033a2 Hide sidebar items when there is no match 2021-02-02 05:41:45 +03:00
abdo
6f5d1bca3f Add more sidebar section roots 2021-02-02 04:51:45 +03:00
Damien Elmes
b7bfe58afe fix sync warning caused by mistake in typing work 2021-02-02 10:43:49 +10:00
Damien Elmes
3a8fce69dd ditch QSortFilterProxyModel in favour of our own code
Simpler and approximately twice as fast in a large collection:

old approach
search for a: 371ms
search for an: 260ms

new approach:
search for a: 171ms
search for an: 149ms

Still todo: add enum defs for the other root categories, update
the _section_root() calls, and update is_expanded() to use the new
extra types
2021-02-02 10:40:50 +10:00
RumovZ
b450c8d45c Add remaining type hints to dyndeckconf etc. 2021-02-01 23:46:56 +01:00
RumovZ
c18af2a0a9 Merge branch 'master' into dyn-deckconf 2021-02-01 23:33:41 +01:00
RumovZ
2ddb4edbb0 Rename standard buttons to have transaltions 2021-02-01 23:20:57 +01:00
RumovZ
6c7b195da8 Make browser links unfocusable
Since Enter would trigger Accept anyway, there is no point in them
having focus.
2021-02-01 21:17:15 +01:00
RumovZ
4666ba8b70 Enable renaming from dyndeck dialogue 2021-02-01 21:02:22 +01:00
RumovZ
8065e73ef8 Add cross links for second dyndeck filter 2021-02-01 19:10:05 +01:00
RumovZ
0d37254238 Style browser-from-filtered-deck button
Use theme color and add hover effect.
2021-02-01 18:01:57 +01:00
abdo
c96248d67f Expand sidebar match trees one level
See 132bb5ff36
2021-02-01 19:12:43 +03:00
Damien Elmes
a56b09b987 add a bunch of return types 2021-02-01 23:53:23 +10:00
RumovZ
4d097b995d Add button in dynDeckConf to search in browser 2021-02-01 13:55:03 +01:00
Damien Elmes
f15715fb07 add types to various other files
Mainly automated with MonkeyType
2021-02-01 22:08:56 +10:00
RumovZ
0949cdc73e Rename "Filtered Deck from Current Filter" 2021-02-01 12:09:37 +01:00
Damien Elmes
84f8d7f604 add some types to main.py 2021-02-01 20:59:18 +10:00
RumovZ
6b1d5f14e8 Change filtered-deck shortcut in browser to Ctrl+G 2021-02-01 11:59:16 +01:00
RumovZ
6de6e5f339 Make browser accept optional args and add reopen
That way, the caller doesn't have to hold a reference to the browser and
explicitly call it again, if it wants to search for something specific.
Also, if the browser was closed and opened for a single-card-search, it
now won't perform a redundant current-deck-search first.
2021-02-01 11:54:28 +01:00
Damien Elmes
98f4b3db81 add types to utils.py
The function signatures for things like getFile() are awful, but
sadly are used by a bunch of add-ons.
2021-02-01 20:23:48 +10:00
RumovZ
d2024d1d1e Fix pylints and type annotations in dyndeckconf
Also fix int representation of learning steps.
2021-02-01 09:56:10 +01:00
RumovZ
5aac81d15f Make DialogManager accept kwargs
When opening a dialogue accepting multiple optional arguments, relying
on position is error-prone and requires passing Nones to fill unused
parameter slots.
2021-02-01 08:50:19 +01:00
Damien Elmes
08b76e4489 add helper script to run mypy daemon 2021-02-01 17:29:03 +10:00
Damien Elmes
d13762bd32 add types to editor.py 2021-02-01 17:28:35 +10:00
Damien Elmes
1f6ed0739f
Merge pull request #962 from hgiesel/editordirs
Make editor a rollup package within data/web/js
2021-02-01 13:40:54 +10:00
Damien Elmes
328c86d3a5 add missing types to sidebar.py 2021-02-01 09:51:46 +10:00
Damien Elmes
66c8ee3e0a add missing types to browser.py 2021-02-01 09:39:55 +10:00
RumovZ
011b562038 Add current-filter-to-filtered-deck action 2021-01-31 23:16:49 +01:00
RumovZ
52867dfa6c Make dyndeckconf a registered dialogue 2021-01-31 22:37:08 +01:00
Henrik Giesel
70b7cbcd4a Move editor css to editor directory 2021-01-31 19:03:40 +01:00
RumovZ
0960ea6ece Rework dynndeckconf
- Handle deck building inside class. New deck is built unless caller
  passes filtered deck.
- If no deck is passed and current deck is filtered, copy settings.
- Remove exec_().
2021-01-31 18:20:47 +01:00
Henrik Giesel
2ab06a6540 Move editor to /ts/editor 2021-01-31 14:15:03 +01:00
Henrik Giesel
859a52ab15 Fix type issues 2021-01-31 13:34:39 +01:00
Henrik Giesel
33160dcb00 Make editor a rollup package 2021-01-31 13:34:37 +01:00
RumovZ
13c6921da1 Remove protobuf filters whole_col and current_deck 2021-01-31 11:12:49 +01:00
Damien Elmes
6c483bb577 add public wrappers for remaining backend functions 2021-01-31 18:56:16 +10:00
Damien Elmes
67cb147493 move rsbridge into _backend 2021-01-31 18:55:45 +10:00
Damien Elmes
9d853bbb03 start work on more clearly defining backend/protobuf boundaries
- anki._backend stores the protobuf files and rsbackend.py code
- pylib modules import protobuf messages directly from the
_pb2 files, and explicitly export any will be returned or consumed
by public pylib functions, so that calling code can import from pylib
- the "rsbackend" no longer imports and re-exports protobuf messages
- pylib can just consume them directly.
- move errors to errors.py

Still todo:

- rsbridge
- finishing the work on rsbackend, and check what we need to add
back to the original file location to avoid breaking add-ons
2021-01-31 18:55:45 +10:00
RumovZ
3e69d39a25 Add missing sidebar onClicks 2021-01-31 08:56:34 +01:00
Damien Elmes
cb805cf355 Merge branch 'more-backend-search' into main 2021-01-31 14:21:51 +10:00
Damien Elmes
126b642115 disable multiple selection for now 2021-01-31 14:02:38 +10:00
Damien Elmes
18f0b78716 disable dragging of unsupported items 2021-01-31 13:46:31 +10:00
Damien Elmes
4579740df6 support dragging multiple decks at once 2021-01-31 13:46:31 +10:00
Damien Elmes
49a40e7178 add missing check for on_done==None in with_progress() 2021-01-31 13:46:31 +10:00
Damien Elmes
28ff061c19 support drag&drop of decks in sidebar 2021-01-31 13:46:31 +10:00
Damien Elmes
8410330f94 move drag/drop deck logic to backend 2021-01-31 13:46:31 +10:00
RumovZ
9bfe8e3840 Remove search button and reword search bar hint 2021-01-30 19:23:40 +01:00
RumovZ
b0890b0e47 Manually namespace enum variants in SearchTerm
In protobuf "...enum values use C++ scoping rules, meaning that
enum values are siblings of their type, not children of it.
Therefore, [an enum variant] must be unique within [a message],
not just within [the enum.]"
So we must prefix enum variants with their enum's name, but can
also call them directly from the message namespace.
The protobuf crate is smart, though, and strips the prefixes.

(Simultaneously change some SearchTerm variant names.)
2021-01-30 17:56:29 +01:00
RumovZ
375794893f Replace leftover _named_filter with _filter_func 2021-01-30 17:39:21 +01:00
Henrik Giesel
126af1fef3 Fix focus on first field upon opening editor 2021-01-30 14:20:14 +01:00
RumovZ
9e9d8b9c7a Build list in focusCid and specify exception
model.cards may be a protobuf sequence but focusCid needs list's index
method, so convert to list, but only if needed.
2021-01-30 13:15:46 +01:00
RumovZ
5425b00d2b Import SearchTerm from collection in aqt 2021-01-30 12:51:24 +01:00
RumovZ
26e5235846 Fix type annotations in browser search 2021-01-30 11:24:33 +01:00
RumovZ
63e8b44629 Update docstrings for browser search 2021-01-30 11:05:48 +01:00
RumovZ
9c4cc88b47 Auto search and check input before model search
- Search for current deck automatically on browser setup.
- Hide current deck and current card searches.
- Check user search input before passing it on to the model, so invalid
  searches don't change TableView.
2021-01-30 10:53:42 +01:00
Damien Elmes
b66bedbc9f
Merge pull request #957 from hgiesel/fieldsshadow
Implement editor as Web Component
2021-01-30 15:13:58 +10:00
Damien Elmes
705012164b move Rating up a level
More ergonomic, and will allow reuse if we expose prop:rated in
the future.
2021-01-30 11:54:39 +10:00
Damien Elmes
cb6b88da0f simplify nid/nids searches, and ditch helper function
- IdList could be re-used for a cids: search in the future if required.
- Embedding the message means it's easy to access from Python as
an attribute of SearchTerm.
2021-01-30 11:37:00 +10:00
Damien Elmes
1adc9952f4 simplify Dupe message and ditch helper function
Calling code doesn't need to know about the existence of such helpers;
it can just rely on code completion to discover the required arguments.
2021-01-30 11:10:26 +10:00
Damien Elmes
5e6dd54c8e export SearchTerm from collection.py, and avoid exporting embedded items 2021-01-30 11:01:11 +10:00
Damien Elmes
73b897c754 rename FilterToSearchIn in backend to match frontend 2021-01-30 10:54:21 +10:00
Damien Elmes
52bac7a7a1 use a separate enum for the is:* searches 2021-01-30 10:49:00 +10:00
Damien Elmes
22b80c2dd5 combine forgot_in_days and studied_today into a more general 'rated' 2021-01-30 10:26:23 +10:00
Damien Elmes
177036d0c1
Merge pull request #958 from hgiesel/zindexedtopbar
Make sticky topbar have a positive z-index
2021-01-30 09:14:50 +10:00
RumovZ
2ca4f31fc8 Update search history only after successful search
Ergo, don't save invalid searches, but also save searches normalised so
equivalent searches get saved only once.
2021-01-29 23:05:51 +01:00
RumovZ
671c6a7b3e Rework search initialisation
- Remove _searchPrompt.
- Add placeholder prompt.
- Move search for current card from browser to caller. (Thus, support
  current card search even with opened browser.)
2021-01-29 21:07:42 +01:00
Henrik Giesel
61346cf1f7 Rename editingContainer -> editingArea; editingArea -> editable
* Custom elements are now namespaces with `anki-`
* The element names are inspired by summernote, which have the same
  naming scheme of "editingArea > editable"
2021-01-29 20:32:21 +01:00
Henrik Giesel
2e72de4af0 Reorder methods / properties 2021-01-29 20:13:02 +01:00
Henrik Giesel
e37fd2e091 Remove unnecessarily observed attribute 2021-01-29 20:11:00 +01:00
Henrik Giesel
aa924ac821 Add semicolon in js message 2021-01-29 19:48:17 +01:00
Henrik Giesel
3559834bc9 Make forEditorField more cheaper to execute by avoiding casting to Array 2021-01-29 19:38:55 +01:00
RumovZ
c299e271e8 Refactor search_string() and FilterToSearchIn
See #955.
2021-01-29 18:27:33 +01:00
Henrik Giesel
79dc0ecf86 Remove explicit ids, as they are not necessary anymore 2021-01-29 18:07:31 +01:00
Henrik Giesel
5e67e706fb No need to set initial values for editing area base CSS 2021-01-29 17:51:26 +01:00
Henrik Giesel
32ee863577 Remove checking for class names for instance checks 2021-01-29 17:41:27 +01:00
Henrik Giesel
982372beae Put HTML initialization into web component constructor
* disconnectedCallback should remove event listeners and free other resources
* attributes belong to connectedCallback
2021-01-29 15:50:34 +01:00