mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 23:12:21 -04:00
Merge branch 'main' into apkg
This commit is contained in:
commit
4837e52fe9
10 changed files with 43 additions and 31 deletions
|
@ -370,7 +370,6 @@ class AnkiPackageExporter(AnkiExporter):
|
|||
p = path.replace(".apkg", ".media.db2")
|
||||
if os.path.exists(p):
|
||||
os.unlink(p)
|
||||
os.chdir(self.mediaDir)
|
||||
shutil.rmtree(path.replace(".apkg", ".media"))
|
||||
return media
|
||||
|
||||
|
|
|
@ -309,13 +309,15 @@ class DataModel(QAbstractTableModel):
|
|||
return 0
|
||||
return self.len_columns()
|
||||
|
||||
_QFont = without_qt5_compat_wrapper(QFont)
|
||||
|
||||
def data(self, index: QModelIndex = QModelIndex(), role: int = 0) -> Any:
|
||||
if not index.isValid():
|
||||
return QVariant()
|
||||
if role == Qt.ItemDataRole.FontRole:
|
||||
if not self.column_at(index).uses_cell_font:
|
||||
return QVariant()
|
||||
qfont = QFont()
|
||||
qfont = self._QFont()
|
||||
row = self.get_row(index)
|
||||
qfont.setFamily(row.font_name)
|
||||
qfont.setPixelSize(row.font_size)
|
||||
|
|
|
@ -758,7 +758,9 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
|||
def urlToLink(self, url: str) -> str | None:
|
||||
fname = self.urlToFile(url)
|
||||
if not fname:
|
||||
return None
|
||||
return '<a href="{}">{}</a>'.format(
|
||||
url, html.escape(urllib.parse.unquote(url))
|
||||
)
|
||||
return self.fnameToLink(fname)
|
||||
|
||||
def fnameToLink(self, fname: str) -> str:
|
||||
|
@ -1261,7 +1263,7 @@ class EditorWebView(AnkiWebView):
|
|||
url = qurl.toString()
|
||||
# chrome likes to give us the URL twice with a \n
|
||||
url = url.splitlines()[0]
|
||||
buf += self.editor.urlToLink(url) or ""
|
||||
buf += self.editor.urlToLink(url)
|
||||
|
||||
return buf
|
||||
|
||||
|
@ -1279,15 +1281,8 @@ class EditorWebView(AnkiWebView):
|
|||
if extended and token.startswith("data:image/"):
|
||||
processed.append(self.editor.inlinedImageToLink(token))
|
||||
elif extended and self.editor.isURL(token):
|
||||
# if the user is pasting an image or sound link, convert it to local
|
||||
# if the user is pasting an image or sound link, convert it to local, otherwise paste as a hyperlink
|
||||
link = self.editor.urlToLink(token)
|
||||
if link:
|
||||
processed.append(link)
|
||||
else:
|
||||
# not media; add it as a normal link
|
||||
link = '<a href="{}">{}</a>'.format(
|
||||
token, html.escape(urllib.parse.unquote(token))
|
||||
)
|
||||
processed.append(link)
|
||||
else:
|
||||
token = html.escape(token).replace("\t", " " * 4)
|
||||
|
|
|
@ -14,7 +14,7 @@ import aqt.modelchooser
|
|||
from anki.errors import Interrupted
|
||||
from anki.importing.anki2 import V2ImportIntoV1
|
||||
from anki.importing.apkg import AnkiPackageImporter
|
||||
from aqt import AnkiQt, gui_hooks
|
||||
from aqt.main import AnkiQt, gui_hooks
|
||||
from aqt.operations import QueryOp
|
||||
from aqt.qt import *
|
||||
from aqt.utils import (
|
||||
|
@ -460,12 +460,13 @@ def full_apkg_import(mw: AnkiQt, file: str) -> None:
|
|||
|
||||
|
||||
def replace_with_apkg(
|
||||
mw: aqt.AnkiQt, filename: str, callback: Callable[[bool], None]
|
||||
mw: AnkiQt, filename: str, callback: Callable[[bool], None]
|
||||
) -> None:
|
||||
"""Tries to replace the provided collection with the provided backup,
|
||||
then calls the callback. True if success.
|
||||
"""
|
||||
dialog = mw.progress.start(immediate=True)
|
||||
if not (dialog := mw.progress.start(immediate=True)):
|
||||
print("No progress dialog during import; aborting will not work")
|
||||
timer = QTimer()
|
||||
timer.setSingleShot(False)
|
||||
timer.setInterval(100)
|
||||
|
|
|
@ -217,6 +217,10 @@ class QueryOp(Generic[T]):
|
|||
|
||||
def wrapped_done(future: Future) -> None:
|
||||
assert mw
|
||||
|
||||
if self._progress:
|
||||
mw.progress.finish()
|
||||
|
||||
mw._decrease_background_ops()
|
||||
# did something go wrong?
|
||||
if exception := future.exception():
|
||||
|
@ -230,11 +234,6 @@ class QueryOp(Generic[T]):
|
|||
# BaseException like SystemExit; rethrow it
|
||||
future.result()
|
||||
|
||||
result = future.result()
|
||||
try:
|
||||
self._success(result)
|
||||
finally:
|
||||
if self._progress:
|
||||
mw.progress.finish()
|
||||
self._success(future.result())
|
||||
|
||||
mw.taskman.run_in_background(wrapped_op, wrapped_done)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import os
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Callable, Union
|
||||
from typing import Callable, TypeVar, Union
|
||||
|
||||
try:
|
||||
import PyQt6
|
||||
|
@ -58,3 +58,16 @@ def qconnect(
|
|||
) -> None:
|
||||
"""Helper to work around type checking not working with signal.connect(func)."""
|
||||
signal.connect(func) # type: ignore
|
||||
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
def without_qt5_compat_wrapper(cls: _T) -> _T:
|
||||
"""Remove Qt5 compat wrapper from Qt class, if active.
|
||||
|
||||
Only needed for a few Qt APIs that deal with QVariants."""
|
||||
if fn := getattr(cls, "_without_compat_wrapper", None):
|
||||
return fn()
|
||||
else:
|
||||
return cls
|
||||
|
|
|
@ -352,7 +352,9 @@ def _instrument_type(
|
|||
class QtClassProxy(
|
||||
type, metaclass=QtClassProxyType
|
||||
): # pylint: disable=invalid-metaclass
|
||||
pass
|
||||
@staticmethod
|
||||
def _without_compat_wrapper():
|
||||
return type
|
||||
|
||||
setattr(module, type_name, QtClassProxy)
|
||||
|
||||
|
|
|
@ -330,6 +330,7 @@ class AnkiWebView(QWebEngineView):
|
|||
self._domDone = True
|
||||
self._queueAction("setHtml", html)
|
||||
self.set_open_links_externally(True)
|
||||
self.setZoomFactor(1)
|
||||
self.show()
|
||||
|
||||
def _setHtml(self, html: str) -> None:
|
||||
|
@ -681,6 +682,7 @@ html {{ {font} }}
|
|||
else:
|
||||
extra = ""
|
||||
self.hide_while_preserving_layout()
|
||||
self.setZoomFactor(1)
|
||||
self.load_url(QUrl(f"{mw.serverURL()}_anki/pages/{name}.html{extra}"))
|
||||
self.inject_dynamic_style_and_show()
|
||||
|
||||
|
|
|
@ -343,13 +343,13 @@ def build_tarball(src_path: Path, variant: str) -> None:
|
|||
subprocess.run(
|
||||
[
|
||||
"tar",
|
||||
"--zstd",
|
||||
"-I",
|
||||
"zstd -c --long -T0 -18",
|
||||
"-cf",
|
||||
dist_folder / (dest_path.name + ".tar.zst"),
|
||||
dest_path.name,
|
||||
],
|
||||
check=True,
|
||||
env=dict(ZSTD_CLEVEL="9"),
|
||||
cwd=dest_path.parent,
|
||||
)
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ img {
|
|||
max-height: 95vh;
|
||||
}
|
||||
|
||||
li {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
#_flag {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
|
@ -48,11 +52,6 @@ img {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.night-mode #typeans {
|
||||
background-color: var(--frame-bg);
|
||||
color: var(--text-fg);
|
||||
}
|
||||
|
||||
.typeGood {
|
||||
background: #afa;
|
||||
color: black;
|
||||
|
|
Loading…
Reference in a new issue