Commit graph

2851 commits

Author SHA1 Message Date
Damien Elmes
36cecfd7c7 Tweak type-answer example so users don't think the spelling is a mistake
https://github.com/ankitects/anki/pull/1954
2022-07-09 12:24:43 +10:00
Sam Penny
6be8c8e2c5 Remember previous choices in reposition dialog (#1950)
* remember previous choices in reposition dialog

* remember previous choice for randomize option as well

* fix failing test
2022-07-08 11:28:38 +10:00
Mateus Etto
aeb5ad3610 Add hook: overview_will_render_bottom (#1946) 2022-07-05 08:28:47 +10:00
Abdo
a0ded69d3a Use portable filter to match all files in getFile (#1943)
`*.*` matches files with no extensions on Windows, while it doesn't do so on
macOS.

Reference: https://doc.qt.io/qt-6/qfiledialog.html#setNameFilters
2022-07-04 09:33:20 +10:00
Sam Penny
7a7cb55771 fixed hook description (browser_will_search) (#1937)
* fixed hook description

* added name to CONTRIBUTORS
2022-07-01 10:12:27 +10:00
Mateus Etto
5f04786489 Fix Study Deck in Sway spawning tiled window instead of floating window (#1935)
* Fix Study Deck in sway spawning tiled window instead of floating window

* Update CONTRIBUTORS

* Fix format error
2022-06-27 17:27:56 +10:00
RumovZ
4eff535358 Handle note without cards in browser (#1929)
Change the IndexError to a NotFoundError which is picked up by the table
model.
2022-06-24 13:57:42 +10:00
RumovZ
ab8c7e71e8 Workaround broken alignment flags in PyQt 6.3.1 (#1922)
Closes #1921
2022-06-22 09:44:50 +10:00
Damien Elmes
92b4f68469 Prevent error when double-tapping delete key in browser
on_all_or_selected_rows_changed() unsets the editor note, but it is
called too late - by that time the note has already been deleted, and
the editor sometimes tries to save the deleted note due to an unfocus/
key timeout.

https://forums.ankiweb.net/t/two-suppr-lead-to-an-empty-warning/20860

Will need to check that this does not regression when #1691 is merged.
2022-06-20 11:07:38 +10:00
Damien Elmes
4ef9a900fe Remove redundant suffix in header key
We're already appending "Qt6"
2022-06-20 10:26:42 +10:00
Damien Elmes
2a034b7766 Add ellipsis to Forget action
https://forums.ankiweb.net/t/bug-card-browser-rmb-forget-label-should-end-with-ellipsis-because-it-displays-a-dialog/20851
2022-06-20 10:25:50 +10:00
Damien Elmes
6f5ed812f7 Work around broken headers in Qt 6.3.1
https://forums.ankiweb.net/t/anki-2-1-54-release-candidate/20861/2
2022-06-19 10:44:10 +10:00
Damien Elmes
5db0774f9b Remove CF_HTML header workaround 2022-06-18 09:56:06 +10:00
Abdo
af4f9fbaa0 Accept .zip as an alias for .ankiaddon too (#1914) 2022-06-17 11:10:29 +10:00
Abdo
37498a3456 Fix JS drop event not firing in the reviewer (#1906)
* Allow webviews to opt in to default D&D handling

* Remove redundant webview.js include

* Block default drag & drop behavior in reviewing screens

* Fix mypy error
2022-06-10 23:33:53 +10:00
Damien Elmes
eefc115f9d Clear cached flag names on sync
Closes #1907
2022-06-09 12:08:16 +10:00
RumovZ
8d2bda4fdd Add legacy importers to new import screen (#1908) 2022-06-09 10:57:29 +10:00
RumovZ
d92f8c67a2 CSV import/export fixes and features (#1898)
* Fix footer moving upwards

* Fix column detection

Was broken because escaped line breaks were not considered.
Also removes delimiter detection on `#columns:` line. User must use tabs
or set delimiter beforehand.

* Add CSV preview

* Parse `#tags column:`

* Optionally export deck and notetype with CSV

* Avoid clones in CSV export

* Prevent bottom of page appearing under footer (dae)

* Increase padding to 1em (dae)

With 0.5em, when a vertical scrollbar is shown, it sits right next to
the right edge of the content, making it look like there's no right
margin.

* Experimental changes to make table fit+scroll (dae)

- limit individual cells to 15em, and show ellipses when truncated
- limit total table width to body width, so that inner table is shown
with scrollbar
- use class rather than id - ids are bad practice in Svelte components,
as more than one may be displayed on a single page

* Skip importing foreign notes with filtered decks

Were implicitly imported into the default deck before.
Also some refactoring to fetch deck ids and names beforehand.

* Hide spacer below hidden field mapping

* Fix guid being replaced when updating note

* Fix dupe identity check

Canonify tags before checking if dupe is identical, but only add update
tags later if appropriate.

* Fix deck export for notes with missing card 1

* Fix note lines starting with `#`

csv crate doesn't support escaping a leading comment char. :(

* Support import/export of guids

* Strip HTML from preview rows

* Fix initially set deck if current is filtered

* Make isHtml toggle reactive

* Fix `html_to_text_line()` stripping sound names

* Tweak export option labels

* Switch to patched rust-csv fork

Fixes writing lines starting with `#`, so revert 5ece10ad05.

* List column options with first column field

* Fix flag for exports with HTML stripped
2022-06-09 10:28:01 +10:00
Bart Louwers
a220fde85f Update get_linux_dark_mode to use freedesktop.org standard (#1905)
* update get_linux_dark_mode to use freedesktop.org standard

* Update CONTRIBUTORS

* run formatter

* Update CONTRIBUTORS

* allow for multiple dark mode detection strategies on Linux

* string -> str

* update docstring

* Update CONTRIBUTORS
2022-06-07 09:30:42 +10:00
Damien Elmes
a4ddda844c Update regex in qt/bundle as well 2022-06-07 08:50:10 +10:00
Damien Elmes
508a60e157 Fix kwin hanging when adding new notetype
https://forums.ankiweb.net/t/bug-anki-2-1-52-crashes-after-adding-new-note-type/20284
2022-06-03 11:23:41 +10:00
Damien Elmes
1c0999e8f0 Expose new import/export code via prefs checkbox 2022-06-02 16:50:32 +10:00
RumovZ
410b8d8dee Plaintext import/export (#1850)
* Add crate csv

* Add start of csv importing on backend

* Add Menomosyne serializer

* Add csv and json importing on backend

* Add plaintext importing on frontend

* Add csv metadata extraction on backend

* Add csv importing with GUI

* Fix missing dfa file in build

Added compile_data_attr, then re-ran cargo/update.py.

* Don't use doubly buffered reader in csv

* Escape HTML entities if CSV is not HTML

Also use name 'is_html' consistently.

* Use decimal number as foreign ease (like '2.5')

* ForeignCard.ivl → ForeignCard.interval

* Only allow fixed set of CSV delimiters

* Map timestamp of ForeignCard to native due time

* Don't trim CSV records

* Document use of empty strings for defaults

* Avoid creating CardGenContexts for every note

This requires CardGenContext to be generic, so it works both with an
owned and borrowed notetype.

* Show all accepted file types  in import file picker

* Add import_json_file()

* factor → ease_factor

* delimter_from_value → delimiter_from_value

* Map columns to fields, not the other way around

* Fallback to current config for csv metadata

* Add start of new import csv screen

* Temporary fix for compilation issue on Linux/Mac

* Disable jest bazel action for import-csv

Jest fails with an error code if no tests are available, but this would
not be noticable on Windows as Jest is not run there.

* Fix field mapping issue

* Revert "Temporary fix for compilation issue on Linux/Mac"

This reverts commit 21f8a26140.

* Add HtmlSwitch and move Switch to components

* Fix spacing and make selectors consistent

* Fix shortcut tooltip

* Place import button at the top with path

* Fix meta column indices

* Remove NotetypeForString

* Fix queue and type of foreign cards

* Support different dupe resolution strategies

* Allow dupe resolution selection when importing CSV

* Test import of unnormalized text

Close  #1863.

* Fix logging of foreign notes

* Implement CSV exports

* Use db_scalar() in notes_table_len()

* Rework CSV metadata

- Notetypes and decks are either defined by a global id or by a column.
- If a notetype id is provided, its field map must also be specified.
- If a notetype column is provided, fields are now mapped by index
instead of name at import time. So the first non-meta column is used for
the first field of every note, regardless of notetype. This makes
importing easier and should improve compatiblity with files without a
notetype column.
- Ensure first field can be mapped to a column.
- Meta columns must be defined as `#[meta name]:[column index]` instead
of in the `#columns` tag.
- Column labels contain the raw names defined by the file and must be
prettified by the frontend.

* Adjust frontend to new backend column mapping

* Add force flags for is_html and delimiter

* Detect if CSV is HTML by field content

* Update dupe resolution labels

* Simplify selectors

* Fix coalescence of oneofs in TS

* Disable meta columns from selection

Plus a lot of refactoring.

* Make import button stick to the bottom

* Write delimiter and html flag into csv

* Refetch field map after notetype change

* Fix log labels for csv import

* Log notes whose deck/notetype was missing

* Fix hiding of empty log queues

* Implement adding tags to all notes of a csv

* Fix dupe resolution not being set in log

* Implement adding tags to updated notes of a csv

* Check first note field is not empty

* Temporary fix for build on Linux/Mac

* Fix inverted html check (dae)

* Remove unused ftl string

* Delimiter → Separator

* Remove commented-out line

* Don't accept .json files

* Tweak tag ftl strings

* Remove redundant blur call

* Strip sound and add spaces in csv export

* Export HTML by default

* Fix unset deck in Mnemosyne import

Also accept both numbers and strings for notetypes and decks in JSON.

* Make DupeResolution::Update the default

* Fix missing dot in extension

* Make column indices 1-based

* Remove StickContainer from TagEditor

Fixes line breaking, border and z index on ImportCsvPage.

* Assign different key combos to tag editors

* Log all updated duplicates

Add a log field for the true number of found notes.

* Show identical notes as skipped

* Split tag-editor into separate ts module (dae)

* Add progress for CSV export

* Add progress for text import

* Tidy-ups after tag-editor split (dae)

- import-csv no longer depends on editor
- remove some commented lines
2022-06-01 20:26:16 +10:00
Abdo
ff6643809f Add the media_check_did_finish hook (#1889) 2022-05-27 16:25:34 +10:00
Damien Elmes
5039db0e17 Avoid progress window pop-up when application not focused
A 10ms delay was chosen as it tends to result in the progress window
appearing immediately when clicking into the unfocused window, preventing
another action from being started before the progress window appears.

Closes #1873
2022-05-26 12:35:39 +10:00
Damien Elmes
da9e3c97ff Fix duplicate Anki icons appearing in dock
MPV was previously stored in the MacOS/ folder, which made macOS think
it should have a dock icon.

Fixes #1812
2022-05-26 11:05:36 +10:00
Damien Elmes
856b89d88e Make editor.cleanup() idempotent
Hammering the esc key as a dialog loads can cause it to be run more
than once, leading to an error message.
2022-05-25 22:04:50 +10:00
Damien Elmes
f51d6aaace Possible fix for Qt 6.3 crashes
As mentioned on #1879, the dialog.deleteLater() call appears to be
causing crashes on some systems on Qt 6.3. Explicitly destroying the page
prior to the containing webview appears to work around the issue.
2022-05-25 21:46:47 +10:00
Damien Elmes
d603fd3227 Rework display of available cards in custom study
In v3, it's more informative to show the count of child decks separately,
since increasing the limit of the current deck does not increase the limits
of child decks. When we rework the decks list in the future, a tooltip
will hopefully provide an easier way for users to see where cards are
available, and where limits are being applied.

Closes #1868
2022-05-20 17:52:02 +10:00
Abdo
6116c2d084 Add the previewer_did_init hook (#1882) 2022-05-19 11:10:12 +10:00
Abdo
5f06829be4 Add the reviewer_will_replay_recording hook (#1877) 2022-05-18 13:44:56 +10:00
RumovZ
c597ccb277 Fix #1874 (#1875)
Probably a race condition. `.get_row()` is not a reliable check for card
or note existence, because it returns from an outdated cache,
if the backend is currently blocked.
2022-05-18 13:34:51 +10:00
Henrik Giesel
da9e444cd3 Use same config for editor and reviewer Mathjax (#1865)
* Remove custom config and use tex-chtml-full for editor Mathjax

* Add mathjax package in /ts

* Share mathjax config between tex-svg and tex-chtml

* Use "[+]" in Mathjax config again

* Remove mention of MathJaxReady

* Satisfy eslint
2022-05-13 13:23:35 +10:00
Abdo
1d9699fb5b Add some helper functions to AVPlayer (#1864) 2022-05-13 13:08:05 +10:00
Abdo
bb7fc2d3d7 Add the av_player_will_play_tags hook (#1842)
A general version of the reviewer_will_play_question_sounds and reviewer_will_play_answer_sounds hooks
2022-05-09 11:08:34 +10:00
Henrik Giesel
e979d31d8b Replace sequences of whitespace into single space in AddTags (#1840) 2022-05-07 09:16:57 +10:00
Damien Elmes
e5cb6c3f8e Add more progress + abort points to export code
The old `media_files_did_export` hook has been kept around for use with
the legacy apkg exporter (an add-on uses it), and a new 
`legacy_export_progress` hook has been added so we can get progress
from the new colpkg exporter until we move over fully to the new code.
2022-05-06 15:32:23 +10:00
Damien Elmes
3e2f415617 Accept .zip as an alias for .apkg
The legacy importer does this already, because some web servers and
clients sniff the content type of .apkg files, and "helpfully" rename
them to .zip
2022-05-05 21:25:59 +10:00
Damien Elmes
b35e5af3dc Show a user-facing message instead of a traceback on invalid file type
While our importing dialog limits the types of files that can be selected,
users can also import by providing a filename on the command line.
2022-05-05 21:24:12 +10:00
Damien Elmes
33bc95a53d Support new import code in drag/drop + file double-click cases
https://forums.ankiweb.net/t/anki-2-1-52-release-candidate/19412/24
2022-05-03 14:09:40 +10:00
Matthias Metelka
d6cb4d9dd6 Fix scrollbars showing on bottom bar (#1833) 2022-05-03 13:57:33 +10:00
RumovZ
9012008529 Add apkg import/export on backend (#1743)
* Add apkg export on backend

* Filter out missing media-paths at write time

* Make TagMatcher::new() infallible

* Gather export data instead of copying directly

* Revert changes to rslib/src/tags/

* Reuse filename_is_safe/check_filename_safe()

* Accept func to produce MediaIter in export_apkg()

* Only store file folder once in MediaIter

* Use temporary tables for gathering

export_apkg() now accepts a search instead of a deck id. Decks are
gathered according to the matched notes' cards.

* Use schedule_as_new() to reset cards

* ExportData → ExchangeData

* Ignore ascii case when filtering system tags

* search_notes_cards_into_table →

search_cards_of_notes_into_table

* Start on apkg importing on backend

* Fix due dates in days for apkg export

* Refactor import-export/package

- Move media and meta code into appropriate modules.
- Normalize/check for normalization when deserializing media entries.

* Add SafeMediaEntry for deserialized MediaEntries

* Prepare media based on checksums

- Ensure all existing media files are hashed.
- Hash incoming files during preparation to detect conflicts.
- Uniquify names of conflicting files with hash (not notetype id).
- Mark media files as used while importing notes.
- Finally copy used media.

* Handle encoding in `replace_media_refs()`

* Add trait to keep down cow boilerplate

* Add notetypes immediately instaed of preparing

* Move target_col into Context

* Add notes immediately instaed of preparing

* Note id, not guid of conflicting notes

* Add import_decks()

* decks_configs → deck_configs

* Add import_deck_configs()

* Add import_cards(), import_revlog()

* Use dyn instead of generic for media_fn

Otherwise, would have to pass None with type annotation in the default
case.

* Fix signature of import_apkg()

* Fix search_cards_of_notes_into_table()

* Test new functions in text.rs

* Add roundtrip test for apkg (stub)

* Keep source id of imported cards (or skip)

* Keep source ids of imported revlog (or skip)

* Try to keep source ids of imported notes

* Make adding notetype with id undoable

* Wrap apkg import in transaction

* Keep source ids of imported deck configs (or skip)

* Handle card due dates and original due/did

* Fix importing cards/revlog

Card ids are manually uniquified.

* Factor out card importing

* Refactor card and revlog importing

* Factor out card importing

Also handle missing parents .

* Factor out note importing

* Factor out media importing

* Maybe upgrade scheduler of apkg

* Fix parent deck gathering

* Unconditionally import static media

* Fix deck importing edge cases

Test those edge cases, and add some global test helpers.

* Test note importing

* Let import_apkg() take a progress func

* Expand roundtrip apkg test

* Use fat pointer to avoid propogating generics

* Fix progress_fn type

* Expose apkg export/import on backend

* Return note log when importing apkg

* Fix archived collection name on apkg import

* Add CollectionOpWithBackendProgress

* Fix wrong Interrupted Exception being checked

* Add ClosedCollectionOp

* Add note ids to log and strip HTML

* Update progress when checking incoming media too

* Conditionally enable new importing in GUI

* Fix all_checksums() for media import

Entries of deleted files are nulled, not removed.

* Make apkg exporting on backend abortable

* Return number of notes imported from apkg

* Fix exception printing for QueryOp as well

* Add QueryOpWithBackendProgress

Also support backend exporting progress.

* Expose new apkg and colpkg exporting

* Open transaction in insert_data()

Was slowing down exporting by several orders of magnitude.

* Handle zstd-compressed apkg

* Add legacy arg to ExportAnkiPackage

Currently not exposed on the frontend

* Remove unused import in proto file

* Add symlink for typechecking of import_export_pb2

* Avoid kwargs in pb message creation, so typechecking is not lost

Protobuf's behaviour is rather subtle and I had to dig through the docs
to figure it out: set a field on a submessage to automatically assign 
the submessage to the parent, or call SetInParent() to persist a default
version of the field you specified.

* Avoid re-exporting protobuf msgs we only use internally

* Stop after one test failure

mypy often fails much faster than pylint

* Avoid an extra allocation when extracting media checksums

* Update progress after prepare_media() finishes

Otherwise the bulk of the import ends up being shown as "Checked: 0"
in the progress window.

* Show progress of note imports

Note import is the slowest part, so showing progress here makes the UI
feel more responsive.

* Reset filtered decks at import time

Before this change, filtered decks exported with scheduling remained
filtered on import, and maybe_remove_from_filtered_deck() moved cards
into them as their home deck, leading to errors during review.

We may still want to provide a way to preserve filtered decks on import,
but to do that we'll need to ensure we don't rewrite the home decks of
cards, and we'll need to ensure the home decks are included as part of
the import (or give an error if they're not).

https://github.com/ankitects/anki/pull/1743/files#r839346423

* Fix a corner-case where due dates were shifted by a day

This issue existed in the old Python code as well. We need to include
the user's UTC offset in the exported file, or days_elapsed falls back
on the v1 cutoff calculation, which may be a day earlier or later than
the v2 calculation.

* Log conflicting note in remapped nt case

* take_fields() → into_fields()

* Alias `[u8; 20]` with `Sha1Hash`

* Truncate logged fields

* Rework apkg note import tests

- Use macros for more helpful errors.
- Split monolith into unit tests.
- Fix some unknown error with the previous test along the way.
(Was failing after 969484de4388d225c9f17d94534b3ba0094c3568.)

* Fix sorting of imported decks

Also adjust the test, so it fails without the patch. It was only passing
before, because the parent deck happened to come before the
inconsistently capitalised child alphabetically. But we want all parent
decks to be imported before their child decks, so their children can
adopt their capitalisation.

* target[_id]s → existing_card[_id]s

* export_collection_extracting_media() → ...

export_into_collection_file()

* target_already_exists→card_ordinal_already_exists

* Add search_cards_of_notes_into_table.sql

* Imrove type of apkg export selector/limit

* Remove redundant call to mod_schema()

* Parent tooltips to mw

* Fix a crash when truncating note text

String::truncate() is a bit of a footgun, and I've hit this before
too :-)

* Remove ExportLimit in favour of separate classes

* Remove OpWithBackendProgress and ClosedCollectionOp

Backend progress logic is now in ProgressManager. QueryOp can be used
for running on closed collection.

Also fix aborting of colpkg exports, which slipped through in #1817.

* Tidy up import log

* Avoid QDialog.exec()

* Default to excluding scheuling for deck list deck

* Use IncrementalProgress in whole import_export code

* Compare checksums when importing colpkgs

* Avoid registering changes if hashes are not needed

* ImportProgress::Collection → ImportProgress::File

* Make downgrading apkgs depend on meta version

* Generalise IncrementableProgress

And use it in entire import_export code instead.

* Fix type complexity lint

* Take count_map for IncrementableProgress::get_inner

* Replace import/export env with Shift click

* Accept all args from update() for backend progress

* Pass fields of ProgressUpdate explicitly

* Move update_interval into IncrementableProgress

* Outsource incrementing into Incrementor

* Mutate ProgressUpdate in progress_update callback

* Switch import/export legacy toggle to profile setting

Shift would have been nice, but the existing shortcuts complicate things.
If the user triggers an import with ctrl+shift+i, shift is unlikely to
have been released by the time our code runs, meaning the user accidentally
triggers the new code. We could potentially wait a while before bringing
up the dialog, but then we're forced to guess at how long it will take the
user to release the key.

One alternative would be to use alt instead of shift, but then we need to
trigger our shortcut when that key is pressed as well, and it could
potentially cause a conflict with an add-on that already uses that
combination.

* Show extension in export dialog

* Continue to provide separate options for schema 11+18 colpkg export

* Default to colpkg export when using File>Export

* Improve appearance of combo boxes when switching between apkg/colpkg

+ Deal with long deck names

* Convert newlines to spaces when showing fields from import

Ensures each imported note appears on a separate line

* Don't separate total note count from the other summary lines

This may come down to personal preference, but I feel the other counts
are equally as important, and separating them feels like it makes it
a bit easier to ignore them.

* Fix 'deck not normal' error when importing a filtered deck for the 2nd time

* Fix [Identical] being shown on first import

* Revert "Continue to provide separate options for schema 11+18 colpkg export"

This reverts commit 8f0b2c175f.

Will use a different approach

* Move legacy support into a separate exporter option; add to apkg export

* Adjust 'too new' message to also apply to .apkg import case

* Show a better message when attempting to import new apkg into old code

Previously the user could end seeing a message like:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 1: invalid start byte

Unfortunately we can't retroactively fix this for older clients.

* Hide legacy support option in older exporting screen

* Reflect change from paths to fnames in type & name

* Make imported decks normal at once

Then skip special casing in update_deck(). Also skip updating
description if new one is empty.

Co-authored-by: Damien Elmes <gpg@ankiweb.net>
2022-05-02 21:12:46 +10:00
RumovZ
c70de3e275 Fix previewer runtime error "deleted" (#1830) 2022-05-02 10:40:44 +10:00
Damien Elmes
a0de544e2f Drop default Show Answer/Good highlight (#1820)
Feedback welcome. Discussion at
https://forums.ankiweb.net/t/2-1-5-border-around-good/19175

Partially reverts 53ceab9bd3
2022-04-27 19:26:16 +10:00
Damien Elmes
e2dcc49284 Reset zoom on page transition
https://forums.ankiweb.net/t/2-1-50-zooming-in-while-reviewing-results-in-an-unusably-huge-deck-list/19283
2022-04-22 15:45:50 +10:00
RumovZ
830cfafa04 Fix progress of chained operations (#1817)
* Fix progress of chained operations

Especially aborting colpkg import.

* Notify about missing progress dialog
2022-04-22 14:47:17 +10:00
Damien Elmes
ea87025d1a Increase compression on zstd packages 2022-04-22 13:52:24 +10:00
Abdo
05b816243b Fix pasting of local links to unsupported types that contain spaces (#1813)
This change causes local links to unsupported formats like PDF to be
handled by _processUrls() instead of _processText, converting them to
correct hyperlinks in case they contain spaces.
2022-04-21 14:10:53 +10:00
Damien Elmes
4878f15b5d Fix custom browser font not being honored
https://forums.ankiweb.net/t/on-anki-2-1-50-browser-table-font-override-is-not-respected/19259
2022-04-21 13:28:22 +10:00
Damien Elmes
3aace1a41e Update Mac build to Qt 6.3 2022-04-20 21:33:31 +10:00