mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
update platform checks (eg isWin -> is_win) + devMode
This commit is contained in:
parent
9d444b40e0
commit
ebad6ad379
24 changed files with 121 additions and 120 deletions
|
@ -13,7 +13,7 @@ import anki
|
||||||
from anki import card_rendering_pb2, hooks
|
from anki import card_rendering_pb2, hooks
|
||||||
from anki.models import NotetypeDict
|
from anki.models import NotetypeDict
|
||||||
from anki.template import TemplateRenderContext, TemplateRenderOutput
|
from anki.template import TemplateRenderContext, TemplateRenderOutput
|
||||||
from anki.utils import call, isMac, namedtmp, tmpdir
|
from anki.utils import call, is_mac, namedtmp, tmpdir
|
||||||
|
|
||||||
pngCommands = [
|
pngCommands = [
|
||||||
["latex", "-interaction=nonstopmode", "tmp.tex"],
|
["latex", "-interaction=nonstopmode", "tmp.tex"],
|
||||||
|
@ -29,7 +29,7 @@ svgCommands = [
|
||||||
build = True # pylint: disable=invalid-name
|
build = True # pylint: disable=invalid-name
|
||||||
|
|
||||||
# add standard tex install location to osx
|
# add standard tex install location to osx
|
||||||
if isMac:
|
if is_mac:
|
||||||
os.environ["PATH"] += ":/usr/texbin:/Library/TeX/texbin"
|
os.environ["PATH"] += ":/usr/texbin:/Library/TeX/texbin"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -212,7 +212,7 @@ def no_bundled_libs() -> Iterator[None]:
|
||||||
def call(argv: list[str], wait: bool = True, **kwargs: Any) -> int:
|
def call(argv: list[str], wait: bool = True, **kwargs: Any) -> int:
|
||||||
"Execute a command. If WAIT, return exit code."
|
"Execute a command. If WAIT, return exit code."
|
||||||
# ensure we don't open a separate window for forking process on windows
|
# ensure we don't open a separate window for forking process on windows
|
||||||
if isWin:
|
if is_win:
|
||||||
info = subprocess.STARTUPINFO() # type: ignore
|
info = subprocess.STARTUPINFO() # type: ignore
|
||||||
try:
|
try:
|
||||||
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW # type: ignore
|
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW # type: ignore
|
||||||
|
@ -245,10 +245,11 @@ def call(argv: list[str], wait: bool = True, **kwargs: Any) -> int:
|
||||||
# OS helpers
|
# OS helpers
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
isMac = sys.platform.startswith("darwin")
|
is_mac = sys.platform.startswith("darwin")
|
||||||
isWin = sys.platform.startswith("win32")
|
is_win = sys.platform.startswith("win32")
|
||||||
isLin = not isMac and not isWin
|
# also covers *BSD
|
||||||
devMode = os.getenv("ANKIDEV", "")
|
is_lin = not is_mac and not is_win
|
||||||
|
dev_mode = os.getenv("ANKIDEV", "")
|
||||||
|
|
||||||
INVALID_FILENAME_CHARS = ':*?"<>|'
|
INVALID_FILENAME_CHARS = ':*?"<>|'
|
||||||
|
|
||||||
|
@ -257,9 +258,9 @@ def invalid_filename(str: str, dirsep: bool = True) -> str | None:
|
||||||
for char in INVALID_FILENAME_CHARS:
|
for char in INVALID_FILENAME_CHARS:
|
||||||
if char in str:
|
if char in str:
|
||||||
return char
|
return char
|
||||||
if (dirsep or isWin) and "/" in str:
|
if (dirsep or is_win) and "/" in str:
|
||||||
return "/"
|
return "/"
|
||||||
elif (dirsep or not isWin) and "\\" in str:
|
elif (dirsep or not is_win) and "\\" in str:
|
||||||
return "\\"
|
return "\\"
|
||||||
elif str.strip().startswith("."):
|
elif str.strip().startswith("."):
|
||||||
return "."
|
return "."
|
||||||
|
@ -272,9 +273,9 @@ def plat_desc() -> str:
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
try:
|
try:
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
if isMac:
|
if is_mac:
|
||||||
theos = f"mac:{platform.mac_ver()[0]}"
|
theos = f"mac:{platform.mac_ver()[0]}"
|
||||||
elif isWin:
|
elif is_win:
|
||||||
theos = f"win:{platform.win32_ver()[0]}"
|
theos = f"win:{platform.win32_ver()[0]}"
|
||||||
elif system == "Linux":
|
elif system == "Linux":
|
||||||
import distro # pytype: disable=import-error # pylint: disable=import-error
|
import distro # pytype: disable=import-error # pylint: disable=import-error
|
||||||
|
|
|
@ -10,7 +10,7 @@ from anki.collection import Collection as aopen
|
||||||
from anki.dbproxy import emulate_named_args
|
from anki.dbproxy import emulate_named_args
|
||||||
from anki.lang import TR, without_unicode_isolation
|
from anki.lang import TR, without_unicode_isolation
|
||||||
from anki.stdmodels import _legacy_add_basic_model, get_stock_notetypes
|
from anki.stdmodels import _legacy_add_basic_model, get_stock_notetypes
|
||||||
from anki.utils import isWin
|
from anki.utils import is_win
|
||||||
from tests.shared import assertException, getEmptyCol
|
from tests.shared import assertException, getEmptyCol
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ def test_create_open():
|
||||||
col.close()
|
col.close()
|
||||||
|
|
||||||
# non-writeable dir
|
# non-writeable dir
|
||||||
if isWin:
|
if is_win:
|
||||||
dir = "c:\root.anki2"
|
dir = "c:\root.anki2"
|
||||||
else:
|
else:
|
||||||
dir = "/attachroot.anki2"
|
dir = "/attachroot.anki2"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import time
|
||||||
|
|
||||||
from anki.consts import MODEL_CLOZE
|
from anki.consts import MODEL_CLOZE
|
||||||
from anki.errors import NotFoundError
|
from anki.errors import NotFoundError
|
||||||
from anki.utils import isWin, strip_html
|
from anki.utils import is_win, strip_html
|
||||||
from tests.shared import getEmptyCol
|
from tests.shared import getEmptyCol
|
||||||
|
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ def test_modelChange():
|
||||||
assert note.cards()[0].id == c1.id
|
assert note.cards()[0].id == c1.id
|
||||||
# delete first card
|
# delete first card
|
||||||
map = {0: None, 1: 1}
|
map = {0: None, 1: 1}
|
||||||
if isWin:
|
if is_win:
|
||||||
# The low precision timer on Windows reveals a race condition
|
# The low precision timer on Windows reveals a race condition
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
col.models.change(basic, [note.id], basic, noop, map)
|
col.models.change(basic, [note.id], basic, noop, map)
|
||||||
|
|
|
@ -33,7 +33,7 @@ from anki._backend import RustBackend
|
||||||
from anki.buildinfo import version as _version
|
from anki.buildinfo import version as _version
|
||||||
from anki.collection import Collection
|
from anki.collection import Collection
|
||||||
from anki.consts import HELP_SITE
|
from anki.consts import HELP_SITE
|
||||||
from anki.utils import checksum, isLin, isMac
|
from anki.utils import checksum, is_lin, is_mac
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import TR, tr
|
from aqt.utils import TR, tr
|
||||||
|
@ -238,7 +238,7 @@ def setupLangAndBackend(
|
||||||
# load qt translations
|
# load qt translations
|
||||||
_qtrans = QTranslator()
|
_qtrans = QTranslator()
|
||||||
|
|
||||||
if isMac and getattr(sys, "frozen", False):
|
if is_mac and getattr(sys, "frozen", False):
|
||||||
qt_dir = os.path.join(sys.prefix, "../Resources/qt_translations")
|
qt_dir = os.path.join(sys.prefix, "../Resources/qt_translations")
|
||||||
else:
|
else:
|
||||||
if qtmajor == 5:
|
if qtmajor == 5:
|
||||||
|
@ -331,7 +331,7 @@ def parseArgs(argv: list[str]) -> tuple[argparse.Namespace, list[str]]:
|
||||||
"Returns (opts, args)."
|
"Returns (opts, args)."
|
||||||
# py2app fails to strip this in some instances, then anki dies
|
# py2app fails to strip this in some instances, then anki dies
|
||||||
# as there's no such profile
|
# as there's no such profile
|
||||||
if isMac and len(argv) > 1 and argv[1].startswith("-psn"):
|
if is_mac and len(argv) > 1 and argv[1].startswith("-psn"):
|
||||||
argv = [argv[0]]
|
argv = [argv[0]]
|
||||||
parser = argparse.ArgumentParser(description=f"Anki {appVersion}")
|
parser = argparse.ArgumentParser(description=f"Anki {appVersion}")
|
||||||
parser.usage = "%(prog)s [OPTIONS] [file to import/add-on to install]"
|
parser.usage = "%(prog)s [OPTIONS] [file to import/add-on to install]"
|
||||||
|
@ -353,13 +353,13 @@ def parseArgs(argv: list[str]) -> tuple[argparse.Namespace, list[str]]:
|
||||||
|
|
||||||
|
|
||||||
def setupGL(pm: aqt.profiles.ProfileManager) -> None:
|
def setupGL(pm: aqt.profiles.ProfileManager) -> None:
|
||||||
if isMac:
|
if is_mac:
|
||||||
return
|
return
|
||||||
|
|
||||||
driver = pm.video_driver()
|
driver = pm.video_driver()
|
||||||
|
|
||||||
# work around pyqt loading wrong GL library
|
# work around pyqt loading wrong GL library
|
||||||
if isLin:
|
if is_lin:
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
ctypes.CDLL("libGL.so.1", ctypes.RTLD_GLOBAL)
|
ctypes.CDLL("libGL.so.1", ctypes.RTLD_GLOBAL)
|
||||||
|
@ -412,11 +412,11 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
|
||||||
if driver == VideoDriver.OpenGL:
|
if driver == VideoDriver.OpenGL:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if isWin:
|
if is_win:
|
||||||
os.environ["QT_OPENGL"] = driver.value
|
os.environ["QT_OPENGL"] = driver.value
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
|
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
|
||||||
elif isLin:
|
elif is_lin:
|
||||||
os.environ["QT_XCB_FORCE_SOFTWARE_OPENGL"] = "1"
|
os.environ["QT_XCB_FORCE_SOFTWARE_OPENGL"] = "1"
|
||||||
|
|
||||||
|
|
||||||
|
@ -521,7 +521,7 @@ def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiAp
|
||||||
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
|
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isWin
|
is_win
|
||||||
and qtmajor == 5
|
and qtmajor == 5
|
||||||
and (qtminor == 14 or (qtminor == 15 and qtpoint == 0))
|
and (qtminor == 14 or (qtminor == 15 and qtpoint == 0))
|
||||||
and "QT_QPA_PLATFORM" not in os.environ
|
and "QT_QPA_PLATFORM" not in os.environ
|
||||||
|
@ -545,11 +545,11 @@ def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiAp
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# disable icons on mac; this must be done before window created
|
# disable icons on mac; this must be done before window created
|
||||||
if isMac:
|
if is_mac:
|
||||||
app.setAttribute(Qt.ApplicationAttribute.AA_DontShowIconsInMenus)
|
app.setAttribute(Qt.ApplicationAttribute.AA_DontShowIconsInMenus)
|
||||||
|
|
||||||
# disable help button in title bar on qt versions that support it
|
# disable help button in title bar on qt versions that support it
|
||||||
if isWin and qtmajor == 5 and qtminor >= 10:
|
if is_win and qtmajor == 5 and qtminor >= 10:
|
||||||
QApplication.setAttribute(Qt.AA_DisableWindowContextHelpButton) # type: ignore
|
QApplication.setAttribute(Qt.AA_DisableWindowContextHelpButton) # type: ignore
|
||||||
|
|
||||||
# proxy configured?
|
# proxy configured?
|
||||||
|
@ -606,7 +606,7 @@ def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiAp
|
||||||
backend = setupLangAndBackend(pm, app, opts.lang, pmLoadResult.firstTime)
|
backend = setupLangAndBackend(pm, app, opts.lang, pmLoadResult.firstTime)
|
||||||
|
|
||||||
driver = pm.video_driver()
|
driver = pm.video_driver()
|
||||||
if isLin and driver == VideoDriver.OpenGL:
|
if is_lin and driver == VideoDriver.OpenGL:
|
||||||
from aqt.utils import gfxDriverIsBroken
|
from aqt.utils import gfxDriverIsBroken
|
||||||
|
|
||||||
if gfxDriverIsBroken():
|
if gfxDriverIsBroken():
|
||||||
|
|
|
@ -10,7 +10,7 @@ from anki.collection import OpChanges, SearchNode
|
||||||
from anki.decks import DeckId
|
from anki.decks import DeckId
|
||||||
from anki.models import NotetypeId
|
from anki.models import NotetypeId
|
||||||
from anki.notes import Note, NoteFieldsCheckResult, NoteId
|
from anki.notes import Note, NoteFieldsCheckResult, NoteId
|
||||||
from anki.utils import html_to_text_line, isMac
|
from anki.utils import html_to_text_line, is_mac
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.deckchooser import DeckChooser
|
from aqt.deckchooser import DeckChooser
|
||||||
from aqt.notetypechooser import NotetypeChooser
|
from aqt.notetypechooser import NotetypeChooser
|
||||||
|
@ -101,7 +101,7 @@ class AddCards(QMainWindow):
|
||||||
bb.addButton(self.helpButton, QDialogButtonBox.ButtonRole.HelpRole)
|
bb.addButton(self.helpButton, QDialogButtonBox.ButtonRole.HelpRole)
|
||||||
# history
|
# history
|
||||||
b = bb.addButton(f"{tr.adding_history()} {downArrow()}", ar)
|
b = bb.addButton(f"{tr.adding_history()} {downArrow()}", ar)
|
||||||
if isMac:
|
if is_mac:
|
||||||
sc = "Ctrl+Shift+H"
|
sc = "Ctrl+Shift+H"
|
||||||
else:
|
else:
|
||||||
sc = "Ctrl+H"
|
sc = "Ctrl+H"
|
||||||
|
|
|
@ -31,7 +31,7 @@ from aqt.utils import (
|
||||||
askUser,
|
askUser,
|
||||||
disable_help_button,
|
disable_help_button,
|
||||||
getFile,
|
getFile,
|
||||||
isWin,
|
is_win,
|
||||||
openFolder,
|
openFolder,
|
||||||
openLink,
|
openLink,
|
||||||
restoreGeom,
|
restoreGeom,
|
||||||
|
@ -1528,7 +1528,7 @@ class ConfigEditor(QDialog):
|
||||||
)
|
)
|
||||||
text = gui_hooks.addon_config_editor_will_display_json(text)
|
text = gui_hooks.addon_config_editor_will_display_json(text)
|
||||||
self.form.editor.setPlainText(text)
|
self.form.editor.setPlainText(text)
|
||||||
if isMac:
|
if is_mac:
|
||||||
self.form.editor.repaint()
|
self.form.editor.repaint()
|
||||||
|
|
||||||
def onClose(self) -> None:
|
def onClose(self) -> None:
|
||||||
|
|
|
@ -15,7 +15,7 @@ from anki.errors import NotFoundError
|
||||||
from anki.lang import without_unicode_isolation
|
from anki.lang import without_unicode_isolation
|
||||||
from anki.notes import NoteId
|
from anki.notes import NoteId
|
||||||
from anki.tags import MARKED_TAG
|
from anki.tags import MARKED_TAG
|
||||||
from anki.utils import isMac
|
from anki.utils import is_mac
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.editor import Editor
|
from aqt.editor import Editor
|
||||||
from aqt.exporting import ExportDialog
|
from aqt.exporting import ExportDialog
|
||||||
|
@ -177,7 +177,7 @@ class Browser(QMainWindow):
|
||||||
qconnect(f.actionRedo.triggered, self.redo)
|
qconnect(f.actionRedo.triggered, self.redo)
|
||||||
qconnect(f.actionInvertSelection.triggered, self.table.invert_selection)
|
qconnect(f.actionInvertSelection.triggered, self.table.invert_selection)
|
||||||
qconnect(f.actionSelectNotes.triggered, self.selectNotes)
|
qconnect(f.actionSelectNotes.triggered, self.selectNotes)
|
||||||
if not isMac:
|
if not is_mac:
|
||||||
f.actionClose.setVisible(False)
|
f.actionClose.setVisible(False)
|
||||||
qconnect(f.actionCreateFilteredDeck.triggered, self.createFilteredDeck)
|
qconnect(f.actionCreateFilteredDeck.triggered, self.createFilteredDeck)
|
||||||
f.actionCreateFilteredDeck.setShortcuts(["Ctrl+G", "Ctrl+Alt+G"])
|
f.actionCreateFilteredDeck.setShortcuts(["Ctrl+G", "Ctrl+Alt+G"])
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Copyright: Ankitects Pty Ltd and contributors
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
from anki.utils import isMac
|
from anki.utils import is_mac
|
||||||
from aqt.theme import theme_manager
|
from aqt.theme import theme_manager
|
||||||
|
|
||||||
|
|
||||||
def _want_right_border() -> bool:
|
def _want_right_border() -> bool:
|
||||||
return not isMac or theme_manager.night_mode
|
return not is_mac or theme_manager.night_mode
|
||||||
|
|
||||||
|
|
||||||
from .item import SidebarItem, SidebarItemType
|
from .item import SidebarItem, SidebarItemType
|
||||||
|
|
|
@ -10,7 +10,7 @@ from anki.cards import Card, CardId
|
||||||
from anki.collection import Collection, Config, OpChanges
|
from anki.collection import Collection, Config, OpChanges
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.notes import Note, NoteId
|
from anki.notes import Note, NoteId
|
||||||
from anki.utils import isWin
|
from anki.utils import is_win
|
||||||
from aqt import colors, gui_hooks
|
from aqt import colors, gui_hooks
|
||||||
from aqt.browser.table import Columns, ItemId, SearchContext
|
from aqt.browser.table import Columns, ItemId, SearchContext
|
||||||
from aqt.browser.table.model import DataModel
|
from aqt.browser.table.model import DataModel
|
||||||
|
@ -375,7 +375,7 @@ class Table:
|
||||||
def _setup_headers(self) -> None:
|
def _setup_headers(self) -> None:
|
||||||
vh = self._view.verticalHeader()
|
vh = self._view.verticalHeader()
|
||||||
hh = self._view.horizontalHeader()
|
hh = self._view.horizontalHeader()
|
||||||
if not isWin:
|
if not is_win:
|
||||||
vh.hide()
|
vh.hide()
|
||||||
hh.show()
|
hh.show()
|
||||||
hh.setHighlightSections(False)
|
hh.setHighlightSections(False)
|
||||||
|
|
|
@ -29,7 +29,7 @@ from anki.consts import MODEL_CLOZE
|
||||||
from anki.hooks import runFilter
|
from anki.hooks import runFilter
|
||||||
from anki.httpclient import HttpClient
|
from anki.httpclient import HttpClient
|
||||||
from anki.notes import Note, NoteFieldsCheckResult
|
from anki.notes import Note, NoteFieldsCheckResult
|
||||||
from anki.utils import checksum, isLin, isWin, namedtmp
|
from anki.utils import checksum, is_lin, is_win, namedtmp
|
||||||
from aqt import AnkiQt, colors, gui_hooks
|
from aqt import AnkiQt, colors, gui_hooks
|
||||||
from aqt.operations import QueryOp
|
from aqt.operations import QueryOp
|
||||||
from aqt.operations.note import update_note
|
from aqt.operations.note import update_note
|
||||||
|
@ -331,7 +331,7 @@ noteEditorPromise.then(noteEditor => noteEditor.toolbar.toolbar.appendGroup({{
|
||||||
parent=self.parentWindow,
|
parent=self.parentWindow,
|
||||||
fill_empty=False,
|
fill_empty=False,
|
||||||
)
|
)
|
||||||
if isWin:
|
if is_win:
|
||||||
self.parentWindow.activateWindow()
|
self.parentWindow.activateWindow()
|
||||||
|
|
||||||
# JS->Python bridge
|
# JS->Python bridge
|
||||||
|
@ -988,7 +988,7 @@ noteEditorPromise.then(noteEditor => noteEditor.toolbar.toolbar.appendGroup({{
|
||||||
# choose new colour
|
# choose new colour
|
||||||
@deprecated(info=_js_legacy)
|
@deprecated(info=_js_legacy)
|
||||||
def onChangeCol(self) -> None:
|
def onChangeCol(self) -> None:
|
||||||
if isLin:
|
if is_lin:
|
||||||
new = QColorDialog.getColor(
|
new = QColorDialog.getColor(
|
||||||
QColor(self.fcolour),
|
QColor(self.fcolour),
|
||||||
None,
|
None,
|
||||||
|
@ -1277,7 +1277,7 @@ class EditorWebView(AnkiWebView):
|
||||||
# add a comment in the clipboard html so we can tell text is copied
|
# add a comment in the clipboard html so we can tell text is copied
|
||||||
# from us and doesn't need to be stripped
|
# from us and doesn't need to be stripped
|
||||||
clip = self.editor.mw.app.clipboard()
|
clip = self.editor.mw.app.clipboard()
|
||||||
if not isMac and not clip.ownsClipboard():
|
if not is_mac and not clip.ownsClipboard():
|
||||||
return
|
return
|
||||||
mime = clip.mimeData()
|
mime = clip.mimeData()
|
||||||
if not mime.hasHtml():
|
if not mime.hasHtml():
|
||||||
|
|
|
@ -31,7 +31,7 @@ from anki.decks import DeckDict, DeckId
|
||||||
from anki.hooks import runHook
|
from anki.hooks import runHook
|
||||||
from anki.notes import NoteId
|
from anki.notes import NoteId
|
||||||
from anki.sound import AVTag, SoundOrVideoTag
|
from anki.sound import AVTag, SoundOrVideoTag
|
||||||
from anki.utils import devMode, ids2str, int_time, isLin, isMac, isWin, split_fields
|
from anki.utils import dev_mode, ids2str, int_time, is_lin, is_mac, is_win, split_fields
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.addons import DownloadLogEntry, check_and_prompt_for_updates, show_log_to_user
|
from aqt.addons import DownloadLogEntry, check_and_prompt_for_updates, show_log_to_user
|
||||||
from aqt.dbcheck import check_db
|
from aqt.dbcheck import check_db
|
||||||
|
@ -125,7 +125,7 @@ class AnkiQt(QMainWindow):
|
||||||
self.onAppMsg(args[0])
|
self.onAppMsg(args[0])
|
||||||
# Load profile in a timer so we can let the window finish init and not
|
# Load profile in a timer so we can let the window finish init and not
|
||||||
# close on profile load error.
|
# close on profile load error.
|
||||||
if isWin:
|
if is_win:
|
||||||
fn = self.setupProfileAfterWebviewsLoaded
|
fn = self.setupProfileAfterWebviewsLoaded
|
||||||
else:
|
else:
|
||||||
fn = self.setupProfile
|
fn = self.setupProfile
|
||||||
|
@ -194,7 +194,7 @@ class AnkiQt(QMainWindow):
|
||||||
|
|
||||||
def setup_shortcuts(self) -> None:
|
def setup_shortcuts(self) -> None:
|
||||||
QShortcut(
|
QShortcut(
|
||||||
QKeySequence("Ctrl+Meta+F" if isMac else "F11"),
|
QKeySequence("Ctrl+Meta+F" if is_mac else "F11"),
|
||||||
self,
|
self,
|
||||||
self.on_toggle_fullscreen,
|
self.on_toggle_fullscreen,
|
||||||
).setContext(Qt.ShortcutContext.ApplicationShortcut)
|
).setContext(Qt.ShortcutContext.ApplicationShortcut)
|
||||||
|
@ -557,7 +557,7 @@ class AnkiQt(QMainWindow):
|
||||||
corrupt = False
|
corrupt = False
|
||||||
try:
|
try:
|
||||||
self.maybeOptimize()
|
self.maybeOptimize()
|
||||||
if not devMode:
|
if not dev_mode:
|
||||||
corrupt = self.col.db.scalar("pragma quick_check") != "ok"
|
corrupt = self.col.db.scalar("pragma quick_check") != "ok"
|
||||||
except:
|
except:
|
||||||
corrupt = True
|
corrupt = True
|
||||||
|
@ -611,7 +611,7 @@ class AnkiQt(QMainWindow):
|
||||||
assert not self.col or not self.col.db
|
assert not self.col or not self.col.db
|
||||||
|
|
||||||
nbacks = self.pm.profile["numBackups"]
|
nbacks = self.pm.profile["numBackups"]
|
||||||
if not nbacks or devMode:
|
if not nbacks or dev_mode:
|
||||||
return
|
return
|
||||||
dir = self.pm.backupFolder()
|
dir = self.pm.backupFolder()
|
||||||
path = self.pm.collectionPath()
|
path = self.pm.collectionPath()
|
||||||
|
@ -845,7 +845,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
self.form.centralwidget.setLayout(self.mainLayout)
|
self.form.centralwidget.setLayout(self.mainLayout)
|
||||||
|
|
||||||
# force webengine processes to load before cwd is changed
|
# force webengine processes to load before cwd is changed
|
||||||
if isWin:
|
if is_win:
|
||||||
for webview in self.web, self.bottomWeb:
|
for webview in self.web, self.bottomWeb:
|
||||||
webview.force_load_hack()
|
webview.force_load_hack()
|
||||||
|
|
||||||
|
@ -1005,7 +1005,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
|
|
||||||
def setupStyle(self) -> None:
|
def setupStyle(self) -> None:
|
||||||
theme_manager.apply_style()
|
theme_manager.apply_style()
|
||||||
if isLin:
|
if is_lin:
|
||||||
# On Linux, the check requires invoking an external binary,
|
# On Linux, the check requires invoking an external binary,
|
||||||
# which we don't want to be doing frequently
|
# which we don't want to be doing frequently
|
||||||
interval_secs = 300
|
interval_secs = 300
|
||||||
|
@ -1260,7 +1260,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
aqt.update.showMessages(self, data)
|
aqt.update.showMessages(self, data)
|
||||||
|
|
||||||
def clockIsOff(self, diff: int) -> None:
|
def clockIsOff(self, diff: int) -> None:
|
||||||
if devMode:
|
if dev_mode:
|
||||||
print("clock is off; ignoring")
|
print("clock is off; ignoring")
|
||||||
return
|
return
|
||||||
diffText = tr.qt_misc_second(count=diff)
|
diffText = tr.qt_misc_second(count=diff)
|
||||||
|
@ -1560,14 +1560,14 @@ title="{}" {}>{}</button>""".format(
|
||||||
|
|
||||||
def setupSystemSpecific(self) -> None:
|
def setupSystemSpecific(self) -> None:
|
||||||
self.hideMenuAccels = False
|
self.hideMenuAccels = False
|
||||||
if isMac:
|
if is_mac:
|
||||||
# mac users expect a minimize option
|
# mac users expect a minimize option
|
||||||
self.minimizeShortcut = QShortcut("Ctrl+M", self)
|
self.minimizeShortcut = QShortcut("Ctrl+M", self)
|
||||||
qconnect(self.minimizeShortcut.activated, self.onMacMinimize)
|
qconnect(self.minimizeShortcut.activated, self.onMacMinimize)
|
||||||
self.hideMenuAccels = True
|
self.hideMenuAccels = True
|
||||||
self.maybeHideAccelerators()
|
self.maybeHideAccelerators()
|
||||||
self.hideStatusTips()
|
self.hideStatusTips()
|
||||||
elif isWin:
|
elif is_win:
|
||||||
# make sure ctypes is bundled
|
# make sure ctypes is bundled
|
||||||
from ctypes import windll, wintypes # type: ignore
|
from ctypes import windll, wintypes # type: ignore
|
||||||
|
|
||||||
|
@ -1627,7 +1627,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
# raise window
|
# raise window
|
||||||
if isWin:
|
if is_win:
|
||||||
# on windows we can raise the window by minimizing and restoring
|
# on windows we can raise the window by minimizing and restoring
|
||||||
self.showMinimized()
|
self.showMinimized()
|
||||||
self.setWindowState(Qt.WindowState.WindowActive)
|
self.setWindowState(Qt.WindowState.WindowActive)
|
||||||
|
|
|
@ -30,7 +30,7 @@ from anki.collection import GraphPreferences, OpChanges
|
||||||
from anki.decks import UpdateDeckConfigs
|
from anki.decks import UpdateDeckConfigs
|
||||||
from anki.models import NotetypeNames
|
from anki.models import NotetypeNames
|
||||||
from anki.scheduler.v3 import NextStates
|
from anki.scheduler.v3 import NextStates
|
||||||
from anki.utils import devMode, from_json_bytes
|
from anki.utils import dev_mode, from_json_bytes
|
||||||
from aqt.changenotetype import ChangeNotetypeDialog
|
from aqt.changenotetype import ChangeNotetypeDialog
|
||||||
from aqt.deckoptions import DeckOptionsDialog
|
from aqt.deckoptions import DeckOptionsDialog
|
||||||
from aqt.operations.deck import update_deck_configs
|
from aqt.operations.deck import update_deck_configs
|
||||||
|
@ -87,7 +87,7 @@ class MediaServer(threading.Thread):
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
try:
|
try:
|
||||||
if devMode:
|
if dev_mode:
|
||||||
# idempotent if logging has already been set up
|
# idempotent if logging has already been set up
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
logging.getLogger("waitress").setLevel(logging.ERROR)
|
logging.getLogger("waitress").setLevel(logging.ERROR)
|
||||||
|
@ -100,7 +100,7 @@ class MediaServer(threading.Thread):
|
||||||
port=desired_port,
|
port=desired_port,
|
||||||
clear_untrusted_proxy_headers=True,
|
clear_untrusted_proxy_headers=True,
|
||||||
)
|
)
|
||||||
if devMode:
|
if dev_mode:
|
||||||
print(
|
print(
|
||||||
"Serving on http://%s:%s"
|
"Serving on http://%s:%s"
|
||||||
% (self.server.effective_host, self.server.effective_port) # type: ignore
|
% (self.server.effective_host, self.server.effective_port) # type: ignore
|
||||||
|
@ -163,7 +163,7 @@ class MediaServer(threading.Thread):
|
||||||
return 0
|
return 0
|
||||||
# https://github.com/Pylons/webtest/blob/4b8a3ebf984185ff4fefb31b4d0cf82682e1fcf7/webtest/http.py#L123-L132
|
# https://github.com/Pylons/webtest/blob/4b8a3ebf984185ff4fefb31b4d0cf82682e1fcf7/webtest/http.py#L123-L132
|
||||||
for index in range(retries):
|
for index in range(retries):
|
||||||
if devMode or index > 0:
|
if dev_mode or index > 0:
|
||||||
print(
|
print(
|
||||||
f"{datetime.datetime.now()} awaiting media server on {host}:{port}..."
|
f"{datetime.datetime.now()} awaiting media server on {host}:{port}..."
|
||||||
)
|
)
|
||||||
|
@ -236,7 +236,7 @@ def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
if devMode:
|
if dev_mode:
|
||||||
print(
|
print(
|
||||||
"Caught HTTP server exception,\n%s"
|
"Caught HTTP server exception,\n%s"
|
||||||
% "".join(traceback.format_exception(*sys.exc_info())),
|
% "".join(traceback.format_exception(*sys.exc_info())),
|
||||||
|
@ -260,7 +260,7 @@ def _builtin_data(path: str) -> bytes:
|
||||||
with open(full_path, "rb") as f:
|
with open(full_path, "rb") as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
else:
|
else:
|
||||||
if isWin and not getattr(sys, "frozen", False):
|
if is_win and not getattr(sys, "frozen", False):
|
||||||
# default Python resource loader expects backslashes on Windows
|
# default Python resource loader expects backslashes on Windows
|
||||||
path = path.replace("/", "\\")
|
path = path.replace("/", "\\")
|
||||||
reader = aqt.__loader__.get_resource_reader("aqt") # type: ignore
|
reader = aqt.__loader__.get_resource_reader("aqt") # type: ignore
|
||||||
|
@ -281,7 +281,7 @@ def _handle_builtin_file_request(request: BundledFileRequest) -> Response:
|
||||||
HTTPStatus.NOT_FOUND,
|
HTTPStatus.NOT_FOUND,
|
||||||
)
|
)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
if devMode:
|
if dev_mode:
|
||||||
print(
|
print(
|
||||||
"Caught HTTP server exception,\n%s"
|
"Caught HTTP server exception,\n%s"
|
||||||
% "".join(traceback.format_exception(*sys.exc_info())),
|
% "".join(traceback.format_exception(*sys.exc_info())),
|
||||||
|
@ -299,7 +299,7 @@ def _handle_builtin_file_request(request: BundledFileRequest) -> Response:
|
||||||
@app.route("/<path:pathin>", methods=["GET", "POST"])
|
@app.route("/<path:pathin>", methods=["GET", "POST"])
|
||||||
def handle_request(pathin: str) -> Response:
|
def handle_request(pathin: str) -> Response:
|
||||||
request = _extract_request(pathin)
|
request = _extract_request(pathin)
|
||||||
if devMode:
|
if dev_mode:
|
||||||
print(f"{time.time():.3f} {flask.request.method} /{pathin}")
|
print(f"{time.time():.3f} {flask.request.method} /{pathin}")
|
||||||
|
|
||||||
if isinstance(request, NotFound):
|
if isinstance(request, NotFound):
|
||||||
|
@ -383,7 +383,7 @@ def _extract_addon_request(path: str) -> LocalFileRequest | NotFound | None:
|
||||||
try:
|
try:
|
||||||
manager = aqt.mw.addonManager
|
manager = aqt.mw.addonManager
|
||||||
except AttributeError as error:
|
except AttributeError as error:
|
||||||
if devMode:
|
if dev_mode:
|
||||||
print(f"_redirectWebExports: {error}")
|
print(f"_redirectWebExports: {error}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ from distutils.spawn import ( # pylint: disable=import-error,no-name-in-module
|
||||||
from queue import Empty, Full, Queue
|
from queue import Empty, Full, Queue
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from anki.utils import isWin
|
from anki.utils import is_win
|
||||||
|
|
||||||
|
|
||||||
class MPVError(Exception):
|
class MPVError(Exception):
|
||||||
|
@ -65,7 +65,7 @@ class MPVTimeoutError(MPVError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
# pylint: disable=import-error
|
# pylint: disable=import-error
|
||||||
import pywintypes
|
import pywintypes
|
||||||
import win32file # pytype: disable=import-error
|
import win32file # pytype: disable=import-error
|
||||||
|
@ -142,7 +142,7 @@ class MPVBase:
|
||||||
"""Create a random socket filename which we pass to mpv with the
|
"""Create a random socket filename which we pass to mpv with the
|
||||||
--input-unix-socket option.
|
--input-unix-socket option.
|
||||||
"""
|
"""
|
||||||
if isWin:
|
if is_win:
|
||||||
self._sock_filename = "ankimpv"
|
self._sock_filename = "ankimpv"
|
||||||
return
|
return
|
||||||
fd, self._sock_filename = tempfile.mkstemp(prefix="mpv.")
|
fd, self._sock_filename = tempfile.mkstemp(prefix="mpv.")
|
||||||
|
@ -157,7 +157,7 @@ class MPVBase:
|
||||||
while self.is_running() and time.time() < start + 10:
|
while self.is_running() and time.time() < start + 10:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
# named pipe
|
# named pipe
|
||||||
try:
|
try:
|
||||||
self._sock = win32file.CreateFile(
|
self._sock = win32file.CreateFile(
|
||||||
|
@ -228,7 +228,7 @@ class MPVBase:
|
||||||
"""
|
"""
|
||||||
buf = b""
|
buf = b""
|
||||||
while not self._stop_event.is_set():
|
while not self._stop_event.is_set():
|
||||||
if isWin:
|
if is_win:
|
||||||
try:
|
try:
|
||||||
(n, b) = win32file.ReadFile(self._sock, 4096)
|
(n, b) = win32file.ReadFile(self._sock, 4096)
|
||||||
buf += b
|
buf += b
|
||||||
|
@ -327,7 +327,7 @@ class MPVBase:
|
||||||
raise MPVTimeoutError("unable to put request")
|
raise MPVTimeoutError("unable to put request")
|
||||||
|
|
||||||
# Write the message data to the socket.
|
# Write the message data to the socket.
|
||||||
if isWin:
|
if is_win:
|
||||||
win32file.WriteFile(self._sock, data)
|
win32file.WriteFile(self._sock, data)
|
||||||
else:
|
else:
|
||||||
while data:
|
while data:
|
||||||
|
|
|
@ -40,14 +40,14 @@ import anki.sync
|
||||||
import anki.rsbackend
|
import anki.rsbackend
|
||||||
|
|
||||||
# platform-specifics
|
# platform-specifics
|
||||||
from anki.utils import isLin, isMac, isWin
|
from anki.utils import is_lin, is_mac, is_win
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
# external module access
|
# external module access
|
||||||
import pythoncom
|
import pythoncom
|
||||||
import pywintypes
|
import pywintypes
|
||||||
import win32com
|
import win32com
|
||||||
|
|
||||||
if isLin:
|
if is_lin:
|
||||||
# file locking
|
# file locking
|
||||||
import fcntl
|
import fcntl
|
||||||
|
|
|
@ -11,12 +11,12 @@ import sys
|
||||||
from ctypes import CDLL
|
from ctypes import CDLL
|
||||||
|
|
||||||
import aqt.utils
|
import aqt.utils
|
||||||
from anki.utils import isLin, isMac, isWin
|
from anki.utils import is_lin, is_mac, is_win
|
||||||
|
|
||||||
|
|
||||||
def get_windows_dark_mode() -> bool:
|
def get_windows_dark_mode() -> bool:
|
||||||
"True if Windows system is currently in dark mode."
|
"True if Windows system is currently in dark mode."
|
||||||
if not isWin:
|
if not is_win:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from winreg import ( # pylint: disable=import-error
|
from winreg import ( # pylint: disable=import-error
|
||||||
|
@ -34,7 +34,7 @@ def get_windows_dark_mode() -> bool:
|
||||||
|
|
||||||
def set_macos_dark_mode(enabled: bool) -> bool:
|
def set_macos_dark_mode(enabled: bool) -> bool:
|
||||||
"True if setting successful."
|
"True if setting successful."
|
||||||
if not isMac:
|
if not is_mac:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
_ankihelper().set_darkmode_enabled(enabled)
|
_ankihelper().set_darkmode_enabled(enabled)
|
||||||
|
@ -47,7 +47,7 @@ def set_macos_dark_mode(enabled: bool) -> bool:
|
||||||
|
|
||||||
def get_macos_dark_mode() -> bool:
|
def get_macos_dark_mode() -> bool:
|
||||||
"True if macOS system is currently in dark mode."
|
"True if macOS system is currently in dark mode."
|
||||||
if not isMac:
|
if not is_mac:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
return _ankihelper().system_is_dark()
|
return _ankihelper().system_is_dark()
|
||||||
|
@ -60,7 +60,7 @@ def get_macos_dark_mode() -> bool:
|
||||||
def get_linux_dark_mode() -> bool:
|
def get_linux_dark_mode() -> bool:
|
||||||
"""True if Linux system is in dark mode.
|
"""True if Linux system is in dark mode.
|
||||||
This only works if the GTK theme name contains '-dark'"""
|
This only works if the GTK theme name contains '-dark'"""
|
||||||
if not isLin:
|
if not is_lin:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
process = subprocess.run(
|
process = subprocess.run(
|
||||||
|
|
|
@ -295,12 +295,12 @@ def video_driver_name_for_platform(driver: VideoDriver) -> str:
|
||||||
if driver == VideoDriver.ANGLE:
|
if driver == VideoDriver.ANGLE:
|
||||||
return tr.preferences_video_driver_angle()
|
return tr.preferences_video_driver_angle()
|
||||||
elif driver == VideoDriver.Software:
|
elif driver == VideoDriver.Software:
|
||||||
if isMac:
|
if is_mac:
|
||||||
return tr.preferences_video_driver_software_mac()
|
return tr.preferences_video_driver_software_mac()
|
||||||
else:
|
else:
|
||||||
return tr.preferences_video_driver_software_other()
|
return tr.preferences_video_driver_software_other()
|
||||||
else:
|
else:
|
||||||
if isMac:
|
if is_mac:
|
||||||
return tr.preferences_video_driver_opengl_mac()
|
return tr.preferences_video_driver_opengl_mac()
|
||||||
else:
|
else:
|
||||||
return tr.preferences_video_driver_opengl_other()
|
return tr.preferences_video_driver_opengl_other()
|
||||||
|
|
|
@ -20,7 +20,7 @@ from anki.collection import Collection
|
||||||
from anki.db import DB
|
from anki.db import DB
|
||||||
from anki.lang import without_unicode_isolation
|
from anki.lang import without_unicode_isolation
|
||||||
from anki.sync import SyncAuth
|
from anki.sync import SyncAuth
|
||||||
from anki.utils import int_time, isMac, isWin
|
from anki.utils import int_time, is_mac, is_win
|
||||||
from aqt import appHelpSite
|
from aqt import appHelpSite
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.theme import Theme
|
from aqt.theme import Theme
|
||||||
|
@ -39,20 +39,20 @@ class VideoDriver(Enum):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def default_for_platform() -> VideoDriver:
|
def default_for_platform() -> VideoDriver:
|
||||||
if isMac:
|
if is_mac:
|
||||||
return VideoDriver.OpenGL
|
return VideoDriver.OpenGL
|
||||||
else:
|
else:
|
||||||
return VideoDriver.Software
|
return VideoDriver.Software
|
||||||
|
|
||||||
def constrained_to_platform(self) -> VideoDriver:
|
def constrained_to_platform(self) -> VideoDriver:
|
||||||
if self == VideoDriver.ANGLE and not isWin:
|
if self == VideoDriver.ANGLE and not is_win:
|
||||||
return VideoDriver.Software
|
return VideoDriver.Software
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def next(self) -> VideoDriver:
|
def next(self) -> VideoDriver:
|
||||||
if self == VideoDriver.Software:
|
if self == VideoDriver.Software:
|
||||||
return VideoDriver.OpenGL
|
return VideoDriver.OpenGL
|
||||||
elif self == VideoDriver.OpenGL and isWin:
|
elif self == VideoDriver.OpenGL and is_win:
|
||||||
return VideoDriver.ANGLE
|
return VideoDriver.ANGLE
|
||||||
else:
|
else:
|
||||||
return VideoDriver.Software
|
return VideoDriver.Software
|
||||||
|
@ -60,7 +60,7 @@ class VideoDriver(Enum):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def all_for_platform() -> list[VideoDriver]:
|
def all_for_platform() -> list[VideoDriver]:
|
||||||
all = [VideoDriver.OpenGL]
|
all = [VideoDriver.OpenGL]
|
||||||
if isWin:
|
if is_win:
|
||||||
all.append(VideoDriver.ANGLE)
|
all.append(VideoDriver.ANGLE)
|
||||||
all.append(VideoDriver.Software)
|
all.append(VideoDriver.Software)
|
||||||
return all
|
return all
|
||||||
|
@ -340,11 +340,11 @@ class ProfileManager:
|
||||||
self.ensureBaseExists()
|
self.ensureBaseExists()
|
||||||
|
|
||||||
def _defaultBase(self) -> str:
|
def _defaultBase(self) -> str:
|
||||||
if isWin:
|
if is_win:
|
||||||
from aqt.winpaths import get_appdata
|
from aqt.winpaths import get_appdata
|
||||||
|
|
||||||
return os.path.join(get_appdata(), "Anki2")
|
return os.path.join(get_appdata(), "Anki2")
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
return os.path.expanduser("~/Library/Application Support/Anki2")
|
return os.path.expanduser("~/Library/Application Support/Anki2")
|
||||||
else:
|
else:
|
||||||
dataDir = os.environ.get(
|
dataDir = os.environ.get(
|
||||||
|
|
|
@ -20,7 +20,7 @@ else:
|
||||||
from . import qt5_compat # needs to be imported first
|
from . import qt5_compat # needs to be imported first
|
||||||
from .qt6 import *
|
from .qt6 import *
|
||||||
|
|
||||||
from anki.utils import isMac, isWin
|
from anki.utils import is_mac, is_win
|
||||||
|
|
||||||
# fix buggy ubuntu12.04 display of language selector
|
# fix buggy ubuntu12.04 display of language selector
|
||||||
os.environ["LIBOVERLAY_SCROLLBAR"] = "0"
|
os.environ["LIBOVERLAY_SCROLLBAR"] = "0"
|
||||||
|
|
|
@ -23,7 +23,7 @@ import aqt
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.sound import AV_REF_RE, AVTag, SoundOrVideoTag
|
from anki.sound import AV_REF_RE, AVTag, SoundOrVideoTag
|
||||||
from anki.utils import isLin, isMac, isWin, namedtmp
|
from anki.utils import is_lin, is_mac, is_win, namedtmp
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.mpv import MPV, MPVBase, MPVCommandError
|
from aqt.mpv import MPV, MPVBase, MPVCommandError
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -235,7 +235,7 @@ def _packagedCmd(cmd: list[str]) -> tuple[Any, dict[str, str]]:
|
||||||
if "LD_LIBRARY_PATH" in env:
|
if "LD_LIBRARY_PATH" in env:
|
||||||
del env["LD_LIBRARY_PATH"]
|
del env["LD_LIBRARY_PATH"]
|
||||||
|
|
||||||
packaged_path = Path(sys.prefix) / "audio" / (cmd[0] + (".exe" if isWin else ""))
|
packaged_path = Path(sys.prefix) / "audio" / (cmd[0] + (".exe" if is_win else ""))
|
||||||
if packaged_path.exists():
|
if packaged_path.exists():
|
||||||
cmd[0] = str(packaged_path)
|
cmd[0] = str(packaged_path)
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ class SimpleMpvPlayer(SimpleProcessPlayer, VideoPlayer):
|
||||||
|
|
||||||
class SimpleMplayerPlayer(SimpleProcessPlayer, SoundOrVideoPlayer):
|
class SimpleMplayerPlayer(SimpleProcessPlayer, SoundOrVideoPlayer):
|
||||||
args, env = _packagedCmd(["mplayer", "-really-quiet", "-noautosub"])
|
args, env = _packagedCmd(["mplayer", "-really-quiet", "-noautosub"])
|
||||||
if isWin:
|
if is_win:
|
||||||
args += ["-ao", "win32"]
|
args += ["-ao", "win32"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ class SimpleMplayerPlayer(SimpleProcessPlayer, SoundOrVideoPlayer):
|
||||||
|
|
||||||
class MpvManager(MPV, SoundOrVideoPlayer):
|
class MpvManager(MPV, SoundOrVideoPlayer):
|
||||||
|
|
||||||
if not isLin:
|
if not is_lin:
|
||||||
default_argv = MPVBase.default_argv + [
|
default_argv = MPVBase.default_argv + [
|
||||||
"--input-media-keys=no",
|
"--input-media-keys=no",
|
||||||
]
|
]
|
||||||
|
@ -801,7 +801,7 @@ def setup_audio(taskman: TaskManager, base_folder: str) -> None:
|
||||||
if mpvManager is not None:
|
if mpvManager is not None:
|
||||||
av_player.players.append(mpvManager)
|
av_player.players.append(mpvManager)
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
mpvPlayer = SimpleMpvPlayer(taskman, base_folder)
|
mpvPlayer = SimpleMpvPlayer(taskman, base_folder)
|
||||||
av_player.players.append(mpvPlayer)
|
av_player.players.append(mpvPlayer)
|
||||||
else:
|
else:
|
||||||
|
@ -809,11 +809,11 @@ def setup_audio(taskman: TaskManager, base_folder: str) -> None:
|
||||||
av_player.players.append(mplayer)
|
av_player.players.append(mplayer)
|
||||||
|
|
||||||
# tts support
|
# tts support
|
||||||
if isMac:
|
if is_mac:
|
||||||
from aqt.tts import MacTTSPlayer
|
from aqt.tts import MacTTSPlayer
|
||||||
|
|
||||||
av_player.players.append(MacTTSPlayer(taskman))
|
av_player.players.append(MacTTSPlayer(taskman))
|
||||||
elif isWin:
|
elif is_win:
|
||||||
from aqt.tts import WindowsTTSPlayer
|
from aqt.tts import WindowsTTSPlayer
|
||||||
|
|
||||||
av_player.players.append(WindowsTTSPlayer(taskman))
|
av_player.players.append(WindowsTTSPlayer(taskman))
|
||||||
|
|
|
@ -8,8 +8,8 @@ import platform
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.utils import isMac
|
from anki.utils import is_mac
|
||||||
from aqt import QApplication, colors, gui_hooks, isWin
|
from aqt import QApplication, colors, gui_hooks, is_win
|
||||||
from aqt.platform import (
|
from aqt.platform import (
|
||||||
get_linux_dark_mode,
|
get_linux_dark_mode,
|
||||||
get_macos_dark_mode,
|
get_macos_dark_mode,
|
||||||
|
@ -65,7 +65,7 @@ class ThemeManager:
|
||||||
|
|
||||||
def macos_dark_mode(self) -> bool:
|
def macos_dark_mode(self) -> bool:
|
||||||
"True if the user has night mode on, and has forced native widgets."
|
"True if the user has night mode on, and has forced native widgets."
|
||||||
if not isMac:
|
if not is_mac:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not self._night_mode_preference:
|
if not self._night_mode_preference:
|
||||||
|
@ -128,9 +128,9 @@ class ThemeManager:
|
||||||
def body_class(self, night_mode: bool | None = None) -> str:
|
def body_class(self, night_mode: bool | None = None) -> str:
|
||||||
"Returns space-separated class list for platform/theme."
|
"Returns space-separated class list for platform/theme."
|
||||||
classes = []
|
classes = []
|
||||||
if isWin:
|
if is_win:
|
||||||
classes.append("isWin")
|
classes.append("isWin")
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
classes.append("isMac")
|
classes.append("isMac")
|
||||||
else:
|
else:
|
||||||
classes.append("isLin")
|
classes.append("isLin")
|
||||||
|
@ -164,9 +164,9 @@ class ThemeManager:
|
||||||
elif theme == Theme.DARK:
|
elif theme == Theme.DARK:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
if isWin:
|
if is_win:
|
||||||
return get_windows_dark_mode()
|
return get_windows_dark_mode()
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
return get_macos_dark_mode()
|
return get_macos_dark_mode()
|
||||||
else:
|
else:
|
||||||
return get_linux_dark_mode()
|
return get_linux_dark_mode()
|
||||||
|
@ -192,7 +192,7 @@ class ThemeManager:
|
||||||
def _apply_style(self, app: QApplication) -> None:
|
def _apply_style(self, app: QApplication) -> None:
|
||||||
buf = ""
|
buf = ""
|
||||||
|
|
||||||
if isWin and platform.release() == "10":
|
if is_win and platform.release() == "10":
|
||||||
# day mode is missing a bottom border; background must be
|
# day mode is missing a bottom border; background must be
|
||||||
# also set for border to apply
|
# also set for border to apply
|
||||||
buf += f"""
|
buf += f"""
|
||||||
|
|
|
@ -41,7 +41,7 @@ from typing import Any, cast
|
||||||
import anki
|
import anki
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.sound import AVTag, TTSTag
|
from anki.sound import AVTag, TTSTag
|
||||||
from anki.utils import checksum, isWin, tmpdir
|
from anki.utils import checksum, is_win, tmpdir
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.sound import OnDoneCallback, SimpleProcessPlayer
|
from aqt.sound import OnDoneCallback, SimpleProcessPlayer
|
||||||
from aqt.utils import tooltip, tr
|
from aqt.utils import tooltip, tr
|
||||||
|
@ -264,7 +264,7 @@ class WindowsVoice(TTSVoice):
|
||||||
handle: Any
|
handle: Any
|
||||||
|
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
import win32com.client # pylint: disable=import-error
|
import win32com.client # pylint: disable=import-error
|
||||||
|
|
||||||
# language ID map from https://github.com/sindresorhus/lcid/blob/master/lcid.json
|
# language ID map from https://github.com/sindresorhus/lcid/blob/master/lcid.json
|
||||||
|
|
|
@ -14,8 +14,8 @@ from anki.collection import Collection, HelpPage
|
||||||
from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
|
from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
|
||||||
from anki.utils import (
|
from anki.utils import (
|
||||||
invalid_filename,
|
invalid_filename,
|
||||||
isMac,
|
is_mac,
|
||||||
isWin,
|
is_win,
|
||||||
no_bundled_libs,
|
no_bundled_libs,
|
||||||
version_with_build,
|
version_with_build,
|
||||||
)
|
)
|
||||||
|
@ -509,7 +509,7 @@ def getSaveFile(
|
||||||
|
|
||||||
def saveGeom(widget: QWidget, key: str) -> None:
|
def saveGeom(widget: QWidget, key: str) -> None:
|
||||||
key += "Geom"
|
key += "Geom"
|
||||||
if isMac and (widget.windowState() & Qt.WindowState.WindowFullScreen):
|
if is_mac and (widget.windowState() & Qt.WindowState.WindowFullScreen):
|
||||||
geom = None
|
geom = None
|
||||||
else:
|
else:
|
||||||
geom = widget.saveGeometry()
|
geom = widget.saveGeometry()
|
||||||
|
@ -522,7 +522,7 @@ def restoreGeom(
|
||||||
key += "Geom"
|
key += "Geom"
|
||||||
if aqt.mw.pm.profile.get(key):
|
if aqt.mw.pm.profile.get(key):
|
||||||
widget.restoreGeometry(aqt.mw.pm.profile[key])
|
widget.restoreGeometry(aqt.mw.pm.profile[key])
|
||||||
if isMac and offset:
|
if is_mac and offset:
|
||||||
if qtmajor > 5 or qtminor > 6:
|
if qtmajor > 5 or qtminor > 6:
|
||||||
# bug in osx toolkit
|
# bug in osx toolkit
|
||||||
s = widget.size()
|
s = widget.size()
|
||||||
|
@ -659,7 +659,7 @@ def mungeQA(col: Collection, txt: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def openFolder(path: str) -> None:
|
def openFolder(path: str) -> None:
|
||||||
if isWin:
|
if is_win:
|
||||||
subprocess.run(["explorer", f"file://{path}"], check=False)
|
subprocess.run(["explorer", f"file://{path}"], check=False)
|
||||||
else:
|
else:
|
||||||
with no_bundled_libs():
|
with no_bundled_libs():
|
||||||
|
@ -667,20 +667,20 @@ def openFolder(path: str) -> None:
|
||||||
|
|
||||||
|
|
||||||
def shortcut(key: str) -> str:
|
def shortcut(key: str) -> str:
|
||||||
if isMac:
|
if is_mac:
|
||||||
return re.sub("(?i)ctrl", "Command", key)
|
return re.sub("(?i)ctrl", "Command", key)
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
def maybeHideClose(bbox: QDialogButtonBox) -> None:
|
def maybeHideClose(bbox: QDialogButtonBox) -> None:
|
||||||
if isMac:
|
if is_mac:
|
||||||
b = bbox.button(QDialogButtonBox.StandardButton.Close)
|
b = bbox.button(QDialogButtonBox.StandardButton.Close)
|
||||||
if b:
|
if b:
|
||||||
bbox.removeButton(b)
|
bbox.removeButton(b)
|
||||||
|
|
||||||
|
|
||||||
def addCloseShortcut(widg: QDialog) -> None:
|
def addCloseShortcut(widg: QDialog) -> None:
|
||||||
if not isMac:
|
if not is_mac:
|
||||||
return
|
return
|
||||||
shortcut = QShortcut(QKeySequence("Ctrl+W"), widg)
|
shortcut = QShortcut(QKeySequence("Ctrl+W"), widg)
|
||||||
qconnect(shortcut.activated, widg.reject)
|
qconnect(shortcut.activated, widg.reject)
|
||||||
|
@ -688,7 +688,7 @@ def addCloseShortcut(widg: QDialog) -> None:
|
||||||
|
|
||||||
|
|
||||||
def downArrow() -> str:
|
def downArrow() -> str:
|
||||||
if isWin:
|
if is_win:
|
||||||
return "▼"
|
return "▼"
|
||||||
# windows 10 is lacking the smaller arrow on English installs
|
# windows 10 is lacking the smaller arrow on English installs
|
||||||
return "▾"
|
return "▾"
|
||||||
|
@ -853,9 +853,9 @@ def supportText() -> str:
|
||||||
|
|
||||||
from aqt import mw
|
from aqt import mw
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
platname = f"Windows {platform.win32_ver()[0]}"
|
platname = f"Windows {platform.win32_ver()[0]}"
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
platname = f"Mac {platform.mac_ver()[0]}"
|
platname = f"Mac {platform.mac_ver()[0]}"
|
||||||
else:
|
else:
|
||||||
platname = "Linux"
|
platname = "Linux"
|
||||||
|
|
|
@ -9,7 +9,7 @@ from typing import Any, Callable, Optional, Sequence, cast
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
from anki.lang import is_rtl
|
from anki.lang import is_rtl
|
||||||
from anki.utils import isLin, isMac, isWin
|
from anki.utils import is_lin, is_mac, is_win
|
||||||
from aqt import colors, gui_hooks
|
from aqt import colors, gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.theme import theme_manager
|
from aqt.theme import theme_manager
|
||||||
|
@ -265,7 +265,7 @@ class AnkiWebView(QWebEngineView):
|
||||||
isinstance(evt, QMouseEvent)
|
isinstance(evt, QMouseEvent)
|
||||||
and evt.type() == QEvent.Type.MouseButtonRelease
|
and evt.type() == QEvent.Type.MouseButtonRelease
|
||||||
):
|
):
|
||||||
if evt.button() == Qt.MouseButton.MiddleButton and isLin:
|
if evt.button() == Qt.MouseButton.MiddleButton and is_lin:
|
||||||
self.onMiddleClickPaste()
|
self.onMiddleClickPaste()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -356,7 +356,7 @@ class AnkiWebView(QWebEngineView):
|
||||||
if webscale:
|
if webscale:
|
||||||
return float(webscale)
|
return float(webscale)
|
||||||
|
|
||||||
if qtmajor > 5 or isMac:
|
if qtmajor > 5 or is_mac:
|
||||||
return 1
|
return 1
|
||||||
screen = QApplication.desktop().screen() # type: ignore
|
screen = QApplication.desktop().screen() # type: ignore
|
||||||
if screen is None:
|
if screen is None:
|
||||||
|
@ -364,7 +364,7 @@ class AnkiWebView(QWebEngineView):
|
||||||
|
|
||||||
dpi = screen.logicalDpiX()
|
dpi = screen.logicalDpiX()
|
||||||
factor = dpi / 96.0
|
factor = dpi / 96.0
|
||||||
if isLin:
|
if is_lin:
|
||||||
factor = max(1, factor)
|
factor = max(1, factor)
|
||||||
return factor
|
return factor
|
||||||
return 1
|
return 1
|
||||||
|
@ -388,7 +388,7 @@ class AnkiWebView(QWebEngineView):
|
||||||
def get_window_bg_color(self, night_mode: bool) -> QColor:
|
def get_window_bg_color(self, night_mode: bool) -> QColor:
|
||||||
if night_mode:
|
if night_mode:
|
||||||
return QColor(colors.WINDOW_BG[1])
|
return QColor(colors.WINDOW_BG[1])
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
# standard palette does not return correct window color on macOS
|
# standard palette does not return correct window color on macOS
|
||||||
return QColor("#ececec")
|
return QColor("#ececec")
|
||||||
else:
|
else:
|
||||||
|
@ -398,13 +398,13 @@ class AnkiWebView(QWebEngineView):
|
||||||
palette = theme_manager.default_palette
|
palette = theme_manager.default_palette
|
||||||
color_hl = palette.color(QPalette.ColorRole.Highlight).name()
|
color_hl = palette.color(QPalette.ColorRole.Highlight).name()
|
||||||
|
|
||||||
if isWin:
|
if is_win:
|
||||||
# T: include a font for your language on Windows, eg: "Segoe UI", "MS Mincho"
|
# T: include a font for your language on Windows, eg: "Segoe UI", "MS Mincho"
|
||||||
family = tr.qt_misc_segoe_ui()
|
family = tr.qt_misc_segoe_ui()
|
||||||
button_style = "button { font-family:%s; }" % family
|
button_style = "button { font-family:%s; }" % family
|
||||||
button_style += "\n:focus { outline: 1px solid %s; }" % color_hl
|
button_style += "\n:focus { outline: 1px solid %s; }" % color_hl
|
||||||
font = f"font-size:12px;font-family:{family};"
|
font = f"font-size:12px;font-family:{family};"
|
||||||
elif isMac:
|
elif is_mac:
|
||||||
family = "Helvetica"
|
family = "Helvetica"
|
||||||
font = f'font-size:15px;font-family:"{family}";'
|
font = f'font-size:15px;font-family:"{family}";'
|
||||||
button_style = """
|
button_style = """
|
||||||
|
|
Loading…
Reference in a new issue