Merge pull request #1406 from ankitects/qt6

PyQt6 support
This commit is contained in:
Damien Elmes 2021-10-15 13:38:56 +10:00 committed by GitHub
commit 63fe9097fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
157 changed files with 1377 additions and 691 deletions

View file

@ -9,6 +9,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install
load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories") load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories")
load("@com_github_ali5h_rules_pip//:defs.bzl", "pip_import") load("@com_github_ali5h_rules_pip//:defs.bzl", "pip_import")
load("//pip/pyqt5:defs.bzl", "install_pyqt5") load("//pip/pyqt5:defs.bzl", "install_pyqt5")
load("//pip/pyqt6:defs.bzl", "install_pyqt6")
anki_version = "2.1.49" anki_version = "2.1.49"
@ -43,6 +44,11 @@ def setup_deps():
python_runtime = "@python//:python", python_runtime = "@python//:python",
) )
install_pyqt6(
name = "pyqt6",
python_runtime = "@python//:python",
)
node_repositories(package_json = ["@ankidesktop//:package.json"]) node_repositories(package_json = ["@ankidesktop//:package.json"])
yarn_install( yarn_install(

0
pip/pyqt6/BUILD.bazel Normal file
View file

47
pip/pyqt6/defs.bzl Normal file
View file

@ -0,0 +1,47 @@
# based off https://github.com/ali5h/rules_pip/blob/master/defs.bzl
pip_vendor_label = Label("@com_github_ali5h_rules_pip//:third_party/py/easy_install.py")
def _execute(repository_ctx, arguments, quiet = False):
pip_vendor = str(repository_ctx.path(pip_vendor_label).dirname)
return repository_ctx.execute(arguments, environment = {
"PYTHONPATH": pip_vendor,
}, quiet = quiet)
def _install_pyqt6_impl(repository_ctx):
python_interpreter = repository_ctx.attr.python_interpreter
if repository_ctx.attr.python_runtime:
python_interpreter = repository_ctx.path(repository_ctx.attr.python_runtime)
args = [
python_interpreter,
repository_ctx.path(repository_ctx.attr._script),
repository_ctx.path("."),
]
result = _execute(repository_ctx, args, quiet = repository_ctx.attr.quiet)
if result.return_code:
fail("failed: %s (%s)" % (result.stdout, result.stderr))
install_pyqt6 = repository_rule(
attrs = {
"python_interpreter": attr.string(default = "python", doc = """
The command to run the Python interpreter used to invoke pip and unpack the
wheels.
"""),
"python_runtime": attr.label(doc = """
The label to the Python run-time interpreted used to invoke pip and unpack the wheels.
If the label is specified it will overwrite the python_interpreter attribute.
"""),
"_script": attr.label(
executable = True,
default = Label("//pip/pyqt6:install_pyqt6.py"),
cfg = "host",
),
"quiet": attr.bool(
default = True,
doc = "If stdout and stderr should be printed to the terminal.",
),
},
implementation = _install_pyqt6_impl,
)

196
pip/pyqt6/install_pyqt6.py Normal file
View file

@ -0,0 +1,196 @@
# based on https://github.com/ali5h/rules_pip/blob/master/src/whl.py
# MIT
"""downloads and parses info of a pkg and generates a BUILD file for it"""
import argparse
import glob
import logging
import os
import re
import shutil
import subprocess
import sys
import pkginfo
from pip._internal.commands import create_command
from pip._vendor import pkg_resources
def _create_nspkg_init(dirpath):
"""Creates an init file to enable namespacing"""
if not os.path.exists(dirpath):
# Handle missing namespace packages by ignoring them
return
nspkg_init = os.path.join(dirpath, "__init__.py")
with open(nspkg_init, "w") as nspkg:
nspkg.write("__path__ = __import__('pkgutil').extend_path(__path__, __name__)")
def install_package(pkg, directory, pip_args):
"""Downloads wheel for a package. Assumes python binary provided has
pip and wheel package installed.
Args:
pkg: package name
directory: destination directory to download the wheel file in
python: python binary path used to run pip command
pip_args: extra pip args sent to pip
Returns:
str: path to the wheel file
"""
pip_args = [
"--isolated",
"--disable-pip-version-check",
"--target",
directory,
"--no-deps",
"--ignore-requires-python",
pkg,
] + pip_args
cmd = create_command("install")
cmd.main(pip_args)
# need dist-info directory for pkg_resources to be able to find the packages
dist_info = glob.glob(os.path.join(directory, "*.dist-info"))[0]
# fix namespace packages by adding proper __init__.py files
namespace_packages = os.path.join(dist_info, "namespace_packages.txt")
if os.path.exists(namespace_packages):
with open(namespace_packages) as nspkg:
for line in nspkg.readlines():
namespace = line.strip().replace(".", os.sep)
if namespace:
_create_nspkg_init(os.path.join(directory, namespace))
# PEP 420 -- Implicit Namespace Packages
if (sys.version_info[0], sys.version_info[1]) >= (3, 3):
for dirpath, dirnames, filenames in os.walk(directory):
# we are only interested in dirs with no init file
if "__init__.py" in filenames:
dirnames[:] = []
continue
# remove bin and dist-info dirs
for ignored in ("bin", os.path.basename(dist_info)):
if ignored in dirnames:
dirnames.remove(ignored)
_create_nspkg_init(dirpath)
return pkginfo.Wheel(dist_info)
def _cleanup(directory, pattern):
for p in glob.glob(os.path.join(directory, pattern)):
shutil.rmtree(p)
fix_none = re.compile(r"(\s*None) =")
def copy_and_fix_pyi(source, dest):
"Fix broken PyQt types."
with open(source) as input_file:
with open(dest, "w") as output_file:
for line in input_file.readlines():
# inheriting from the missing sip.sipwrapper definition
# causes missing attributes not to be detected, as it's treating
# the class as inheriting from Any
line = line.replace("PyQt6.sip.wrapper", "object")
line = line.replace("PyQt6.sip.wrapper", "object")
# # remove blanket getattr in QObject which also causes missing
# # attributes not to be detected
if "def __getattr__(self, name: str) -> typing.Any" in line:
continue
output_file.write(line)
def merge_files(root, source):
for dirpath, _dirnames, filenames in os.walk(source):
target_dir = os.path.join(root, os.path.relpath(dirpath, source))
if not os.path.exists(target_dir):
os.mkdir(target_dir)
for fname in filenames:
source_path = os.path.join(dirpath, fname)
target_path = os.path.join(target_dir, fname)
if not os.path.exists(target_path):
if fname.endswith(".pyi"):
copy_and_fix_pyi(source_path, target_path)
else:
shutil.copy2(source_path, target_path)
def main():
base = sys.argv[1]
local_site_packages = os.environ.get("PYTHON_SITE_PACKAGES")
if local_site_packages:
subprocess.run(
[
"rsync",
"-ai",
"--include=PyQt**",
"--exclude=*",
local_site_packages,
base + "/",
],
check=True,
)
with open(os.path.join(base, "__init__.py"), "w") as file:
pass
else:
packages = [
("pyqt6", "pyqt6==6.2.0"),
("pyqt6-qt6", "pyqt6-qt6==6.2.0"),
("pyqt6-webengine", "pyqt6-webengine==6.2.0"),
("pyqt6-webengine-qt6", "pyqt6-webengine-qt6==6.2.0"),
("pyqt6-sip", "pyqt6_sip==13.1.0"),
]
for (name, with_version) in packages:
# install package in subfolder
folder = os.path.join(base, "temp")
_pkg = install_package(with_version, folder, [])
# merge into parent
merge_files(base, folder)
shutil.rmtree(folder)
# add missing py.typed file
with open(os.path.join(base, "py.typed"), "w") as file:
pass
result = """
load("@rules_python//python:defs.bzl", "py_library")
package(default_visibility = ["//visibility:public"])
py_library(
name = "pkg",
srcs = glob(["**/*.py"]),
data = glob(["**/*"], exclude = [
"**/*.py",
"**/*.pyc",
"**/* *",
"BUILD",
"WORKSPACE",
"bin/*",
"__pycache__",
# these make building slower
"Qt/qml/**",
"**/*.sip",
"**/*.png",
]),
# This makes this directory a top-level in the python import
# search path for anything that depends on this.
imports = ["."],
)
"""
# clean up
_cleanup(base, "__pycache__")
with open(os.path.join(base, "BUILD"), "w") as f:
f.write(result)
if __name__ == "__main__":
main()

View file

@ -72,11 +72,11 @@ py_wheel(
}, },
platform = select({ platform = select({
"//platforms:windows_x86_64": "win_amd64", "//platforms:windows_x86_64": "win_amd64",
"//platforms:macos_x86_64": "macosx_10_7_x86_64", "//platforms:macos_x86_64": "macosx_10_13_x86_64",
"//platforms:linux_x86_64": "manylinux2014_x86_64", "//platforms:linux_x86_64": "manylinux_2_28_x86_64",
"//platforms:linux_arm64": "manylinux2014_aarch64", "//platforms:linux_arm64": "manylinux_2_28_aarch64",
}), }),
python_tag = "cp38", python_tag = "cp39",
python_version = ">=3.9", python_version = ">=3.9",
requires = [ requires = [
"beautifulsoup4", "beautifulsoup4",
@ -124,7 +124,10 @@ py_library(
":proto_py", ":proto_py",
], ],
# includes the .pyi files # includes the .pyi files
data = [":proto_py", "py.typed"], data = [
"py.typed",
":proto_py",
],
imports = [".."], imports = [".."],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )

View file

@ -18,7 +18,7 @@ rust_library(
): [ ): [
"-Clink-arg=-undefined", "-Clink-arg=-undefined",
"-Clink-arg=dynamic_lookup", "-Clink-arg=dynamic_lookup",
"-Clink-arg=-mmacosx-version-min=10.7", "-Clink-arg=-mmacosx-version-min=10.13",
], ],
"//conditions:default": [], "//conditions:default": [],
}), }),

View file

@ -1,6 +1,6 @@
[MASTER] [MASTER]
persistent = no persistent = no
extension-pkg-whitelist=PyQt5 extension-pkg-whitelist=PyQt6
ignore = forms,hooks_gen.py ignore = forms,hooks_gen.py
[TYPECHECK] [TYPECHECK]

View file

@ -45,21 +45,21 @@ py_test(
args = [ args = [
"aqt", "aqt",
"$(location mypy.ini)", "$(location mypy.ini)",
"$(location @pyqt5//:__init__.py)", "$(location @pyqt6//:__init__.py)",
"$(location //pip/stubs:extendsitepkgs)", "$(location //pip/stubs:extendsitepkgs)",
], ],
data = [ data = [
"mypy.ini", "mypy.ini",
"//pip/stubs", "//pip/stubs",
"//pip/stubs:extendsitepkgs", "//pip/stubs:extendsitepkgs",
"@pyqt5//:__init__.py", "@pyqt6//:__init__.py",
], ],
env = {"EXTRA_SITE_PACKAGES": "$(location //pip/stubs)"}, env = {"EXTRA_SITE_PACKAGES": "$(location //pip/stubs)"},
main = "tests/run_mypy.py", main = "tests/run_mypy.py",
deps = [ deps = [
"//pylib/anki", "//pylib/anki",
"//qt/aqt:aqt_without_data", "//qt/aqt:aqt_without_data",
"@pyqt5//:pkg", "@pyqt6//:pkg",
requirement("mypy"), requirement("mypy"),
], ],
) )
@ -133,6 +133,20 @@ py_binary(
], ],
) )
py_binary(
name = "runanki_qt5",
srcs = [
"bazelfixes.py",
"runanki.py",
],
imports = ["."],
main = "runanki.py",
deps = [
"//pylib/anki",
"//qt/aqt:aqt_with_data_qt5",
],
)
py_binary( py_binary(
name = "dmypy", name = "dmypy",
srcs = [ srcs = [

View file

@ -50,7 +50,6 @@ aqt_deps = [
requirement("waitress"), requirement("waitress"),
requirement("send2trash"), requirement("send2trash"),
requirement("jsonschema"), requirement("jsonschema"),
"@pyqt5//:pkg",
] + select({ ] + select({
"@bazel_tools//src/conditions:host_windows": [ "@bazel_tools//src/conditions:host_windows": [
requirement("psutil"), requirement("psutil"),
@ -66,7 +65,9 @@ py_library(
srcs = _py_srcs_and_forms, srcs = _py_srcs_and_forms,
data = aqt_core_data, data = aqt_core_data,
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = aqt_deps, deps = aqt_deps + [
"@pyqt6//:pkg",
],
) )
py_library( py_library(
@ -74,7 +75,19 @@ py_library(
srcs = _py_srcs_and_forms, srcs = _py_srcs_and_forms,
data = aqt_core_data + ["//qt/aqt/data"], data = aqt_core_data + ["//qt/aqt/data"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = aqt_deps, deps = aqt_deps + [
"@pyqt6//:pkg",
],
)
py_library(
name = "aqt_with_data_qt5",
srcs = _py_srcs_and_forms,
data = aqt_core_data + ["//qt/aqt/data"],
visibility = ["//visibility:public"],
deps = aqt_deps + [
"@pyqt5//:pkg",
],
) )
py_package( py_package(
@ -94,10 +107,20 @@ py_wheel(
entry_points = { entry_points = {
"console_scripts": ["anki = aqt:run"], "console_scripts": ["anki = aqt:run"],
}, },
extra_requires = {
"qt5": [
"pyqt5>=5.14",
"pyqtwebengine",
],
"qt6": [
"pyqt6>=6.2",
"pyqt6-webengine>=6.2",
],
},
homepage = "https://apps.ankiweb.net", homepage = "https://apps.ankiweb.net",
license = "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", license = "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
python_tag = "py3", python_tag = "py3",
python_version = ">=3.8", python_version = ">=3.9",
requires = [ requires = [
"beautifulsoup4", "beautifulsoup4",
"requests", "requests",
@ -106,12 +129,9 @@ py_wheel(
"flask", "flask",
"flask_cors", "flask_cors",
"waitress", "waitress",
"pyqt5>=5.12",
"pyqtwebengine",
'psutil; sys.platform == "win32"', 'psutil; sys.platform == "win32"',
'pywin32; sys.platform == "win32"', 'pywin32; sys.platform == "win32"',
'winrt==1.0.20239.1; sys.platform == "win32" and platform_release == "10" and python_version == "3.8"', 'winrt; sys.platform == "win32"',
'winrt; sys.platform == "win32" and platform_release == "10" and python_version >= "3.9"',
"anki==" + anki_version, "anki==" + anki_version,
], ],
strip_path_prefixes = [ strip_path_prefixes = [

View file

@ -99,8 +99,10 @@ class DialogManager:
def open(self, name: str, *args: Any, **kwargs: Any) -> Any: def open(self, name: str, *args: Any, **kwargs: Any) -> Any:
(creator, instance) = self._dialogs[name] (creator, instance) = self._dialogs[name]
if instance: if instance:
if instance.windowState() & Qt.WindowMinimized: if instance.windowState() & Qt.WindowState.WindowMinimized:
instance.setWindowState(instance.windowState() & ~Qt.WindowMinimized) instance.setWindowState(
instance.windowState() & ~Qt.WindowState.WindowMinimized
)
instance.activateWindow() instance.activateWindow()
instance.raise_() instance.raise_()
if hasattr(instance, "reopen"): if hasattr(instance, "reopen"):
@ -224,9 +226,9 @@ def setupLangAndBackend(
# switch direction for RTL languages # switch direction for RTL languages
if anki.lang.is_rtl(lang): if anki.lang.is_rtl(lang):
app.setLayoutDirection(Qt.RightToLeft) app.setLayoutDirection(Qt.LayoutDirection.RightToLeft)
else: else:
app.setLayoutDirection(Qt.LeftToRight) app.setLayoutDirection(Qt.LayoutDirection.LeftToRight)
# load qt translations # load qt translations
_qtrans = QTranslator() _qtrans = QTranslator()
@ -238,7 +240,10 @@ def setupLangAndBackend(
os.path.join(aqt_data_folder(), "..", "qt_translations") os.path.join(aqt_data_folder(), "..", "qt_translations")
) )
else: else:
qt_dir = QLibraryInfo.location(QLibraryInfo.TranslationsPath) if qtmajor == 5:
qt_dir = QLibraryInfo.location(QLibraryInfo.TranslationsPath) # type: ignore
else:
qt_dir = QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath)
qt_lang = lang.replace("-", "_") qt_lang = lang.replace("-", "_")
if _qtrans.load(f"qtbase_{qt_lang}", qt_dir): if _qtrans.load(f"qtbase_{qt_lang}", qt_dir):
app.installTranslator(_qtrans) app.installTranslator(_qtrans)
@ -285,7 +290,7 @@ class AnkiApp(QApplication):
def sendMsg(self, txt: str) -> bool: def sendMsg(self, txt: str) -> bool:
sock = QLocalSocket(self) sock = QLocalSocket(self)
sock.connectToServer(self.KEY, QIODevice.WriteOnly) sock.connectToServer(self.KEY, QIODevice.OpenModeFlag.WriteOnly)
if not sock.waitForConnected(self.TMOUT): if not sock.waitForConnected(self.TMOUT):
# first instance or previous instance dead # first instance or previous instance dead
return False return False
@ -315,7 +320,7 @@ class AnkiApp(QApplication):
################################################## ##################################################
def event(self, evt: QEvent) -> bool: def event(self, evt: QEvent) -> bool:
if evt.type() == QEvent.FileOpen: if evt.type() == QEvent.Type.FileOpen:
self.appMsg.emit(evt.file() or "raise") # type: ignore self.appMsg.emit(evt.file() or "raise") # type: ignore
return True return True
return QApplication.event(self, evt) return QApplication.event(self, evt)
@ -360,20 +365,18 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
# catch opengl errors # catch opengl errors
def msgHandler(category: Any, ctx: Any, msg: Any) -> None: def msgHandler(category: Any, ctx: Any, msg: Any) -> None:
if category == QtDebugMsg: if category == QtMsgType.QtDebugMsg:
category = "debug" category = "debug"
elif category == QtInfoMsg: elif category == QtMsgType.QtInfoMsg:
category = "info" category = "info"
elif category == QtWarningMsg: elif category == QtMsgType.QtWarningMsg:
category = "warning" category = "warning"
elif category == QtCriticalMsg: elif category == QtMsgType.QtCriticalMsg:
category = "critical" category = "critical"
elif category == QtDebugMsg: elif category == QtMsgType.QtDebugMsg:
category = "debug" category = "debug"
elif category == QtFatalMsg: elif category == QtMsgType.QtFatalMsg:
category = "fatal" category = "fatal"
elif category == QtSystemMsg:
category = "system"
else: else:
category = "unknown" category = "unknown"
context = "" context = ""
@ -407,7 +410,7 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
if isWin: if isWin:
os.environ["QT_OPENGL"] = driver.value os.environ["QT_OPENGL"] = driver.value
elif isMac: elif isMac:
QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL) QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
elif isLin: elif isLin:
os.environ["QT_XCB_FORCE_SOFTWARE_OPENGL"] = "1" os.environ["QT_XCB_FORCE_SOFTWARE_OPENGL"] = "1"
@ -501,15 +504,15 @@ def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiAp
os.environ["QT_SCALE_FACTOR"] = str(pm.uiScale()) os.environ["QT_SCALE_FACTOR"] = str(pm.uiScale())
# opt in to full hidpi support? # opt in to full hidpi support?
if not os.environ.get("ANKI_NOHIGHDPI"): if not os.environ.get("ANKI_NOHIGHDPI") and qtmajor == 5:
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling) # type: ignore
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps) # type: ignore
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1" os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1"
os.environ["QT_SCALE_FACTOR_ROUNDING_POLICY"] = "PassThrough" os.environ["QT_SCALE_FACTOR_ROUNDING_POLICY"] = "PassThrough"
# Opt into software rendering. Useful for buggy systems. # Opt into software rendering. Useful for buggy systems.
if os.environ.get("ANKI_SOFTWAREOPENGL"): if os.environ.get("ANKI_SOFTWAREOPENGL"):
QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL) QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
if ( if (
isWin isWin
@ -537,11 +540,13 @@ def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiAp
# 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 isMac:
app.setAttribute(Qt.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 qtminor >= 10: if isWin and qtmajor == 5 and qtminor >= 10:
QApplication.setAttribute(Qt.AA_DisableWindowContextHelpButton) QApplication.setAttribute(
QApplication.Attribute.AA_DisableWindowContextHelpButton # type: ignore
)
# proxy configured? # proxy configured?
from urllib.request import getproxies, proxy_bypass from urllib.request import getproxies, proxy_bypass
@ -561,7 +566,7 @@ def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiAp
if disable_proxies: if disable_proxies:
print("webview proxy use disabled") print("webview proxy use disabled")
proxy = QNetworkProxy() proxy = QNetworkProxy()
proxy.setType(QNetworkProxy.NoProxy) proxy.setType(QNetworkProxy.ProxyType.NoProxy)
QNetworkProxy.setApplicationProxy(proxy) QNetworkProxy.setApplicationProxy(proxy)
# we must have a usable temp dir # we must have a usable temp dir

View file

@ -88,8 +88,8 @@ def show(mw: aqt.AnkiQt) -> QDialog:
btn = QPushButton(tr.about_copy_debug_info()) btn = QPushButton(tr.about_copy_debug_info())
qconnect(btn.clicked, onCopy) qconnect(btn.clicked, onCopy)
abt.buttonBox.addButton(btn, QDialogButtonBox.ActionRole) abt.buttonBox.addButton(btn, QDialogButtonBox.ButtonRole.ActionRole)
abt.buttonBox.button(QDialogButtonBox.Ok).setFocus() abt.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setFocus()
# WebView contents # WebView contents
###################################################################### ######################################################################

View file

@ -35,7 +35,7 @@ from aqt.utils import (
class AddCards(QDialog): class AddCards(QDialog):
def __init__(self, mw: AnkiQt) -> None: def __init__(self, mw: AnkiQt) -> None:
QDialog.__init__(self, None, Qt.Window) QDialog.__init__(self, None, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self) mw.garbage_collect_on_dialog_finish(self)
self.mw = mw self.mw = mw
self.col = mw.col self.col = mw.col
@ -85,7 +85,7 @@ class AddCards(QDialog):
def setupButtons(self) -> None: def setupButtons(self) -> None:
bb = self.form.buttonBox bb = self.form.buttonBox
ar = QDialogButtonBox.ActionRole ar = QDialogButtonBox.ButtonRole.ActionRole
# add # add
self.addButton = bb.addButton(tr.actions_add(), ar) self.addButton = bb.addButton(tr.actions_add(), ar)
qconnect(self.addButton.clicked, self.add_current_note) qconnect(self.addButton.clicked, self.add_current_note)
@ -97,11 +97,11 @@ class AddCards(QDialog):
# close # close
self.closeButton = QPushButton(tr.actions_close()) self.closeButton = QPushButton(tr.actions_close())
self.closeButton.setAutoDefault(False) self.closeButton.setAutoDefault(False)
bb.addButton(self.closeButton, QDialogButtonBox.RejectRole) bb.addButton(self.closeButton, QDialogButtonBox.ButtonRole.RejectRole)
# help # help
self.helpButton = QPushButton(tr.actions_help(), clicked=self.helpRequested) # type: ignore self.helpButton = QPushButton(tr.actions_help(), clicked=self.helpRequested) # type: ignore
self.helpButton.setAutoDefault(False) self.helpButton.setAutoDefault(False)
bb.addButton(self.helpButton, QDialogButtonBox.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 isMac:
@ -266,7 +266,10 @@ class AddCards(QDialog):
def keyPressEvent(self, evt: QKeyEvent) -> None: def keyPressEvent(self, evt: QKeyEvent) -> None:
"Show answer on RET or register answer." "Show answer on RET or register answer."
if evt.key() in (Qt.Key_Enter, Qt.Key_Return) and self.editor.tags.hasFocus(): if (
evt.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return)
and self.editor.tags.hasFocus()
):
evt.accept() evt.accept()
return return
return QDialog.keyPressEvent(self, evt) return QDialog.keyPressEvent(self, evt)

View file

@ -804,7 +804,7 @@ class AddonsDialog(QDialog):
name = self.name_for_addon_list(addon) name = self.name_for_addon_list(addon)
item = QListWidgetItem(name, addonList) item = QListWidgetItem(name, addonList)
if self.should_grey(addon): if self.should_grey(addon):
item.setForeground(Qt.gray) item.setForeground(Qt.GlobalColor.gray)
if addon.dir_name in selected: if addon.dir_name in selected:
item.setSelected(True) item.setSelected(True)
@ -947,7 +947,7 @@ class GetAddons(QDialog):
self.form = aqt.forms.getaddons.Ui_Dialog() self.form = aqt.forms.getaddons.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
b = self.form.buttonBox.addButton( b = self.form.buttonBox.addButton(
tr.addons_browse_addons(), QDialogButtonBox.ActionRole tr.addons_browse_addons(), QDialogButtonBox.ButtonRole.ActionRole
) )
qconnect(b.clicked, self.onBrowse) qconnect(b.clicked, self.onBrowse)
disable_help_button(self) disable_help_button(self)
@ -1183,7 +1183,7 @@ class ChooseAddonsToUpdateList(QListWidget):
) )
self.ignore_check_evt = False self.ignore_check_evt = False
self.setup() self.setup()
self.setContextMenuPolicy(Qt.CustomContextMenu) self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
qconnect(self.itemClicked, self.on_click) qconnect(self.itemClicked, self.on_click)
qconnect(self.itemChanged, self.on_check) qconnect(self.itemChanged, self.on_check)
qconnect(self.itemDoubleClicked, self.on_double_click) qconnect(self.itemDoubleClicked, self.on_double_click)
@ -1191,7 +1191,9 @@ class ChooseAddonsToUpdateList(QListWidget):
def setup(self) -> None: def setup(self) -> None:
header_item = QListWidgetItem(tr.addons_choose_update_update_all(), self) header_item = QListWidgetItem(tr.addons_choose_update_update_all(), self)
header_item.setFlags(Qt.ItemFlag(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)) header_item.setFlags(
Qt.ItemFlag(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsEnabled)
)
self.header_item = header_item self.header_item = header_item
for update_info in self.updated_addons: for update_info in self.updated_addons:
addon_id = update_info.id addon_id = update_info.id
@ -1204,22 +1206,22 @@ class ChooseAddonsToUpdateList(QListWidget):
addon_label = f"{update_time:%Y-%m-%d} {addon_name}" addon_label = f"{update_time:%Y-%m-%d} {addon_name}"
item = QListWidgetItem(addon_label, self) item = QListWidgetItem(addon_label, self)
# Not user checkable because it overlaps with itemClicked signal # Not user checkable because it overlaps with itemClicked signal
item.setFlags(Qt.ItemFlag(Qt.ItemIsEnabled)) item.setFlags(Qt.ItemFlag(Qt.ItemFlag.ItemIsEnabled))
if update_enabled: if update_enabled:
item.setCheckState(Qt.Checked) item.setCheckState(Qt.CheckState.Checked)
else: else:
item.setCheckState(Qt.Unchecked) item.setCheckState(Qt.CheckState.Unchecked)
item.setData(self.ADDON_ID_ROLE, addon_id) item.setData(self.ADDON_ID_ROLE, addon_id)
self.refresh_header_check_state() self.refresh_header_check_state()
def bool_to_check(self, check_bool: bool) -> Qt.CheckState: def bool_to_check(self, check_bool: bool) -> Qt.CheckState:
if check_bool: if check_bool:
return Qt.Checked return Qt.CheckState.Checked
else: else:
return Qt.Unchecked return Qt.CheckState.Unchecked
def checked(self, item: QListWidgetItem) -> bool: def checked(self, item: QListWidgetItem) -> bool:
return item.checkState() == Qt.Checked return item.checkState() == Qt.CheckState.Checked
def on_click(self, item: QListWidgetItem) -> None: def on_click(self, item: QListWidgetItem) -> None:
if item == self.header_item: if item == self.header_item:
@ -1262,9 +1264,9 @@ class ChooseAddonsToUpdateList(QListWidget):
for i in range(1, self.count()): for i in range(1, self.count()):
item = self.item(i) item = self.item(i)
if not self.checked(item): if not self.checked(item):
self.check_item(self.header_item, Qt.Unchecked) self.check_item(self.header_item, Qt.CheckState.Unchecked)
return return
self.check_item(self.header_item, Qt.Checked) self.check_item(self.header_item, Qt.CheckState.Checked)
def get_selected_addon_ids(self) -> list[int]: def get_selected_addon_ids(self) -> list[int]:
addon_ids = [] addon_ids = []
@ -1290,7 +1292,7 @@ class ChooseAddonsToUpdateDialog(QDialog):
) -> None: ) -> None:
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
self.setWindowTitle(tr.addons_choose_update_window_title()) self.setWindowTitle(tr.addons_choose_update_window_title())
self.setWindowModality(Qt.WindowModal) self.setWindowModality(Qt.WindowModality.WindowModal)
self.mgr = mgr self.mgr = mgr
self.updated_addons = updated_addons self.updated_addons = updated_addons
self.setup() self.setup()
@ -1306,9 +1308,14 @@ class ChooseAddonsToUpdateDialog(QDialog):
layout.addWidget(addons_list_widget) layout.addWidget(addons_list_widget)
self.addons_list_widget = addons_list_widget self.addons_list_widget = addons_list_widget
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) # type: ignore button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) # type: ignore
qconnect(button_box.button(QDialogButtonBox.Ok).clicked, self.accept) qconnect(
qconnect(button_box.button(QDialogButtonBox.Cancel).clicked, self.reject) button_box.button(QDialogButtonBox.StandardButton.Ok).clicked, self.accept
)
qconnect(
button_box.button(QDialogButtonBox.StandardButton.Cancel).clicked,
self.reject,
)
layout.addWidget(button_box) layout.addWidget(button_box)
self.setLayout(layout) self.setLayout(layout)
@ -1317,7 +1324,7 @@ class ChooseAddonsToUpdateDialog(QDialog):
ret = self.exec() ret = self.exec()
saveGeom(self, "addonsChooseUpdate") saveGeom(self, "addonsChooseUpdate")
self.addons_list_widget.save_check_state() self.addons_list_widget.save_check_state()
if ret == QDialog.Accepted: if ret == QDialog.DialogCode.Accepted:
return self.addons_list_widget.get_selected_addon_ids() return self.addons_list_widget.get_selected_addon_ids()
else: else:
return [] return []
@ -1475,7 +1482,9 @@ class ConfigEditor(QDialog):
self.mgr = dlg.mgr self.mgr = dlg.mgr
self.form = aqt.forms.addonconf.Ui_Dialog() self.form = aqt.forms.addonconf.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
restore = self.form.buttonBox.button(QDialogButtonBox.RestoreDefaults) restore = self.form.buttonBox.button(
QDialogButtonBox.StandardButton.RestoreDefaults
)
qconnect(restore.clicked, self.onRestoreDefaults) qconnect(restore.clicked, self.onRestoreDefaults)
self.setupFonts() self.setupFonts()
self.updateHelp() self.updateHelp()
@ -1498,7 +1507,7 @@ class ConfigEditor(QDialog):
tooltip(tr.addons_restored_defaults(), parent=self) tooltip(tr.addons_restored_defaults(), parent=self)
def setupFonts(self) -> None: def setupFonts(self) -> None:
font_mono = QFontDatabase.systemFont(QFontDatabase.FixedFont) font_mono = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont)
font_mono.setPointSize(font_mono.pointSize() + 1) font_mono.setPointSize(font_mono.pointSize() + 1)
self.form.editor.setFont(font_mono) self.form.editor.setFont(font_mono)
@ -1600,9 +1609,12 @@ def installAddonPackages(
parent=parent, parent=parent,
title=tr.addons_install_anki_addon(), title=tr.addons_install_anki_addon(),
type="warning", type="warning",
customBtns=[QMessageBox.No, QMessageBox.Yes], customBtns=[
QMessageBox.StandardButton.No,
QMessageBox.StandardButton.Yes,
],
) )
== QMessageBox.Yes == QMessageBox.StandardButton.Yes
): ):
return False return False

View file

@ -104,7 +104,7 @@ class Browser(QMainWindow):
search -- set and perform search; caller must ensure validity search -- set and perform search; caller must ensure validity
""" """
QMainWindow.__init__(self, None, Qt.Window) QMainWindow.__init__(self, None, Qt.WindowType.Window)
self.mw = mw self.mw = mw
self.col = self.mw.col self.col = self.mw.col
self.lastFilter = "" self.lastFilter = ""
@ -255,7 +255,7 @@ class Browser(QMainWindow):
onsuccess() onsuccess()
def keyPressEvent(self, evt: QKeyEvent) -> None: def keyPressEvent(self, evt: QKeyEvent) -> None:
if evt.key() == Qt.Key_Escape: if evt.key() == Qt.Key.Key_Escape:
self.close() self.close()
else: else:
super().keyPressEvent(evt) super().keyPressEvent(evt)
@ -490,9 +490,9 @@ class Browser(QMainWindow):
def setupSidebar(self) -> None: def setupSidebar(self) -> None:
dw = self.sidebarDockWidget = QDockWidget(tr.browsing_sidebar(), self) dw = self.sidebarDockWidget = QDockWidget(tr.browsing_sidebar(), self)
dw.setFeatures(QDockWidget.NoDockWidgetFeatures) dw.setFeatures(QDockWidget.DockWidgetFeature.NoDockWidgetFeatures)
dw.setObjectName("Sidebar") dw.setObjectName("Sidebar")
dw.setAllowedAreas(Qt.LeftDockWidgetArea) dw.setAllowedAreas(Qt.DockWidgetArea.LeftDockWidgetArea)
self.sidebar = SidebarTreeView(self) self.sidebar = SidebarTreeView(self)
self.sidebarTree = self.sidebar # legacy alias self.sidebarTree = self.sidebar # legacy alias
@ -513,7 +513,7 @@ class Browser(QMainWindow):
self.sidebarDockWidget.setFloating(False) self.sidebarDockWidget.setFloating(False)
self.sidebarDockWidget.setTitleBarWidget(QWidget()) self.sidebarDockWidget.setTitleBarWidget(QWidget())
self.addDockWidget(Qt.LeftDockWidgetArea, dw) self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, dw)
# schedule sidebar to refresh after browser window has loaded, so the # schedule sidebar to refresh after browser window has loaded, so the
# UI is more responsive # UI is more responsive

View file

@ -28,7 +28,7 @@ class CardInfoDialog(QDialog):
self.show() self.show()
def _setup_ui(self, card_id: CardId) -> None: def _setup_ui(self, card_id: CardId) -> None:
self.setWindowModality(Qt.ApplicationModal) self.setWindowModality(Qt.WindowModality.ApplicationModal)
self.mw.garbage_collect_on_dialog_finish(self) self.mw.garbage_collect_on_dialog_finish(self)
disable_help_button(self) disable_help_button(self)
restoreGeom(self, self.GEOMETRY_KEY) restoreGeom(self, self.GEOMETRY_KEY)
@ -40,7 +40,7 @@ class CardInfoDialog(QDialog):
layout = QVBoxLayout() layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.web) layout.addWidget(self.web)
buttons = QDialogButtonBox(QDialogButtonBox.Close) buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
buttons.setContentsMargins(10, 0, 10, 10) buttons.setContentsMargins(10, 0, 10, 10)
layout.addWidget(buttons) layout.addWidget(buttons)
qconnect(buttons.rejected, self.reject) qconnect(buttons.rejected, self.reject)

View file

@ -73,16 +73,18 @@ class FindAndReplaceDialog(QDialog):
disable_help_button(self) disable_help_button(self)
self.form = aqt.forms.findreplace.Ui_Dialog() self.form = aqt.forms.findreplace.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
self.setWindowModality(Qt.WindowModal) self.setWindowModality(Qt.WindowModality.WindowModal)
self._find_history = restore_combo_history( self._find_history = restore_combo_history(
self.form.find, self.COMBO_NAME + "Find" self.form.find, self.COMBO_NAME + "Find"
) )
self.form.find.completer().setCaseSensitivity(Qt.CaseSensitive) self.form.find.completer().setCaseSensitivity(Qt.CaseSensitivity.CaseSensitive)
self._replace_history = restore_combo_history( self._replace_history = restore_combo_history(
self.form.replace, self.COMBO_NAME + "Replace" self.form.replace, self.COMBO_NAME + "Replace"
) )
self.form.replace.completer().setCaseSensitivity(Qt.CaseSensitive) self.form.replace.completer().setCaseSensitivity(
Qt.CaseSensitivity.CaseSensitive
)
if not self.note_ids: if not self.note_ids:
# no selected notes to affect # no selected notes to affect

View file

@ -71,7 +71,7 @@ class FindDuplicatesDialog(QDialog):
).run_in_background() ).run_in_background()
search = form.buttonBox.addButton( search = form.buttonBox.addButton(
tr.actions_search(), QDialogButtonBox.ActionRole tr.actions_search(), QDialogButtonBox.ButtonRole.ActionRole
) )
qconnect(search.clicked, on_click) qconnect(search.clicked, on_click)
self.show() self.show()
@ -80,7 +80,7 @@ class FindDuplicatesDialog(QDialog):
self._dupes = dupes self._dupes = dupes
if not self._dupesButton: if not self._dupesButton:
self._dupesButton = b = self.form.buttonBox.addButton( self._dupesButton = b = self.form.buttonBox.addButton(
tr.browsing_tag_duplicates(), QDialogButtonBox.ActionRole tr.browsing_tag_duplicates(), QDialogButtonBox.ButtonRole.ActionRole
) )
qconnect(b.clicked, self._tag_duplicates) qconnect(b.clicked, self._tag_duplicates)
text = "" text = ""

View file

@ -46,14 +46,14 @@ class Previewer(QDialog):
def __init__( def __init__(
self, parent: QWidget, mw: AnkiQt, on_close: Callable[[], None] self, parent: QWidget, mw: AnkiQt, on_close: Callable[[], None]
) -> None: ) -> None:
super().__init__(None, Qt.Window) super().__init__(None, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self) mw.garbage_collect_on_dialog_finish(self)
self._open = True self._open = True
self._parent = parent self._parent = parent
self._close_callback = on_close self._close_callback = on_close
self.mw = mw self.mw = mw
icon = QIcon() icon = QIcon()
icon.addPixmap(QPixmap("icons:anki.png"), QIcon.Normal, QIcon.Off) icon.addPixmap(QPixmap("icons:anki.png"), QIcon.Mode.Normal, QIcon.State.Off)
disable_help_button(self) disable_help_button(self)
self.setWindowIcon(icon) self.setWindowIcon(icon)
@ -86,7 +86,7 @@ class Previewer(QDialog):
self.bbox = QDialogButtonBox() self.bbox = QDialogButtonBox()
self._replay = self.bbox.addButton( self._replay = self.bbox.addButton(
tr.actions_replay_audio(), QDialogButtonBox.ActionRole tr.actions_replay_audio(), QDialogButtonBox.ButtonRole.ActionRole
) )
self._replay.setAutoDefault(False) self._replay.setAutoDefault(False)
self._replay.setShortcut(QKeySequence("R")) self._replay.setShortcut(QKeySequence("R"))
@ -96,7 +96,7 @@ class Previewer(QDialog):
both_sides_button = QCheckBox(tr.qt_misc_back_side_only()) both_sides_button = QCheckBox(tr.qt_misc_back_side_only())
both_sides_button.setShortcut(QKeySequence("B")) both_sides_button.setShortcut(QKeySequence("B"))
both_sides_button.setToolTip(tr.actions_shortcut_key(val="B")) both_sides_button.setToolTip(tr.actions_shortcut_key(val="B"))
self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole) self.bbox.addButton(both_sides_button, QDialogButtonBox.ButtonRole.ActionRole)
self._show_both_sides = self.mw.col.get_config_bool( self._show_both_sides = self.mw.col.get_config_bool(
Config.Bool.PREVIEW_BOTH_SIDES Config.Bool.PREVIEW_BOTH_SIDES
) )
@ -266,12 +266,12 @@ class MultiCardPreviewer(Previewer):
def _create_gui(self) -> None: def _create_gui(self) -> None:
super()._create_gui() super()._create_gui()
self._prev = self.bbox.addButton("<", QDialogButtonBox.ActionRole) self._prev = self.bbox.addButton("<", QDialogButtonBox.ButtonRole.ActionRole)
self._prev.setAutoDefault(False) self._prev.setAutoDefault(False)
self._prev.setShortcut(QKeySequence("Left")) self._prev.setShortcut(QKeySequence("Left"))
self._prev.setToolTip(tr.qt_misc_shortcut_key_left_arrow()) self._prev.setToolTip(tr.qt_misc_shortcut_key_left_arrow())
self._next = self.bbox.addButton(">", QDialogButtonBox.ActionRole) self._next = self.bbox.addButton(">", QDialogButtonBox.ButtonRole.ActionRole)
self._next.setAutoDefault(True) self._next.setAutoDefault(True)
self._next.setShortcut(QKeySequence("Right")) self._next.setShortcut(QKeySequence("Right"))
self._next.setToolTip(tr.qt_misc_shortcut_key_right_arrow_or_enter()) self._next.setToolTip(tr.qt_misc_shortcut_key_right_arrow_or_enter())

View file

@ -76,35 +76,48 @@ class SidebarModel(QAbstractItemModel):
return self.createIndex(row, 0, parentItem) return self.createIndex(row, 0, parentItem)
def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> QVariant: def data(
self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole
) -> QVariant:
if not index.isValid(): if not index.isValid():
return QVariant() return QVariant()
if role not in (Qt.DisplayRole, Qt.DecorationRole, Qt.ToolTipRole, Qt.EditRole): if role not in (
Qt.ItemDataRole.DisplayRole,
Qt.ItemDataRole.DecorationRole,
Qt.ItemDataRole.ToolTipRole,
Qt.ItemDataRole.EditRole,
):
return QVariant() return QVariant()
item: SidebarItem = index.internalPointer() item: SidebarItem = index.internalPointer()
if role in (Qt.DisplayRole, Qt.EditRole): if role in (Qt.ItemDataRole.DisplayRole, Qt.ItemDataRole.EditRole):
return QVariant(item.name) return QVariant(item.name)
if role == Qt.ToolTipRole: if role == Qt.ItemDataRole.ToolTipRole:
return QVariant(item.tooltip) return QVariant(item.tooltip)
return QVariant(theme_manager.icon_from_resources(item.icon)) return QVariant(theme_manager.icon_from_resources(item.icon))
def setData(self, index: QModelIndex, text: str, _role: int = Qt.EditRole) -> bool: def setData(
self, index: QModelIndex, text: str, _role: int = Qt.ItemDataRole.EditRole
) -> bool:
return self.sidebar._on_rename(index.internalPointer(), text) return self.sidebar._on_rename(index.internalPointer(), text)
def supportedDropActions(self) -> Qt.DropActions: def supportedDropActions(self) -> Qt.DropAction:
return cast(Qt.DropActions, Qt.MoveAction) return cast(Qt.DropAction, Qt.DropAction.MoveAction)
def flags(self, index: QModelIndex) -> Qt.ItemFlags: def flags(self, index: QModelIndex) -> Qt.ItemFlag:
if not index.isValid(): if not index.isValid():
return cast(Qt.ItemFlags, Qt.ItemIsEnabled) return cast(Qt.ItemFlag, Qt.ItemFlag.ItemIsEnabled)
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled flags = (
Qt.ItemFlag.ItemIsEnabled
| Qt.ItemFlag.ItemIsSelectable
| Qt.ItemFlag.ItemIsDragEnabled
)
item: SidebarItem = index.internalPointer() item: SidebarItem = index.internalPointer()
if item.item_type in self.sidebar.valid_drop_types: if item.item_type in self.sidebar.valid_drop_types:
flags |= Qt.ItemIsDropEnabled flags |= Qt.ItemFlag.ItemIsDropEnabled
if item.item_type.is_editable(): if item.item_type.is_editable():
flags |= Qt.ItemIsEditable flags |= Qt.ItemFlag.ItemIsEditable
return cast(Qt.ItemFlags, flags) return flags

View file

@ -43,9 +43,9 @@ class SidebarSearchBar(QLineEdit):
self.sidebar.search_for(self.text()) self.sidebar.search_for(self.text())
def keyPressEvent(self, evt: QKeyEvent) -> None: def keyPressEvent(self, evt: QKeyEvent) -> None:
if evt.key() in (Qt.Key_Up, Qt.Key_Down): if evt.key() in (Qt.Key.Key_Up, Qt.Key.Key_Down):
self.sidebar.setFocus() self.sidebar.setFocus()
elif evt.key() in (Qt.Key_Enter, Qt.Key_Return): elif evt.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return):
self.onSearch() self.onSearch()
else: else:
QLineEdit.keyPressEvent(self, evt) QLineEdit.keyPressEvent(self, evt)

View file

@ -29,7 +29,7 @@ class SidebarToolbar(QToolBar):
qconnect(self._action_group.triggered, self._on_action_group_triggered) qconnect(self._action_group.triggered, self._on_action_group_triggered)
self._setup_tools() self._setup_tools()
self.setIconSize(QSize(16, 16)) self.setIconSize(QSize(16, 16))
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
self.setStyle(QStyleFactory.create("fusion")) self.setStyle(QStyleFactory.create("fusion"))
def _setup_tools(self) -> None: def _setup_tools(self) -> None:

View file

@ -79,14 +79,14 @@ class SidebarTreeView(QTreeView):
self.valid_drop_types: tuple[SidebarItemType, ...] = () self.valid_drop_types: tuple[SidebarItemType, ...] = ()
self._refresh_needed = False self._refresh_needed = False
self.setContextMenuPolicy(Qt.CustomContextMenu) self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore
self.setUniformRowHeights(True) self.setUniformRowHeights(True)
self.setHeaderHidden(True) self.setHeaderHidden(True)
self.setIndentation(15) self.setIndentation(15)
self.setAutoExpandDelay(600) self.setAutoExpandDelay(600)
self.setDragDropOverwriteMode(False) self.setDragDropOverwriteMode(False)
self.setEditTriggers(QAbstractItemView.EditKeyPressed) self.setEditTriggers(QAbstractItemView.EditTrigger.EditKeyPressed)
qconnect(self.expanded, self._on_expansion) qconnect(self.expanded, self._on_expansion)
qconnect(self.collapsed, self._on_collapse) qconnect(self.collapsed, self._on_collapse)
@ -122,12 +122,12 @@ class SidebarTreeView(QTreeView):
def tool(self, tool: SidebarTool) -> None: def tool(self, tool: SidebarTool) -> None:
self._tool = tool self._tool = tool
if tool == SidebarTool.SEARCH: if tool == SidebarTool.SEARCH:
selection_mode = QAbstractItemView.SingleSelection selection_mode = QAbstractItemView.SelectionMode.SingleSelection
drag_drop_mode = QAbstractItemView.NoDragDrop drag_drop_mode = QAbstractItemView.DragDropMode.NoDragDrop
double_click_expands = False double_click_expands = False
else: else:
selection_mode = QAbstractItemView.ExtendedSelection selection_mode = QAbstractItemView.SelectionMode.ExtendedSelection
drag_drop_mode = QAbstractItemView.InternalMove drag_drop_mode = QAbstractItemView.DragDropMode.InternalMove
double_click_expands = True double_click_expands = True
self.setSelectionMode(selection_mode) self.setSelectionMode(selection_mode)
self.setDragDropMode(drag_drop_mode) self.setDragDropMode(drag_drop_mode)
@ -191,9 +191,9 @@ class SidebarTreeView(QTreeView):
if current := self.find_item(current.has_same_id): if current := self.find_item(current.has_same_id):
index = self.model().index_for_item(current) index = self.model().index_for_item(current)
self.selectionModel().setCurrentIndex( self.selectionModel().setCurrentIndex(
index, QItemSelectionModel.SelectCurrent index, QItemSelectionModel.SelectionFlag.SelectCurrent
) )
self.scrollTo(index, QAbstractItemView.PositionAtCenter) self.scrollTo(index, QAbstractItemView.ScrollHint.PositionAtCenter)
def find_item( def find_item(
self, self,
@ -247,9 +247,12 @@ class SidebarTreeView(QTreeView):
self.setExpanded(idx, True) self.setExpanded(idx, True)
if item.is_highlighted() and scroll_to_first_match: if item.is_highlighted() and scroll_to_first_match:
self.selectionModel().setCurrentIndex( self.selectionModel().setCurrentIndex(
idx, QItemSelectionModel.SelectCurrent idx,
QItemSelectionModel.SelectionFlag.SelectCurrent,
)
self.scrollTo(
idx, QAbstractItemView.ScrollHint.PositionAtCenter
) )
self.scrollTo(idx, QAbstractItemView.PositionAtCenter)
scroll_to_first_match = False scroll_to_first_match = False
expand_node(parent or QModelIndex()) expand_node(parent or QModelIndex())
@ -301,22 +304,29 @@ class SidebarTreeView(QTreeView):
def dropEvent(self, event: QDropEvent) -> None: def dropEvent(self, event: QDropEvent) -> None:
model = self.model() model = self.model()
target_item = model.item_for_index(self.indexAt(event.pos())) if qtmajor == 5:
pos = event.pos() # type: ignore
else:
pos = event.position().toPoint()
target_item = model.item_for_index(self.indexAt(pos))
if self.handle_drag_drop(self._selected_items(), target_item): if self.handle_drag_drop(self._selected_items(), target_item):
event.acceptProposedAction() event.acceptProposedAction()
def mouseReleaseEvent(self, event: QMouseEvent) -> None: def mouseReleaseEvent(self, event: QMouseEvent) -> None:
super().mouseReleaseEvent(event) super().mouseReleaseEvent(event)
if self.tool == SidebarTool.SEARCH and event.button() == Qt.LeftButton: if (
self.tool == SidebarTool.SEARCH
and event.button() == Qt.MouseButton.LeftButton
):
if (index := self.currentIndex()) == self.indexAt(event.pos()): if (index := self.currentIndex()) == self.indexAt(event.pos()):
self._on_search(index) self._on_search(index)
def keyPressEvent(self, event: QKeyEvent) -> None: def keyPressEvent(self, event: QKeyEvent) -> None:
index = self.currentIndex() index = self.currentIndex()
if event.key() in (Qt.Key_Return, Qt.Key_Enter): if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
if not self.isPersistentEditorOpen(index): if not self.isPersistentEditorOpen(index):
self._on_search(index) self._on_search(index)
elif event.key() == Qt.Key_Delete: elif event.key() == Qt.Key.Key_Delete:
self._on_delete_key(index) self._on_delete_key(index)
else: else:
super().keyPressEvent(event) super().keyPressEvent(event)

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
import time import time
from typing import Any, Callable, Sequence, cast from typing import Any, Callable, Sequence
import aqt import aqt
from anki.cards import Card, CardId from anki.cards import Card, CardId
@ -307,7 +307,7 @@ class DataModel(QAbstractTableModel):
def data(self, index: QModelIndex = QModelIndex(), role: int = 0) -> Any: def data(self, index: QModelIndex = QModelIndex(), role: int = 0) -> Any:
if not index.isValid(): if not index.isValid():
return QVariant() return QVariant()
if role == Qt.FontRole: if role == Qt.ItemDataRole.FontRole:
if not self.column_at(index).uses_cell_font: if not self.column_at(index).uses_cell_font:
return QVariant() return QVariant()
qfont = QFont() qfont = QFont()
@ -315,30 +315,33 @@ class DataModel(QAbstractTableModel):
qfont.setFamily(row.font_name) qfont.setFamily(row.font_name)
qfont.setPixelSize(row.font_size) qfont.setPixelSize(row.font_size)
return qfont return qfont
elif role == Qt.TextAlignmentRole: elif role == Qt.ItemDataRole.TextAlignmentRole:
align: Qt.AlignmentFlag | int = Qt.AlignVCenter align: Qt.AlignmentFlag | int = Qt.AlignmentFlag.AlignVCenter
if self.column_at(index).alignment == Columns.ALIGNMENT_CENTER: if self.column_at(index).alignment == Columns.ALIGNMENT_CENTER:
align |= Qt.AlignHCenter align |= Qt.AlignmentFlag.AlignHCenter
return align return align
elif role == Qt.DisplayRole: elif role == Qt.ItemDataRole.DisplayRole:
return self.get_cell(index).text return self.get_cell(index).text
elif role == Qt.ToolTipRole and self._want_tooltips: elif role == Qt.ItemDataRole.ToolTipRole and self._want_tooltips:
return self.get_cell(index).text return self.get_cell(index).text
return QVariant() return QVariant()
def headerData( def headerData(
self, section: int, orientation: Qt.Orientation, role: int = 0 self, section: int, orientation: Qt.Orientation, role: int = 0
) -> str | None: ) -> str | None:
if orientation == Qt.Horizontal and role == Qt.DisplayRole: if (
orientation == Qt.Orientation.Horizontal
and role == Qt.ItemDataRole.DisplayRole
):
return self._state.column_label(self.column_at_section(section)) return self._state.column_label(self.column_at_section(section))
return None return None
def flags(self, index: QModelIndex) -> Qt.ItemFlags: def flags(self, index: QModelIndex) -> Qt.ItemFlag:
# shortcut for large selections (Ctrl+A) to avoid fetching large numbers of rows at once # shortcut for large selections (Ctrl+A) to avoid fetching large numbers of rows at once
if row := self.get_cached_row(index): if row := self.get_cached_row(index):
if row.is_deleted: if row.is_deleted:
return Qt.ItemFlags(Qt.NoItemFlags) return Qt.ItemFlag(Qt.ItemFlag.NoItemFlags)
return cast(Qt.ItemFlags, Qt.ItemIsEnabled | Qt.ItemIsSelectable) return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable
def addon_column_fillin(key: str) -> Column: def addon_column_fillin(key: str) -> Column:

View file

@ -2,7 +2,7 @@
# 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 __future__ import annotations from __future__ import annotations
from typing import Any, Callable, Sequence, cast from typing import Any, Callable, Sequence
import aqt import aqt
import aqt.forms import aqt.forms
@ -127,10 +127,8 @@ class Table:
self.select_all() self.select_all()
self._view.selectionModel().select( self._view.selectionModel().select(
selection, selection,
cast( QItemSelectionModel.SelectionFlag.Deselect
QItemSelectionModel.SelectionFlags, | QItemSelectionModel.SelectionFlag.Rows,
QItemSelectionModel.Deselect | QItemSelectionModel.Rows,
),
) )
def select_single_card(self, card_id: CardId) -> None: def select_single_card(self, card_id: CardId) -> None:
@ -202,10 +200,10 @@ class Table:
# Move cursor # Move cursor
def to_previous_row(self) -> None: def to_previous_row(self) -> None:
self._move_current(QAbstractItemView.MoveUp) self._move_current(QAbstractItemView.CursorAction.MoveUp)
def to_next_row(self) -> None: def to_next_row(self) -> None:
self._move_current(QAbstractItemView.MoveDown) self._move_current(QAbstractItemView.CursorAction.MoveDown)
def to_first_row(self) -> None: def to_first_row(self) -> None:
self._move_current_to_row(0) self._move_current_to_row(0)
@ -248,7 +246,8 @@ class Table:
def clear_current(self) -> None: def clear_current(self) -> None:
self._view.selectionModel().setCurrentIndex( self._view.selectionModel().setCurrentIndex(
QModelIndex(), QItemSelectionModel.NoUpdate QModelIndex(),
QItemSelectionModel.SelectionFlag.NoUpdate,
) )
# Private methods # Private methods
@ -268,7 +267,10 @@ class Table:
index = self._model.index( index = self._model.index(
row, self._view.horizontalHeader().logicalIndex(column) row, self._view.horizontalHeader().logicalIndex(column)
) )
self._view.selectionModel().setCurrentIndex(index, QItemSelectionModel.NoUpdate) self._view.selectionModel().setCurrentIndex(
index,
QItemSelectionModel.SelectionFlag.NoUpdate,
)
def _reset_selection(self) -> None: def _reset_selection(self) -> None:
"""Remove selection and focus without emitting signals. """Remove selection and focus without emitting signals.
@ -286,7 +288,9 @@ class Table:
self._model.index(row, 0), self._model.index(row, 0),
self._model.index(row, self._model.len_columns() - 1), self._model.index(row, self._model.len_columns() - 1),
) )
self._view.selectionModel().select(selection, QItemSelectionModel.SelectCurrent) self._view.selectionModel().select(
selection, QItemSelectionModel.SelectionFlag.SelectCurrent
)
def _set_sort_indicator(self) -> None: def _set_sort_indicator(self) -> None:
hh = self._view.horizontalHeader() hh = self._view.horizontalHeader()
@ -295,9 +299,9 @@ class Table:
hh.setSortIndicatorShown(False) hh.setSortIndicatorShown(False)
return return
if self._state.sort_backwards: if self._state.sort_backwards:
order = Qt.DescendingOrder order = Qt.SortOrder.DescendingOrder
else: else:
order = Qt.AscendingOrder order = Qt.SortOrder.AscendingOrder
hh.blockSignals(True) hh.blockSignals(True)
hh.setSortIndicator(index, order) hh.setSortIndicator(index, order)
hh.blockSignals(False) hh.blockSignals(False)
@ -305,9 +309,10 @@ class Table:
def _set_column_sizes(self) -> None: def _set_column_sizes(self) -> None:
hh = self._view.horizontalHeader() hh = self._view.horizontalHeader()
hh.setSectionResizeMode(QHeaderView.Interactive) hh.setSectionResizeMode(QHeaderView.ResizeMode.Interactive)
hh.setSectionResizeMode( hh.setSectionResizeMode(
hh.logicalIndex(self._model.len_columns() - 1), QHeaderView.Stretch hh.logicalIndex(self._model.len_columns() - 1),
QHeaderView.ResizeMode.Stretch,
) )
# this must be set post-resize or it doesn't work # this must be set post-resize or it doesn't work
hh.setCascadingSectionResizes(False) hh.setCascadingSectionResizes(False)
@ -334,7 +339,7 @@ class Table:
) )
qconnect(self._view.selectionModel().currentChanged, self._on_current_changed) qconnect(self._view.selectionModel().currentChanged, self._on_current_changed)
self._view.setWordWrap(False) self._view.setWordWrap(False)
self._view.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self._view.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
self._view.horizontalScrollBar().setSingleStep(10) self._view.horizontalScrollBar().setSingleStep(10)
self._update_font() self._update_font()
if not theme_manager.night_mode: if not theme_manager.night_mode:
@ -346,7 +351,7 @@ class Table:
self._view.setStyleSheet( self._view.setStyleSheet(
f"QTableView {{ gridline-color: {colors.FRAME_BG} }}" f"QTableView {{ gridline-color: {colors.FRAME_BG} }}"
) )
self._view.setContextMenuPolicy(Qt.CustomContextMenu) self._view.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
qconnect(self._view.customContextMenuRequested, self._on_context_menu) qconnect(self._view.customContextMenuRequested, self._on_context_menu)
def _update_font(self) -> None: def _update_font(self) -> None:
@ -369,7 +374,7 @@ class Table:
hh.setHighlightSections(False) hh.setHighlightSections(False)
hh.setMinimumSectionSize(50) hh.setMinimumSectionSize(50)
hh.setSectionsMovable(True) hh.setSectionsMovable(True)
hh.setContextMenuPolicy(Qt.CustomContextMenu) hh.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self._restore_header() self._restore_header()
qconnect(hh.customContextMenuRequested, self._on_header_context) qconnect(hh.customContextMenuRequested, self._on_header_context)
qconnect(hh.sortIndicatorChanged, self._on_sort_column_changed) qconnect(hh.sortIndicatorChanged, self._on_sort_column_changed)
@ -573,7 +578,9 @@ class Table:
visible = top_border >= 0 and bottom_border < self._view.viewport().height() visible = top_border >= 0 and bottom_border < self._view.viewport().height()
if not visible or scroll_even_if_visible: if not visible or scroll_even_if_visible:
horizontal = self._view.horizontalScrollBar().value() horizontal = self._view.horizontalScrollBar().value()
self._view.scrollTo(self._model.index(row, 0), self._view.PositionAtTop) self._view.scrollTo(
self._model.index(row, 0), QAbstractItemView.ScrollHint.PositionAtTop
)
self._view.horizontalScrollBar().setValue(horizontal) self._view.horizontalScrollBar().setValue(horizontal)
def _scroll_to_column(self, column: int) -> None: def _scroll_to_column(self, column: int) -> None:
@ -583,26 +590,26 @@ class Table:
if not visible: if not visible:
vertical = self._view.verticalScrollBar().value() vertical = self._view.verticalScrollBar().value()
self._view.scrollTo( self._view.scrollTo(
self._model.index(0, column), self._view.PositionAtCenter self._model.index(0, column),
QAbstractItemView.ScrollHint.PositionAtCenter,
) )
self._view.verticalScrollBar().setValue(vertical) self._view.verticalScrollBar().setValue(vertical)
def _move_current(self, direction: int, index: QModelIndex = None) -> None: def _move_current(
self, direction: QAbstractItemView.CursorAction, index: QModelIndex = None
) -> None:
if not self.has_current(): if not self.has_current():
return return
if index is None: if index is None:
index = self._view.moveCursor( index = self._view.moveCursor(
cast(QAbstractItemView.CursorAction, direction), direction,
self.browser.mw.app.keyboardModifiers(), self.browser.mw.app.keyboardModifiers(),
) )
self._view.selectionModel().setCurrentIndex( self._view.selectionModel().setCurrentIndex(
index, index,
cast( QItemSelectionModel.SelectionFlag.Clear
QItemSelectionModel.SelectionFlag, | QItemSelectionModel.SelectionFlag.Select
QItemSelectionModel.Clear | QItemSelectionModel.SelectionFlag.Rows,
| QItemSelectionModel.Select
| QItemSelectionModel.Rows,
),
) )
def _move_current_to_row(self, row: int) -> None: def _move_current_to_row(self, row: int) -> None:
@ -614,10 +621,8 @@ class Table:
selection = QItemSelection(new, old) selection = QItemSelection(new, old)
self._view.selectionModel().select( self._view.selectionModel().select(
selection, selection,
cast( QItemSelectionModel.SelectionFlag.SelectCurrent
QItemSelectionModel.SelectionFlag, | QItemSelectionModel.SelectionFlag.Rows,
QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows,
),
) )
@ -630,7 +635,7 @@ class StatusDelegate(QItemDelegate):
self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex
) -> None: ) -> None:
if self._model.get_cell(index).is_rtl: if self._model.get_cell(index).is_rtl:
option.direction = Qt.RightToLeft option.direction = Qt.LayoutDirection.RightToLeft
if row_color := self._model.get_row(index).color: if row_color := self._model.get_row(index).color:
brush = QBrush(theme_manager.qcolor(row_color)) brush = QBrush(theme_manager.qcolor(row_color))
painter.save() painter.save()

View file

@ -43,7 +43,7 @@ class ChangeNotetypeDialog(QDialog):
self.show() self.show()
def _setup_ui(self, notetype_id: NotetypeId) -> None: def _setup_ui(self, notetype_id: NotetypeId) -> None:
self.setWindowModality(Qt.ApplicationModal) self.setWindowModality(Qt.WindowModality.ApplicationModal)
self.mw.garbage_collect_on_dialog_finish(self) self.mw.garbage_collect_on_dialog_finish(self)
self.setMinimumWidth(400) self.setMinimumWidth(400)
disable_help_button(self) disable_help_button(self)

View file

@ -45,7 +45,7 @@ class CardLayout(QDialog):
parent: Optional[QWidget] = None, parent: Optional[QWidget] = None,
fill_empty: bool = False, fill_empty: bool = False,
) -> None: ) -> None:
QDialog.__init__(self, parent or mw, Qt.Window) QDialog.__init__(self, parent or mw, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self) mw.garbage_collect_on_dialog_finish(self)
self.mw = aqt.mw self.mw = aqt.mw
self.note = note self.note = note
@ -80,7 +80,7 @@ class CardLayout(QDialog):
self.redraw_everything() self.redraw_everything()
restoreGeom(self, "CardLayout") restoreGeom(self, "CardLayout")
restoreSplitter(self.mainArea, "CardLayoutMainArea") restoreSplitter(self.mainArea, "CardLayoutMainArea")
self.setWindowModality(Qt.ApplicationModal) self.setWindowModality(Qt.WindowModality.ApplicationModal)
self.show() self.show()
# take the focus away from the first input area when starting up, # take the focus away from the first input area when starting up,
# as users tend to accidentally type into the template # as users tend to accidentally type into the template
@ -108,7 +108,9 @@ class CardLayout(QDialog):
def setupTopArea(self) -> None: def setupTopArea(self) -> None:
self.topArea = QWidget() self.topArea = QWidget()
self.topArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.topArea.setSizePolicy(
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum
)
self.topAreaForm = aqt.forms.clayout_top.Ui_Form() self.topAreaForm = aqt.forms.clayout_top.Ui_Form()
self.topAreaForm.setupUi(self.topArea) self.topAreaForm.setupUi(self.topArea)
self.topAreaForm.templateOptions.setText( self.topAreaForm.templateOptions.setText(
@ -215,8 +217,8 @@ class CardLayout(QDialog):
def setupMainArea(self) -> None: def setupMainArea(self) -> None:
split = self.mainArea = QSplitter() split = self.mainArea = QSplitter()
split.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) split.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
split.setOrientation(Qt.Horizontal) split.setOrientation(Qt.Orientation.Horizontal)
left = QWidget() left = QWidget()
tform = self.tform = aqt.forms.template.Ui_Form() tform = self.tform = aqt.forms.template.Ui_Form()
tform.setupUi(left) tform.setupUi(left)
@ -305,7 +307,7 @@ class CardLayout(QDialog):
if not editor.find(text): if not editor.find(text):
# try again from top # try again from top
cursor = editor.textCursor() cursor = editor.textCursor()
cursor.movePosition(QTextCursor.Start) cursor.movePosition(QTextCursor.MoveOperation.Start)
editor.setTextCursor(cursor) editor.setTextCursor(cursor)
if not editor.find(text): if not editor.find(text):
tooltip("No matches found.") tooltip("No matches found.")
@ -752,7 +754,7 @@ class CardLayout(QDialog):
if t["did"]: if t["did"]:
te.setText(self.col.decks.get(t["did"])["name"]) te.setText(self.col.decks.get(t["did"])["name"])
te.selectAll() te.selectAll()
bb = QDialogButtonBox(QDialogButtonBox.Close) bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
qconnect(bb.rejected, d.close) qconnect(bb.rejected, d.close)
l.addWidget(bb) l.addWidget(bb)
d.setLayout(l) d.setLayout(l)

View file

@ -30,7 +30,7 @@ class CustomStudy(QDialog):
self.created_custom_study = False self.created_custom_study = False
f.setupUi(self) f.setupUi(self)
disable_help_button(self) disable_help_button(self)
self.setWindowModality(Qt.WindowModal) self.setWindowModality(Qt.WindowModality.WindowModal)
self.setupSignals() self.setupSignals()
f.radioNew.click() f.radioNew.click()
self.exec() self.exec()
@ -116,7 +116,7 @@ class CustomStudy(QDialog):
f.spin.setValue(sval) f.spin.setValue(sval)
f.preSpin.setText(pre) f.preSpin.setText(pre)
f.postSpin.setText(post) f.postSpin.setText(post)
f.buttonBox.button(QDialogButtonBox.Ok).setText(ok) f.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(ok)
self.radioIdx = idx self.radioIdx = idx
def accept(self) -> None: def accept(self) -> None:

View file

@ -6,8 +6,6 @@ from __future__ import annotations
from operator import itemgetter from operator import itemgetter
from typing import Any from typing import Any
from PyQt5.QtWidgets import QLineEdit
import aqt import aqt
from anki.consts import NEW_CARDS_RANDOM from anki.consts import NEW_CARDS_RANDOM
from anki.decks import DeckConfigDict from anki.decks import DeckConfigDict
@ -42,13 +40,15 @@ class DeckConf(QDialog):
self.mw.checkpoint(tr.actions_options()) self.mw.checkpoint(tr.actions_options())
self.setupCombos() self.setupCombos()
self.setupConfs() self.setupConfs()
self.setWindowModality(Qt.WindowModal) self.setWindowModality(Qt.WindowModality.WindowModal)
qconnect( qconnect(
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.DECK_OPTIONS) self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.DECK_OPTIONS)
) )
qconnect(self.form.confOpts.clicked, self.confOpts) qconnect(self.form.confOpts.clicked, self.confOpts)
qconnect( qconnect(
self.form.buttonBox.button(QDialogButtonBox.RestoreDefaults).clicked, self.form.buttonBox.button(
QDialogButtonBox.StandardButton.RestoreDefaults
).clicked,
self.onRestore, self.onRestore,
) )
self.setWindowTitle( self.setWindowTitle(

View file

@ -17,7 +17,7 @@ class DeckDescriptionDialog(QDialog):
silentlyClose = True silentlyClose = True
def __init__(self, mw: aqt.main.AnkiQt) -> None: def __init__(self, mw: aqt.main.AnkiQt) -> None:
QDialog.__init__(self, mw, Qt.Window) QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw self.mw = mw
# set on success # set on success
@ -39,7 +39,7 @@ class DeckDescriptionDialog(QDialog):
def _setup_ui(self) -> None: def _setup_ui(self) -> None:
self.setWindowTitle(tr.scheduling_description()) self.setWindowTitle(tr.scheduling_description())
self.setWindowModality(Qt.ApplicationModal) self.setWindowModality(Qt.WindowModality.ApplicationModal)
self.mw.garbage_collect_on_dialog_finish(self) self.mw.garbage_collect_on_dialog_finish(self)
self.setMinimumWidth(400) self.setMinimumWidth(400)
disable_help_button(self) disable_help_button(self)
@ -58,7 +58,7 @@ class DeckDescriptionDialog(QDialog):
box.addWidget(self.description) box.addWidget(self.description)
button_box = QDialogButtonBox() button_box = QDialogButtonBox()
ok = button_box.addButton(QDialogButtonBox.Ok) ok = button_box.addButton(QDialogButtonBox.StandardButton.Ok)
qconnect(ok.clicked, self.save_and_accept) qconnect(ok.clicked, self.save_and_accept)
box.addWidget(button_box) box.addWidget(button_box)

View file

@ -28,14 +28,14 @@ class DeckOptionsDialog(QDialog):
silentlyClose = True silentlyClose = True
def __init__(self, mw: aqt.main.AnkiQt, deck: DeckDict) -> None: def __init__(self, mw: aqt.main.AnkiQt, deck: DeckDict) -> None:
QDialog.__init__(self, mw, Qt.Window) QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw self.mw = mw
self._deck = deck self._deck = deck
self._setup_ui() self._setup_ui()
self.show() self.show()
def _setup_ui(self) -> None: def _setup_ui(self) -> None:
self.setWindowModality(Qt.ApplicationModal) self.setWindowModality(Qt.WindowModality.ApplicationModal)
self.mw.garbage_collect_on_dialog_finish(self) self.mw.garbage_collect_on_dialog_finish(self)
self.setMinimumWidth(400) self.setMinimumWidth(400)
disable_help_button(self) disable_help_button(self)

View file

@ -12,7 +12,7 @@ from aqt.utils import disable_help_button, restoreGeom, saveGeom, tr
class EditCurrent(QDialog): class EditCurrent(QDialog):
def __init__(self, mw: aqt.AnkiQt) -> None: def __init__(self, mw: aqt.AnkiQt) -> None:
QDialog.__init__(self, None, Qt.Window) QDialog.__init__(self, None, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self) mw.garbage_collect_on_dialog_finish(self)
self.mw = mw self.mw = mw
self.form = aqt.forms.editcurrent.Ui_Dialog() self.form = aqt.forms.editcurrent.Ui_Dialog()
@ -21,7 +21,7 @@ class EditCurrent(QDialog):
disable_help_button(self) disable_help_button(self)
self.setMinimumHeight(400) self.setMinimumHeight(400)
self.setMinimumWidth(250) self.setMinimumWidth(250)
self.form.buttonBox.button(QDialogButtonBox.Close).setShortcut( self.form.buttonBox.button(QDialogButtonBox.StandardButton.Close).setShortcut(
QKeySequence("Ctrl+Return") QKeySequence("Ctrl+Return")
) )
self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self) self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self)

View file

@ -902,7 +902,7 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
@deprecated(info=_js_legacy) @deprecated(info=_js_legacy)
def _onHtmlEdit(self, field: int) -> None: def _onHtmlEdit(self, field: int) -> None:
d = QDialog(self.widget, Qt.Window) d = QDialog(self.widget, Qt.WindowType.Window)
form = aqt.forms.edithtml.Ui_Dialog() form = aqt.forms.edithtml.Ui_Dialog()
form.setupUi(d) form.setupUi(d)
restoreGeom(d, "htmlEditor") restoreGeom(d, "htmlEditor")
@ -911,11 +911,11 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
form.buttonBox.helpRequested, lambda: openHelp(HelpPage.EDITING_FEATURES) form.buttonBox.helpRequested, lambda: openHelp(HelpPage.EDITING_FEATURES)
) )
font = QFont("Courier") font = QFont("Courier")
font.setStyleHint(QFont.TypeWriter) font.setStyleHint(QFont.StyleHint.TypeWriter)
form.textEdit.setFont(font) form.textEdit.setFont(font)
form.textEdit.setPlainText(self.note.fields[field]) form.textEdit.setPlainText(self.note.fields[field])
d.show() d.show()
form.textEdit.moveCursor(QTextCursor.End) form.textEdit.moveCursor(QTextCursor.MoveOperation.End)
d.exec() d.exec()
html = form.textEdit.toPlainText() html = form.textEdit.toPlainText()
if html.find(">") > -1: if html.find(">") > -1:
@ -997,7 +997,10 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
def onChangeCol(self) -> None: def onChangeCol(self) -> None:
if isLin: if isLin:
new = QColorDialog.getColor( new = QColorDialog.getColor(
QColor(self.fcolour), None, None, QColorDialog.DontUseNativeDialog QColor(self.fcolour),
None,
None,
QColorDialog.ColorDialogOption.DontUseNativeDialog,
) )
else: else:
new = QColorDialog.getColor(QColor(self.fcolour), None) new = QColorDialog.getColor(QColor(self.fcolour), None)
@ -1118,10 +1121,10 @@ class EditorWebView(AnkiWebView):
self._flagAnkiText() self._flagAnkiText()
def onCut(self) -> None: def onCut(self) -> None:
self.triggerPageAction(QWebEnginePage.Cut) self.triggerPageAction(QWebEnginePage.WebAction.Cut)
def onCopy(self) -> None: def onCopy(self) -> None:
self.triggerPageAction(QWebEnginePage.Copy) self.triggerPageAction(QWebEnginePage.WebAction.Copy)
def _wantsExtendedPaste(self) -> bool: def _wantsExtendedPaste(self) -> bool:
strip_html = self.editor.mw.col.get_config_bool( strip_html = self.editor.mw.col.get_config_bool(
@ -1140,10 +1143,10 @@ class EditorWebView(AnkiWebView):
self.editor.doPaste(html, internal, extended) self.editor.doPaste(html, internal, extended)
def onPaste(self) -> None: def onPaste(self) -> None:
self._onPaste(QClipboard.Clipboard) self._onPaste(QClipboard.Mode.Clipboard)
def onMiddleClickPaste(self) -> None: def onMiddleClickPaste(self) -> None:
self._onPaste(QClipboard.Selection) self._onPaste(QClipboard.Mode.Selection)
def dragEnterEvent(self, evt: QDragEnterEvent) -> None: def dragEnterEvent(self, evt: QDragEnterEvent) -> None:
evt.accept() evt.accept()

View file

@ -63,7 +63,7 @@ class EmptyCardsDialog(QDialog):
qconnect(self.finished, on_finished) qconnect(self.finished, on_finished)
self._delete_button = self.form.buttonBox.addButton( self._delete_button = self.form.buttonBox.addButton(
tr.empty_cards_delete_button(), QDialogButtonBox.ActionRole tr.empty_cards_delete_button(), QDialogButtonBox.ButtonRole.ActionRole
) )
self._delete_button.setAutoDefault(False) self._delete_button.setAutoDefault(False)
qconnect(self._delete_button.clicked, self._on_delete) qconnect(self._delete_button.clicked, self._on_delete)

View file

@ -31,7 +31,7 @@ class ExportDialog(QDialog):
did: DeckId | None = None, did: DeckId | None = None,
cids: list[CardId] | None = None, cids: list[CardId] | None = None,
): ):
QDialog.__init__(self, mw, Qt.Window) QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw self.mw = mw
self.col = mw.col.weakref() self.col = mw.col.weakref()
self.frm = aqt.forms.exporting.Ui_ExportDialog() self.frm = aqt.forms.exporting.Ui_ExportDialog()
@ -64,7 +64,7 @@ class ExportDialog(QDialog):
self.frm.deck.addItems(self.decks) self.frm.deck.addItems(self.decks)
# save button # save button
b = QPushButton(tr.exporting_export()) b = QPushButton(tr.exporting_export())
self.frm.buttonBox.addButton(b, QDialogButtonBox.AcceptRole) self.frm.buttonBox.addButton(b, QDialogButtonBox.ButtonRole.AcceptRole)
# set default option if accessed through deck button # set default option if accessed through deck button
if did: if did:
name = self.mw.col.decks.get(did)["name"] name = self.mw.col.decks.get(did)["name"]

View file

@ -45,13 +45,19 @@ class FieldDialog(QDialog):
without_unicode_isolation(tr.fields_fields_for(val=self.model["name"])) without_unicode_isolation(tr.fields_fields_for(val=self.model["name"]))
) )
disable_help_button(self) disable_help_button(self)
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False) self.form.buttonBox.button(QDialogButtonBox.StandardButton.Help).setAutoDefault(
self.form.buttonBox.button(QDialogButtonBox.Cancel).setAutoDefault(False) False
self.form.buttonBox.button(QDialogButtonBox.Save).setAutoDefault(False) )
self.form.buttonBox.button(
QDialogButtonBox.StandardButton.Cancel
).setAutoDefault(False)
self.form.buttonBox.button(QDialogButtonBox.StandardButton.Save).setAutoDefault(
False
)
self.currentIdx: Optional[int] = None self.currentIdx: Optional[int] = None
self.fillFields() self.fillFields()
self.setupSignals() self.setupSignals()
self.form.fieldList.setDragDropMode(QAbstractItemView.InternalMove) self.form.fieldList.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
self.form.fieldList.dropEvent = self.onDrop # type: ignore[assignment] self.form.fieldList.dropEvent = self.onDrop # type: ignore[assignment]
self.form.fieldList.setCurrentRow(open_at) self.form.fieldList.setCurrentRow(open_at)
self.exec() self.exec()
@ -77,15 +83,21 @@ class FieldDialog(QDialog):
def onDrop(self, ev: QDropEvent) -> None: def onDrop(self, ev: QDropEvent) -> None:
fieldList = self.form.fieldList fieldList = self.form.fieldList
indicatorPos = fieldList.dropIndicatorPosition() indicatorPos = fieldList.dropIndicatorPosition()
dropPos = fieldList.indexAt(ev.pos()).row() if qtmajor == 5:
pos = ev.pos() # type: ignore
else:
pos = ev.position().toPoint()
dropPos = fieldList.indexAt(pos).row()
idx = self.currentIdx idx = self.currentIdx
if dropPos == idx: if dropPos == idx:
return return
if indicatorPos == QAbstractItemView.OnViewport: # to bottom. if (
indicatorPos == QAbstractItemView.DropIndicatorPosition.OnViewport
): # to bottom.
movePos = fieldList.count() - 1 movePos = fieldList.count() - 1
elif indicatorPos == QAbstractItemView.AboveItem: elif indicatorPos == QAbstractItemView.DropIndicatorPosition.AboveItem:
movePos = dropPos movePos = dropPos
elif indicatorPos == QAbstractItemView.BelowItem: elif indicatorPos == QAbstractItemView.DropIndicatorPosition.BelowItem:
movePos = dropPos + 1 movePos = dropPos + 1
# the item in idx is removed thus subtract 1. # the item in idx is removed thus subtract 1.
if idx < dropPos: if idx < dropPos:

View file

@ -90,7 +90,7 @@ class FilteredDeckConfigDialog(QDialog):
QPushButton[label="hint"] {{ color: {grey} }}""" QPushButton[label="hint"] {{ color: {grey} }}"""
) )
disable_help_button(self) disable_help_button(self)
self.setWindowModality(Qt.WindowModal) self.setWindowModality(Qt.WindowModality.WindowModal)
qconnect( qconnect(
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.FILTERED_DECK) self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.FILTERED_DECK)
) )
@ -117,7 +117,9 @@ class FilteredDeckConfigDialog(QDialog):
build_label = tr.actions_rebuild() build_label = tr.actions_rebuild()
else: else:
build_label = tr.decks_build() build_label = tr.decks_build()
self.form.buttonBox.button(QDialogButtonBox.Ok).setText(build_label) self.form.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
build_label
)
form.resched.setChecked(config.reschedule) form.resched.setChecked(config.reschedule)
self._onReschedToggled(0) self._onReschedToggled(0)

View file

@ -1,17 +1,48 @@
load("@rules_python//python:defs.bzl", "py_binary") load("@rules_python//python:defs.bzl", "py_binary")
load("compile.bzl", "compile_all") load("compile.bzl", "compile_all")
py_binary(
name = "build_ui_qt5",
srcs = ["build_ui_qt5.py"],
legacy_create_init = False,
deps = ["@pyqt5//:pkg"],
)
py_binary(
name = "build_ui_qt6",
srcs = ["build_ui_qt6.py"],
legacy_create_init = False,
deps = ["@pyqt6//:pkg"],
)
compile_all( compile_all(
name = "forms_qt5",
srcs = glob(["*.ui"]), srcs = glob(["*.ui"]),
group = "forms", builder = "build_ui_qt5",
suffix = "_qt5",
)
compile_all(
name = "forms_qt6",
srcs = glob(["*.ui"]),
builder = "build_ui_qt6",
suffix = "_qt6",
)
filegroup(
name = "forms",
srcs = glob(
["*.py"],
exclude = [
"*_qt5.py",
"*_qt6.py",
"build_ui*.py",
],
) + [
":forms_qt6",
":forms_qt5",
],
visibility = [ visibility = [
"//qt/aqt:__pkg__", "//qt/aqt:__pkg__",
], ],
) )
py_binary(
name = "build_ui",
srcs = ["build_ui.py"],
legacy_create_init = False,
deps = ["@pyqt5//:pkg"],
)

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/__init___qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/about.py

5
qt/aqt/forms/about.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .about_qt6 import *
else:
from .about_qt5 import * # type: ignore

1
qt/aqt/forms/about_qt6.py Symbolic link
View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/about_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/addcards.py

5
qt/aqt/forms/addcards.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .addcards_qt6 import *
else:
from .addcards_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/addcards_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/addfield.py

5
qt/aqt/forms/addfield.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .addfield_qt6 import *
else:
from .addfield_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/addfield_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/addmodel.py

5
qt/aqt/forms/addmodel.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .addmodel_qt6 import *
else:
from .addmodel_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/addmodel_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/addonconf.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .addonconf_qt6 import *
else:
from .addonconf_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/addonconf_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/addons.py

5
qt/aqt/forms/addons.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .addons_qt6 import *
else:
from .addons_qt5 import * # type: ignore

1
qt/aqt/forms/addons_qt6.py Symbolic link
View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/addons_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/browser.py

5
qt/aqt/forms/browser.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .browser_qt6 import *
else:
from .browser_qt5 import * # type: ignore

1
qt/aqt/forms/browser_qt6.py Symbolic link
View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/browser_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/browserdisp.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .browserdisp_qt6 import *
else:
from .browserdisp_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/browserdisp_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/browseropts.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .browseropts_qt6 import *
else:
from .browseropts_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/browseropts_qt6.py

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/build_ui_qt5_qt6.py

View file

@ -0,0 +1,39 @@
import re
import sys
import io
from PyQt6.uic import compileUi
ui_file = sys.argv[1]
py_file = sys.argv[2]
buf = io.StringIO()
compileUi(open(ui_file), buf)
outdata = buf.getvalue()
outdata = outdata.replace(
"from PyQt6 import QtCore, QtGui, QtWidgets",
"from PyQt6 import QtCore, QtGui, QtWidgets\nfrom aqt.utils import tr\n"
)
outdata = re.sub(
r'(?:QtGui\.QApplication\.)?_?translate\(".*?", "(.*?)"', "tr.\\1(", outdata
)
outlines = []
qt_bad_types = [
".connect(",
]
for line in outdata.splitlines():
for substr in qt_bad_types:
if substr in line:
line = line + " # type: ignore"
break
if line == "from . import icons_rc":
continue
line = line.replace(":/icons/", "icons:")
line = line.replace("QAction.PreferencesRole", "QAction.MenuRole.PreferencesRole")
line = line.replace("QAction.AboutRole", "QAction.MenuRole.AboutRole")
line = line.replace("QComboBox.AdjustToMinimumContentsLength", "QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength")
outlines.append(line)
with open(py_file, "w") as file:
file.write("\n".join(outlines))

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/build_ui_qt6_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/changemap.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .changemap_qt6 import *
else:
from .changemap_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/changemap_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/changemodel.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .changemodel_qt6 import *
else:
from .changemodel_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/changemodel_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/clayout_top.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .clayout_top_qt6 import *
else:
from .clayout_top_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/clayout_top_qt6.py

View file

@ -1,28 +1,28 @@
def compile(name, ui_file, py_file): def compile(name, ui_file, py_file, builder):
native.genrule( native.genrule(
name = name, name = name,
srcs = [ui_file], srcs = [ui_file],
outs = [py_file], outs = [py_file],
cmd = "$(location build_ui) $(location {ui_file}) $(location {py_file})".format( cmd = "$(location {builder}) $(location {ui_file}) $(location {py_file})".format(
builder = builder,
ui_file = ui_file, ui_file = ui_file,
py_file = py_file, py_file = py_file,
), ),
tools = [ tools = [
"build_ui", builder,
], ],
message = "Building UI", message = "Building UI",
) )
def compile_all(group, srcs, visibility): def compile_all(name, builder, srcs, suffix):
py_files = [] py_files = []
for ui_file in srcs: for ui_file in srcs:
name = ui_file.replace(".ui", "") fname = ui_file.replace(".ui", "") + suffix
py_file = name + ".py" py_file = fname + ".py"
py_files.append(py_file) py_files.append(py_file)
compile(name, ui_file, py_file) compile(fname, ui_file, py_file, builder)
native.filegroup( native.filegroup(
name = group, name = name,
srcs = py_files + ["__init__.py"], srcs = py_files,
visibility = visibility,
) )

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/customstudy.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .customstudy_qt6 import *
else:
from .customstudy_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/customstudy_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/dconf.py

5
qt/aqt/forms/dconf.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .dconf_qt6 import *
else:
from .dconf_qt5 import * # type: ignore

1
qt/aqt/forms/dconf_qt6.py Symbolic link
View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/dconf_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/debug.py

5
qt/aqt/forms/debug.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .debug_qt6 import *
else:
from .debug_qt5 import * # type: ignore

1
qt/aqt/forms/debug_qt6.py Symbolic link
View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/debug_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/editaddon.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .editaddon_qt6 import *
else:
from .editaddon_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/editaddon_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/editcurrent.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .editcurrent_qt6 import *
else:
from .editcurrent_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/editcurrent_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/edithtml.py

5
qt/aqt/forms/edithtml.py Normal file
View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .edithtml_qt6 import *
else:
from .edithtml_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/edithtml_qt6.py

View file

@ -1 +0,0 @@
../../../bazel-bin/qt/aqt/forms/emptycards.py

View file

@ -0,0 +1,5 @@
from aqt.qt import qtmajor
if qtmajor > 5:
from .emptycards_qt6 import *
else:
from .emptycards_qt5 import * # type: ignore

View file

@ -0,0 +1 @@
../../../bazel-bin/qt/aqt/forms/emptycards_qt6.py

Some files were not shown because too many files have changed in this diff Show more