Commit Graph

2670 Commits

Author SHA1 Message Date
Damien Elmes
52f17c12e0 Partially revert "Fix issue 1362 and add a default favicon.ico (#1369)"
Kept the favicon, but have reverted the rest, as it unfortunately did
not seem to prevent the issue from occurring.

Original discussion: https://github.com/ankitects/anki/pull/1369

This reverts commit 6d0f7e7f05.
2021-12-08 21:20:39 +10:00
Damien Elmes
db5117ce1a fix webviews sometimes failing to load, by enabling cache
Fixes #983

This has been a long-standing issue that was infrequent enough on
developer machines that we weren't able to get to the bottom of it before
now. As luck would have it, the new ARM build had just the right timing
for this to occur every few invocations, and I was able to narrow it down
to the call that turns off the cache.

We don't really want the cache, so this is not a great solution. But I
ran into trouble when trying to figure out a better solution:

- Calling setHttpCacheType() earlier (eg immediately after creating the
page) fails.
- It even fails if you attempt to change the setting in the shared
default profile before any webviews are loaded:

```
    def setupMainWindow(self) -> None:
        QWebEngineProfile.defaultProfile().setHttpCacheType(QWebEngineProfile.HttpCacheType.NoCache)
```

- Creating a profile separately, and passing it into QWebEnginePage()
does work. But it introduces a warning each time a webview is deallocated,
and I fear it may lead to crashes:

```
Release of profile requested but WebEnginePage still not deleted. Expect troubles !
```

I tried various combinations of parents for the profile and page, and
turning web._page into an unretained property, but could not figure it out.
Some Googling pulls up a bunch of other people who seem to have hit similar
issues with PyQt. If anyone has any ideas, they'd be welcome; in the mean
time, I guess we're better off using up some of the user's disk
space than sometimes failing to load.

The profile-in-advance code I tried is below:

```
diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py
index 1c96112d8..4f3e91284 100644
--- a/qt/aqt/webview.py
+++ b/qt/aqt/webview.py
@@ -23,9 +23,49 @@ serverbaseurl = re.compile(r"^.+:\/\/[^\/]+")
 BridgeCommandHandler = Callable[[str], Any]

+def _create_profile(parent: QObject) -> QWebEngineProfile:
+    qwebchannel = ":/qtwebchannel/qwebchannel.js"
+    jsfile = QFile(qwebchannel)
+    if not jsfile.open(QIODevice.OpenModeFlag.ReadOnly):
+        print(f"Error opening '{qwebchannel}': {jsfile.error()}", file=sys.stderr)
+    jstext = bytes(cast(bytes, jsfile.readAll())).decode("utf-8")
+    jsfile.close()
+
+    script = QWebEngineScript()
+    script.setSourceCode(
+        jstext
+        + """
+            var pycmd, bridgeCommand;
+            new QWebChannel(qt.webChannelTransport, function(channel) {
+                bridgeCommand = pycmd = function (arg, cb) {
+                    var resultCB = function (res) {
+                        // pass result back to user-provided callback
+                        if (cb) {
+                            cb(JSON.parse(res));
+                        }
+                    }
+
+                    channel.objects.py.cmd(arg, resultCB);
+                    return false;
+                }
+                pycmd("domDone");
+            });
+        """
+    )
+    script.setWorldId(QWebEngineScript.ScriptWorldId.MainWorld)
+    script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
+    script.setRunsOnSubFrames(False)
+
+    profile = QWebEngineProfile(parent)
+    profile.setHttpCacheType(QWebEngineProfile.HttpCacheType.NoCache)
+    profile.scripts().insert(script)
+    return profile
+
+
 class AnkiWebPage(QWebEnginePage):
-    def __init__(self, onBridgeCmd: BridgeCommandHandler) -> None:
-        QWebEnginePage.__init__(self)
+    def __init__(self, onBridgeCmd: BridgeCommandHandler, parent: QObject) -> None:
+        profile = _create_profile(parent)
+        QWebEnginePage.__init__(self, profile, parent)
         self._onBridgeCmd = onBridgeCmd
         self._setupBridge()
         self.open_links_externally = True
@@ -46,39 +86,6 @@ class AnkiWebPage(QWebEnginePage):
         self._channel.registerObject("py", self._bridge)
         self.setWebChannel(self._channel)

-        qwebchannel = ":/qtwebchannel/qwebchannel.js"
-        jsfile = QFile(qwebchannel)
-        if not jsfile.open(QIODevice.OpenModeFlag.ReadOnly):
-            print(f"Error opening '{qwebchannel}': {jsfile.error()}", file=sys.stderr)
-        jstext = bytes(cast(bytes, jsfile.readAll())).decode("utf-8")
-        jsfile.close()
-
-        script = QWebEngineScript()
-        script.setSourceCode(
-            jstext
-            + """
-            var pycmd, bridgeCommand;
-            new QWebChannel(qt.webChannelTransport, function(channel) {
-                bridgeCommand = pycmd = function (arg, cb) {
-                    var resultCB = function (res) {
-                        // pass result back to user-provided callback
-                        if (cb) {
-                            cb(JSON.parse(res));
-                        }
-                    }
-
-                    channel.objects.py.cmd(arg, resultCB);
-                    return false;
-                }
-                pycmd("domDone");
-            });
-        """
-        )
-        script.setWorldId(QWebEngineScript.ScriptWorldId.MainWorld)
-        script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
-        script.setRunsOnSubFrames(False)
-        self.profile().scripts().insert(script)
-
     def javaScriptConsoleMessage(
         self,
         level: QWebEnginePage.JavaScriptConsoleMessageLevel,
@@ -228,7 +235,7 @@ class AnkiWebView(QWebEngineView):
     ) -> None:
         QWebEngineView.__init__(self, parent=parent)
         self.set_title(title)
-        self._page = AnkiWebPage(self._onBridgeCmd)
+        self._page = AnkiWebPage(self._onBridgeCmd, self)
         self._page.setBackgroundColor(
             self.get_window_bg_color(theme_manager.night_mode)
@@ -242,7 +249,6 @@ class AnkiWebView(QWebEngineView):
         self.requiresCol = True
         self.setPage(self._page)

-        self._page.profile().setHttpCacheType(QWebEngineProfile.HttpCacheType.NoCache)
         self.resetHandlers()
         self.allowDrops = False
         self._filterSet = False
```
2021-12-08 21:20:39 +10:00
Damien Elmes
d87383a2d5 experimental ARM Linux packaged build 2021-12-08 20:53:46 +10:00
Damien Elmes
cad0c64105 add unbury_cards() op
https://forums.ankiweb.net/t/add-a-collection-operation-to-unbury-cards/15720
2021-12-08 09:44:47 +10:00
RumovZ
cd22485f9b
Add browser action to create note copy (#1535)
* Add browser action to create note copy

* Use new note and copy instead of using source

* Change shortcut due to Qt's Alt-Gr bug

* Add separate routine for suffixing action with ...

* Remove '...' from some translations

The convention is to add an ellipsis if more input is required to
perform the action. Whether or not the action opens a new window is not
decisive.
Sources:
https://developer.apple.com/design/human-interface-guidelines/macos/menus/menu-anatomy/
https://docs.microsoft.com/en-us/windows/win32/uxguide/cmd-toolbars
2021-12-08 08:40:48 +10:00
RumovZ
bcea43dc6a
Disable saving fullscreen geometry (#1538)
Restoring fullscreen windows is buggy.
https://forums.ankiweb.net/t/anki-2-1-50-beta/15608/39
2021-12-08 08:12:10 +10:00
nwwt
9becb4c11f
Allow <audio> to play without user interaction in accordance to autoplay setting v2 (#1539)
Adds back setting Chromium's autoplay policy according to Anki's, this time without globals.
2021-12-08 08:08:56 +10:00
Damien Elmes
0de24122ad implement a basic native macOS audio recorder
This was motivated by the fact that recording was crashing on the native
M1 build. That ended up being mostly a PEBKAC problem - turns out the
Mac Mini has no built-in microphone 🤦.

I still thinks this has some value though - it doesn't crash in such
cases, and probably doesn't suffer from the problem shown in this thread
either:

https://forums.ankiweb.net/t/anki-crashes-when-trying-to-record-on-mac/14764

For now, this is only enabled when running on arm64. If it turns out to
be reliable, it could be offered as an option on amd64 as well.
2021-12-07 18:48:24 +10:00
Damien Elmes
d9c8addbc1 switch AnkiHelper to Swift
More pleasant to work with than ObjectiveC, which will help with the
following commit.

Swift libraries weren't added to macOS until 10.14.4, so theme
autodetection will fail on 10.14.0-10.14.3. The Qt6 build will have its
minimum version bumped to 10.14.4; the Qt5 build will remain on 10.13.4.

Bazel's rules_swift doesn't currently support building Swift dylibs, so
we need to invoke swiftc directly via a genrule().
2021-12-07 18:48:24 +10:00
Matthias Metelka
924e16879f
Update about.py (#1533)
* Update about.py

* Add cqg to list

for his contributions to the community (testing, support, suggestions).

* Add the AnKing to list

for his efforts to keep add-ons compatible with new versions and popularizing Anki in the medical community via YouTube, Reddit and other social media.
2021-12-07 09:01:30 +10:00
Abdo
4571e78016
Fix error on previewer close (#1528)
_on_close was being called twice, causing an error when the destroyed
_web is accessed again.
2021-12-06 19:34:41 +10:00
Abdo
dc4fd95f24
Fix previous card info shortcut label (#1534) 2021-12-06 19:01:37 +10:00
Abdo
b3ea7288ab
Flip arrows of Bootstrap-styled <select>s for RTL langs (#1526)
* Flip arrows of Bootstrap-styled <select>s for RTL langs

* Use the dir attribute to set document direction

* Remove unused variable and fix use of CSS var
2021-12-06 18:40:26 +10:00
Damien Elmes
cee57f4cb7 work around 'which deck would you like' sticking around on Qt6/macOS
Not a problem on Qt5, and not really sure why this works 🤷
2021-12-06 18:24:38 +10:00
Hikaru Y
e8b795ba69
Fix custom CSS not being applied to scrollbars in night mode (#1525) 2021-12-05 08:20:42 +10:00
Damien Elmes
cbc4f25be7 ensure all packaged files are world-readable
https://forums.ankiweb.net/t/anki-2-1-50-beta/15608/4
2021-12-05 08:16:54 +10:00
Damien Elmes
6de2dc6cd4 place .cargo/bin at end of path when packaging
Otherwise a system-installed older Rust will override the version we
have set with cargo-env, which can break the build.
2021-12-04 16:43:56 +10:00
Damien Elmes
80e6e7ab62 tweak qrc deprecation warning 2021-12-04 14:35:49 +10:00
Damien Elmes
3868e1e4a6 improve PyQt5.Qt compatibility
- support 'from PyQt5 import Qt' case
- alias it to aqt.qt modules instead of relying on getattr, so that
'from PyQt5.Qt import *' case works.
2021-12-04 14:35:49 +10:00
Damien Elmes
61aa8a5bc9 remove enum proxy on QUrl
No add-ons appear to be using it, and it breaks a method decorated
with @pyqtSlot(QUrl) that AMBOSS (unnecessarily) uses.
2021-12-04 14:35:49 +10:00
Damien Elmes
924fd39444 apply Qt aliases after enum proxy injected
Ensures legacy enum references on a legacy alias still work.
2021-12-04 14:35:49 +10:00
Damien Elmes
c1612e641d handle add-ons attempting to import isMac/isWin from aqt.utils 2021-12-04 14:35:47 +10:00
Damien Elmes
dcfc6d73a2 fix media trash throttling; decrease delay 2021-12-04 09:10:31 +10:00
Damien Elmes
db3ce467a3 clarify QueryOp docstring
Maybe there's a better name we could use than QueryOp - suggestions
welcome.
2021-12-04 08:55:11 +10:00
Damien Elmes
5cc261fce7 use QueryOp for unused media deletion
Closes #1517
2021-12-04 08:55:11 +10:00
Damien Elmes
42455eca64 QueryOp() was attempting to open progress window on background thread 2021-12-04 08:55:11 +10:00
Matthias Metelka
3015ddd2c1
Fix bug(s) caused by deleting a notetype currently selected in AddCards (#1514)
* Remove unneeded old.note_type() call

Fixes TypeError thrown after deleting a notetype that's currently selected in the editor.

* Handle IndexError on notetype change

Occurs in the Add window when changing the notetype via NotetypeChooser from
- the notetype that's auto-selected after deleting the currently selected notetype
- to a notetype with fewer fields than the auto-selected one

* Add return to exception handler

to properly ignore the command.
2021-12-04 07:55:22 +10:00
Damien Elmes
ae29c8c333 update PyOxidizer 2021-12-03 21:00:15 +10:00
Abdo
5a3999d0c8
Adjust arrows direction for RTL layouts in previewer (#1513) 2021-11-29 12:41:08 +10:00
Hikaru Y
d2cbd15bbe
Fix memory leak in AnkiWebView (#1510) 2021-11-29 12:31:37 +10:00
RumovZ
627f910635
Remove redundant camelcase aliases (#1509) 2021-11-26 12:29:48 +10:00
Damien Elmes
b9eccec2b0 move aqt/platform.py code into theme.py
We have other platform-specific code scattered through the codebase,
and better it lives in a location where it is used.
2021-11-25 19:10:57 +10:00
Damien Elmes
9ed13eee80 convert invariant assertions to if statements
The packaged builds of 2.1.50 use python -OO, which means our assertion
statements won't be run. This is not an issue for unit tests (as we
don't run them from a packaged build), or for type assertions (which are
added for mypy's benefit), but we do need to ensure that invariant checks
are still run.
2021-11-25 17:47:50 +10:00
Damien Elmes
88392634a8 fix check for user exporting into data folder on Windows
https://forums.ankiweb.net/t/unable-to-export-colpkg-file/10527
2021-11-25 09:30:17 +10:00
Damien Elmes
ebad6ad379 update platform checks (eg isWin -> is_win) + devMode 2021-11-25 09:06:16 +10:00
Damien Elmes
9d444b40e0 avoid duplicate work in overview screen 2021-11-25 09:01:02 +10:00
Damien Elmes
f16bd9a9a8 minor docstring fix 2021-11-25 08:57:33 +10:00
Damien Elmes
f0fedf6ab8 add minimal theme detection on Linux
Closes #1116
2021-11-25 08:45:14 +10:00
RumovZ
f2173fddb0
Live theme changes (#1497)
* Allow theme change at runtime and add hook

* Save or restore default palette on theme change

* Update aqt widget styles on theme change

* styling fixes

- drop _light_palette, as default_palette serves the same purpose
- save default platform theme, and restore it when switching away
from nightmode
- update macOS light/dark mode on theme switch
- fix unreadable menus on Windows

* update night-mode classes on theme change

This is the easy part - CSS styling that uses standard_css or our
css variables should update automatically. The main remaining issue
is JS code that sets colors based on the theme at the time it's run -
eg the graph code, and the editor.

* switch night mode value on toggle

* expose current theme via a store; switch graphs to use it

https://github.com/ankitects/anki/issues/1471#issuecomment-972402492

* start using currentTheme in editor/components

This fixes basic editing - there are still components that need updating.

* add simple xcodeproj for code completion

* add helper to get currently-active system theme on macOS

* fix setCurrentTheme not being immediately available

* live update tag color

* style().name() doesn't work on Qt5

* automatic theme switching on Windows/Mac

* currentTheme -> pageTheme

* Replace `nightModeKey` with `pageTheme`

Co-authored-by: Damien Elmes <gpg@ankiweb.net>
2021-11-25 07:17:41 +10:00
Damien Elmes
7143e8f3d0 change previous card info shortcut
https://forums.ankiweb.net/t/option-i-shortcut-conflicts-with-language-input/15206
2021-11-24 15:44:25 +10:00
Damien Elmes
7f40d6d2a5 retire the v1 scheduler 2021-11-24 14:12:56 +10:00
Matthias Metelka
68092082f2
Change Notetype UI Rework (#1499)
* Enable access to old notetype name

* Set minimum height for ChangeNotetypeDialog

* Add bootstrap icons to change-notetype

* Move alert up and make it collapsible

* Tweak some CSS

- Add variables --sticky-bg and --sticky-border to StickyContainer
- Tweak base.css

* Add translatable string "(Nothing)"

* Rework ChangeNotetype screen

* Initially load option at newIndex and remaining options on focus

Optimization for big notetypes:
Should increase efficiency from O(n²) to O(n). Test on notetype with 500 templates shows significant improvement in load time (~10s down to ~1s).

* Try to satisfy rust test

* Change arrow direction depending on reading direction

+ add 0.5em top padding to main

* Create Alert.svelte

* Introduce CSS variable --pane-bg

* Revert "Initially load option at newIndex and remaining options on focus"

This reverts commit f42beee45c27dba9433d76217fb583b117fb5231.

* Final cleanup

* Refine padding/gutter
2021-11-24 12:09:55 +10:00
Damien Elmes
675155e025 minor wording tweaks and a docstring 2021-11-23 12:18:50 +10:00
evandrocoan
6d0f7e7f05
Fix issue 1362 and add a default favicon.ico (#1369) 2021-11-23 12:18:32 +10:00
Damien Elmes
18b7691e2c drop beta tag from v3 scheduler
Will exit beta when 2.1.50 is released as stable
2021-11-23 11:10:04 +10:00
Arthur Milchior
74151ef60f
Remove all_names in notetypechooser (#1501)
The only purpose is to stop having warning in my console because all_names is deprecated
2021-11-23 10:27:57 +10:00
Damien Elmes
3db3ae28af SELinux fixes
https://forums.ankiweb.net/t/anki-installer-for-linux-install-sh-should-change-file-owners-and-selinux-labels-while-installation/15143
2021-11-22 11:06:21 +10:00
Damien Elmes
26123ce229 update to edition 2021 2021-11-18 20:51:10 +10:00
RumovZ
be0fe849c5
Fix close button for add cards dialog (#1496) 2021-11-18 07:22:23 +10:00
Abdo
65d10c2765
Add hotkey to save add-on config (#1492) 2021-11-17 07:18:48 +10:00