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("@com_github_ali5h_rules_pip//:defs.bzl", "pip_import")
load("//pip/pyqt5:defs.bzl", "install_pyqt5")
load("//pip/pyqt6:defs.bzl", "install_pyqt6")
anki_version = "2.1.49"
@ -43,6 +44,11 @@ def setup_deps():
python_runtime = "@python//:python",
)
install_pyqt6(
name = "pyqt6",
python_runtime = "@python//:python",
)
node_repositories(package_json = ["@ankidesktop//:package.json"])
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({
"//platforms:windows_x86_64": "win_amd64",
"//platforms:macos_x86_64": "macosx_10_7_x86_64",
"//platforms:linux_x86_64": "manylinux2014_x86_64",
"//platforms:linux_arm64": "manylinux2014_aarch64",
"//platforms:macos_x86_64": "macosx_10_13_x86_64",
"//platforms:linux_x86_64": "manylinux_2_28_x86_64",
"//platforms:linux_arm64": "manylinux_2_28_aarch64",
}),
python_tag = "cp38",
python_tag = "cp39",
python_version = ">=3.9",
requires = [
"beautifulsoup4",
@ -124,7 +124,10 @@ py_library(
":proto_py",
],
# includes the .pyi files
data = [":proto_py", "py.typed"],
data = [
"py.typed",
":proto_py",
],
imports = [".."],
visibility = ["//visibility:public"],
)

View file

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

View file

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

View file

@ -45,21 +45,21 @@ py_test(
args = [
"aqt",
"$(location mypy.ini)",
"$(location @pyqt5//:__init__.py)",
"$(location @pyqt6//:__init__.py)",
"$(location //pip/stubs:extendsitepkgs)",
],
data = [
"mypy.ini",
"//pip/stubs",
"//pip/stubs:extendsitepkgs",
"@pyqt5//:__init__.py",
"@pyqt6//:__init__.py",
],
env = {"EXTRA_SITE_PACKAGES": "$(location //pip/stubs)"},
main = "tests/run_mypy.py",
deps = [
"//pylib/anki",
"//qt/aqt:aqt_without_data",
"@pyqt5//:pkg",
"@pyqt6//:pkg",
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(
name = "dmypy",
srcs = [

View file

@ -50,7 +50,6 @@ aqt_deps = [
requirement("waitress"),
requirement("send2trash"),
requirement("jsonschema"),
"@pyqt5//:pkg",
] + select({
"@bazel_tools//src/conditions:host_windows": [
requirement("psutil"),
@ -66,7 +65,9 @@ py_library(
srcs = _py_srcs_and_forms,
data = aqt_core_data,
visibility = ["//visibility:public"],
deps = aqt_deps,
deps = aqt_deps + [
"@pyqt6//:pkg",
],
)
py_library(
@ -74,7 +75,19 @@ py_library(
srcs = _py_srcs_and_forms,
data = aqt_core_data + ["//qt/aqt/data"],
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(
@ -94,10 +107,20 @@ py_wheel(
entry_points = {
"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",
license = "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
python_tag = "py3",
python_version = ">=3.8",
python_version = ">=3.9",
requires = [
"beautifulsoup4",
"requests",
@ -106,12 +129,9 @@ py_wheel(
"flask",
"flask_cors",
"waitress",
"pyqt5>=5.12",
"pyqtwebengine",
'psutil; 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" and platform_release == "10" and python_version >= "3.9"',
'winrt; sys.platform == "win32"',
"anki==" + anki_version,
],
strip_path_prefixes = [

View file

@ -99,8 +99,10 @@ class DialogManager:
def open(self, name: str, *args: Any, **kwargs: Any) -> Any:
(creator, instance) = self._dialogs[name]
if instance:
if instance.windowState() & Qt.WindowMinimized:
instance.setWindowState(instance.windowState() & ~Qt.WindowMinimized)
if instance.windowState() & Qt.WindowState.WindowMinimized:
instance.setWindowState(
instance.windowState() & ~Qt.WindowState.WindowMinimized
)
instance.activateWindow()
instance.raise_()
if hasattr(instance, "reopen"):
@ -224,9 +226,9 @@ def setupLangAndBackend(
# switch direction for RTL languages
if anki.lang.is_rtl(lang):
app.setLayoutDirection(Qt.RightToLeft)
app.setLayoutDirection(Qt.LayoutDirection.RightToLeft)
else:
app.setLayoutDirection(Qt.LeftToRight)
app.setLayoutDirection(Qt.LayoutDirection.LeftToRight)
# load qt translations
_qtrans = QTranslator()
@ -238,7 +240,10 @@ def setupLangAndBackend(
os.path.join(aqt_data_folder(), "..", "qt_translations")
)
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("-", "_")
if _qtrans.load(f"qtbase_{qt_lang}", qt_dir):
app.installTranslator(_qtrans)
@ -285,7 +290,7 @@ class AnkiApp(QApplication):
def sendMsg(self, txt: str) -> bool:
sock = QLocalSocket(self)
sock.connectToServer(self.KEY, QIODevice.WriteOnly)
sock.connectToServer(self.KEY, QIODevice.OpenModeFlag.WriteOnly)
if not sock.waitForConnected(self.TMOUT):
# first instance or previous instance dead
return False
@ -315,7 +320,7 @@ class AnkiApp(QApplication):
##################################################
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
return True
return QApplication.event(self, evt)
@ -360,20 +365,18 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
# catch opengl errors
def msgHandler(category: Any, ctx: Any, msg: Any) -> None:
if category == QtDebugMsg:
if category == QtMsgType.QtDebugMsg:
category = "debug"
elif category == QtInfoMsg:
elif category == QtMsgType.QtInfoMsg:
category = "info"
elif category == QtWarningMsg:
elif category == QtMsgType.QtWarningMsg:
category = "warning"
elif category == QtCriticalMsg:
elif category == QtMsgType.QtCriticalMsg:
category = "critical"
elif category == QtDebugMsg:
elif category == QtMsgType.QtDebugMsg:
category = "debug"
elif category == QtFatalMsg:
elif category == QtMsgType.QtFatalMsg:
category = "fatal"
elif category == QtSystemMsg:
category = "system"
else:
category = "unknown"
context = ""
@ -407,7 +410,7 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
if isWin:
os.environ["QT_OPENGL"] = driver.value
elif isMac:
QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
elif isLin:
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())
# opt in to full hidpi support?
if not os.environ.get("ANKI_NOHIGHDPI"):
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
if not os.environ.get("ANKI_NOHIGHDPI") and qtmajor == 5:
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling) # type: ignore
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps) # type: ignore
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1"
os.environ["QT_SCALE_FACTOR_ROUNDING_POLICY"] = "PassThrough"
# Opt into software rendering. Useful for buggy systems.
if os.environ.get("ANKI_SOFTWAREOPENGL"):
QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)
QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseSoftwareOpenGL)
if (
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
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
if isWin and qtminor >= 10:
QApplication.setAttribute(Qt.AA_DisableWindowContextHelpButton)
if isWin and qtmajor == 5 and qtminor >= 10:
QApplication.setAttribute(
QApplication.Attribute.AA_DisableWindowContextHelpButton # type: ignore
)
# proxy configured?
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:
print("webview proxy use disabled")
proxy = QNetworkProxy()
proxy.setType(QNetworkProxy.NoProxy)
proxy.setType(QNetworkProxy.ProxyType.NoProxy)
QNetworkProxy.setApplicationProxy(proxy)
# 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())
qconnect(btn.clicked, onCopy)
abt.buttonBox.addButton(btn, QDialogButtonBox.ActionRole)
abt.buttonBox.button(QDialogButtonBox.Ok).setFocus()
abt.buttonBox.addButton(btn, QDialogButtonBox.ButtonRole.ActionRole)
abt.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setFocus()
# WebView contents
######################################################################

View file

@ -35,7 +35,7 @@ from aqt.utils import (
class AddCards(QDialog):
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)
self.mw = mw
self.col = mw.col
@ -85,7 +85,7 @@ class AddCards(QDialog):
def setupButtons(self) -> None:
bb = self.form.buttonBox
ar = QDialogButtonBox.ActionRole
ar = QDialogButtonBox.ButtonRole.ActionRole
# add
self.addButton = bb.addButton(tr.actions_add(), ar)
qconnect(self.addButton.clicked, self.add_current_note)
@ -97,11 +97,11 @@ class AddCards(QDialog):
# close
self.closeButton = QPushButton(tr.actions_close())
self.closeButton.setAutoDefault(False)
bb.addButton(self.closeButton, QDialogButtonBox.RejectRole)
bb.addButton(self.closeButton, QDialogButtonBox.ButtonRole.RejectRole)
# help
self.helpButton = QPushButton(tr.actions_help(), clicked=self.helpRequested) # type: ignore
self.helpButton.setAutoDefault(False)
bb.addButton(self.helpButton, QDialogButtonBox.HelpRole)
bb.addButton(self.helpButton, QDialogButtonBox.ButtonRole.HelpRole)
# history
b = bb.addButton(f"{tr.adding_history()} {downArrow()}", ar)
if isMac:
@ -266,7 +266,10 @@ class AddCards(QDialog):
def keyPressEvent(self, evt: QKeyEvent) -> None:
"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()
return
return QDialog.keyPressEvent(self, evt)

View file

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

View file

@ -104,7 +104,7 @@ class Browser(QMainWindow):
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.col = self.mw.col
self.lastFilter = ""
@ -255,7 +255,7 @@ class Browser(QMainWindow):
onsuccess()
def keyPressEvent(self, evt: QKeyEvent) -> None:
if evt.key() == Qt.Key_Escape:
if evt.key() == Qt.Key.Key_Escape:
self.close()
else:
super().keyPressEvent(evt)
@ -490,9 +490,9 @@ class Browser(QMainWindow):
def setupSidebar(self) -> None:
dw = self.sidebarDockWidget = QDockWidget(tr.browsing_sidebar(), self)
dw.setFeatures(QDockWidget.NoDockWidgetFeatures)
dw.setFeatures(QDockWidget.DockWidgetFeature.NoDockWidgetFeatures)
dw.setObjectName("Sidebar")
dw.setAllowedAreas(Qt.LeftDockWidgetArea)
dw.setAllowedAreas(Qt.DockWidgetArea.LeftDockWidgetArea)
self.sidebar = SidebarTreeView(self)
self.sidebarTree = self.sidebar # legacy alias
@ -513,7 +513,7 @@ class Browser(QMainWindow):
self.sidebarDockWidget.setFloating(False)
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
# UI is more responsive

View file

@ -28,7 +28,7 @@ class CardInfoDialog(QDialog):
self.show()
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)
disable_help_button(self)
restoreGeom(self, self.GEOMETRY_KEY)
@ -40,7 +40,7 @@ class CardInfoDialog(QDialog):
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.web)
buttons = QDialogButtonBox(QDialogButtonBox.Close)
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
buttons.setContentsMargins(10, 0, 10, 10)
layout.addWidget(buttons)
qconnect(buttons.rejected, self.reject)

View file

@ -73,16 +73,18 @@ class FindAndReplaceDialog(QDialog):
disable_help_button(self)
self.form = aqt.forms.findreplace.Ui_Dialog()
self.form.setupUi(self)
self.setWindowModality(Qt.WindowModal)
self.setWindowModality(Qt.WindowModality.WindowModal)
self._find_history = restore_combo_history(
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.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:
# no selected notes to affect

View file

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

View file

@ -46,14 +46,14 @@ class Previewer(QDialog):
def __init__(
self, parent: QWidget, mw: AnkiQt, on_close: Callable[[], None]
) -> None:
super().__init__(None, Qt.Window)
super().__init__(None, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self)
self._open = True
self._parent = parent
self._close_callback = on_close
self.mw = mw
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)
self.setWindowIcon(icon)
@ -86,7 +86,7 @@ class Previewer(QDialog):
self.bbox = QDialogButtonBox()
self._replay = self.bbox.addButton(
tr.actions_replay_audio(), QDialogButtonBox.ActionRole
tr.actions_replay_audio(), QDialogButtonBox.ButtonRole.ActionRole
)
self._replay.setAutoDefault(False)
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.setShortcut(QKeySequence("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(
Config.Bool.PREVIEW_BOTH_SIDES
)
@ -266,12 +266,12 @@ class MultiCardPreviewer(Previewer):
def _create_gui(self) -> None:
super()._create_gui()
self._prev = self.bbox.addButton("<", QDialogButtonBox.ActionRole)
self._prev = self.bbox.addButton("<", QDialogButtonBox.ButtonRole.ActionRole)
self._prev.setAutoDefault(False)
self._prev.setShortcut(QKeySequence("Left"))
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.setShortcut(QKeySequence("Right"))
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)
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():
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()
item: SidebarItem = index.internalPointer()
if role in (Qt.DisplayRole, Qt.EditRole):
if role in (Qt.ItemDataRole.DisplayRole, Qt.ItemDataRole.EditRole):
return QVariant(item.name)
if role == Qt.ToolTipRole:
if role == Qt.ItemDataRole.ToolTipRole:
return QVariant(item.tooltip)
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)
def supportedDropActions(self) -> Qt.DropActions:
return cast(Qt.DropActions, Qt.MoveAction)
def supportedDropActions(self) -> Qt.DropAction:
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():
return cast(Qt.ItemFlags, Qt.ItemIsEnabled)
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
return cast(Qt.ItemFlag, Qt.ItemFlag.ItemIsEnabled)
flags = (
Qt.ItemFlag.ItemIsEnabled
| Qt.ItemFlag.ItemIsSelectable
| Qt.ItemFlag.ItemIsDragEnabled
)
item: SidebarItem = index.internalPointer()
if item.item_type in self.sidebar.valid_drop_types:
flags |= Qt.ItemIsDropEnabled
flags |= Qt.ItemFlag.ItemIsDropEnabled
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())
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()
elif evt.key() in (Qt.Key_Enter, Qt.Key_Return):
elif evt.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return):
self.onSearch()
else:
QLineEdit.keyPressEvent(self, evt)

View file

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

View file

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

View file

@ -3,7 +3,7 @@
from __future__ import annotations
import time
from typing import Any, Callable, Sequence, cast
from typing import Any, Callable, Sequence
import aqt
from anki.cards import Card, CardId
@ -307,7 +307,7 @@ class DataModel(QAbstractTableModel):
def data(self, index: QModelIndex = QModelIndex(), role: int = 0) -> Any:
if not index.isValid():
return QVariant()
if role == Qt.FontRole:
if role == Qt.ItemDataRole.FontRole:
if not self.column_at(index).uses_cell_font:
return QVariant()
qfont = QFont()
@ -315,30 +315,33 @@ class DataModel(QAbstractTableModel):
qfont.setFamily(row.font_name)
qfont.setPixelSize(row.font_size)
return qfont
elif role == Qt.TextAlignmentRole:
align: Qt.AlignmentFlag | int = Qt.AlignVCenter
elif role == Qt.ItemDataRole.TextAlignmentRole:
align: Qt.AlignmentFlag | int = Qt.AlignmentFlag.AlignVCenter
if self.column_at(index).alignment == Columns.ALIGNMENT_CENTER:
align |= Qt.AlignHCenter
align |= Qt.AlignmentFlag.AlignHCenter
return align
elif role == Qt.DisplayRole:
elif role == Qt.ItemDataRole.DisplayRole:
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 QVariant()
def headerData(
self, section: int, orientation: Qt.Orientation, role: int = 0
) -> 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 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
if row := self.get_cached_row(index):
if row.is_deleted:
return Qt.ItemFlags(Qt.NoItemFlags)
return cast(Qt.ItemFlags, Qt.ItemIsEnabled | Qt.ItemIsSelectable)
return Qt.ItemFlag(Qt.ItemFlag.NoItemFlags)
return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable
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
from __future__ import annotations
from typing import Any, Callable, Sequence, cast
from typing import Any, Callable, Sequence
import aqt
import aqt.forms
@ -127,10 +127,8 @@ class Table:
self.select_all()
self._view.selectionModel().select(
selection,
cast(
QItemSelectionModel.SelectionFlags,
QItemSelectionModel.Deselect | QItemSelectionModel.Rows,
),
QItemSelectionModel.SelectionFlag.Deselect
| QItemSelectionModel.SelectionFlag.Rows,
)
def select_single_card(self, card_id: CardId) -> None:
@ -202,10 +200,10 @@ class Table:
# Move cursor
def to_previous_row(self) -> None:
self._move_current(QAbstractItemView.MoveUp)
self._move_current(QAbstractItemView.CursorAction.MoveUp)
def to_next_row(self) -> None:
self._move_current(QAbstractItemView.MoveDown)
self._move_current(QAbstractItemView.CursorAction.MoveDown)
def to_first_row(self) -> None:
self._move_current_to_row(0)
@ -248,7 +246,8 @@ class Table:
def clear_current(self) -> None:
self._view.selectionModel().setCurrentIndex(
QModelIndex(), QItemSelectionModel.NoUpdate
QModelIndex(),
QItemSelectionModel.SelectionFlag.NoUpdate,
)
# Private methods
@ -268,7 +267,10 @@ class Table:
index = self._model.index(
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:
"""Remove selection and focus without emitting signals.
@ -286,7 +288,9 @@ class Table:
self._model.index(row, 0),
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:
hh = self._view.horizontalHeader()
@ -295,9 +299,9 @@ class Table:
hh.setSortIndicatorShown(False)
return
if self._state.sort_backwards:
order = Qt.DescendingOrder
order = Qt.SortOrder.DescendingOrder
else:
order = Qt.AscendingOrder
order = Qt.SortOrder.AscendingOrder
hh.blockSignals(True)
hh.setSortIndicator(index, order)
hh.blockSignals(False)
@ -305,9 +309,10 @@ class Table:
def _set_column_sizes(self) -> None:
hh = self._view.horizontalHeader()
hh.setSectionResizeMode(QHeaderView.Interactive)
hh.setSectionResizeMode(QHeaderView.ResizeMode.Interactive)
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
hh.setCascadingSectionResizes(False)
@ -334,7 +339,7 @@ class Table:
)
qconnect(self._view.selectionModel().currentChanged, self._on_current_changed)
self._view.setWordWrap(False)
self._view.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
self._view.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
self._view.horizontalScrollBar().setSingleStep(10)
self._update_font()
if not theme_manager.night_mode:
@ -346,7 +351,7 @@ class Table:
self._view.setStyleSheet(
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)
def _update_font(self) -> None:
@ -369,7 +374,7 @@ class Table:
hh.setHighlightSections(False)
hh.setMinimumSectionSize(50)
hh.setSectionsMovable(True)
hh.setContextMenuPolicy(Qt.CustomContextMenu)
hh.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self._restore_header()
qconnect(hh.customContextMenuRequested, self._on_header_context)
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()
if not visible or scroll_even_if_visible:
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)
def _scroll_to_column(self, column: int) -> None:
@ -583,26 +590,26 @@ class Table:
if not visible:
vertical = self._view.verticalScrollBar().value()
self._view.scrollTo(
self._model.index(0, column), self._view.PositionAtCenter
self._model.index(0, column),
QAbstractItemView.ScrollHint.PositionAtCenter,
)
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():
return
if index is None:
index = self._view.moveCursor(
cast(QAbstractItemView.CursorAction, direction),
direction,
self.browser.mw.app.keyboardModifiers(),
)
self._view.selectionModel().setCurrentIndex(
index,
cast(
QItemSelectionModel.SelectionFlag,
QItemSelectionModel.Clear
| QItemSelectionModel.Select
| QItemSelectionModel.Rows,
),
QItemSelectionModel.SelectionFlag.Clear
| QItemSelectionModel.SelectionFlag.Select
| QItemSelectionModel.SelectionFlag.Rows,
)
def _move_current_to_row(self, row: int) -> None:
@ -614,10 +621,8 @@ class Table:
selection = QItemSelection(new, old)
self._view.selectionModel().select(
selection,
cast(
QItemSelectionModel.SelectionFlag,
QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows,
),
QItemSelectionModel.SelectionFlag.SelectCurrent
| QItemSelectionModel.SelectionFlag.Rows,
)
@ -630,7 +635,7 @@ class StatusDelegate(QItemDelegate):
self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex
) -> None:
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:
brush = QBrush(theme_manager.qcolor(row_color))
painter.save()

View file

@ -43,7 +43,7 @@ class ChangeNotetypeDialog(QDialog):
self.show()
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.setMinimumWidth(400)
disable_help_button(self)

View file

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

View file

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

View file

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

View file

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

View file

@ -28,14 +28,14 @@ class DeckOptionsDialog(QDialog):
silentlyClose = True
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._deck = deck
self._setup_ui()
self.show()
def _setup_ui(self) -> None:
self.setWindowModality(Qt.ApplicationModal)
self.setWindowModality(Qt.WindowModality.ApplicationModal)
self.mw.garbage_collect_on_dialog_finish(self)
self.setMinimumWidth(400)
disable_help_button(self)

View file

@ -12,7 +12,7 @@ from aqt.utils import disable_help_button, restoreGeom, saveGeom, tr
class EditCurrent(QDialog):
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)
self.mw = mw
self.form = aqt.forms.editcurrent.Ui_Dialog()
@ -21,7 +21,7 @@ class EditCurrent(QDialog):
disable_help_button(self)
self.setMinimumHeight(400)
self.setMinimumWidth(250)
self.form.buttonBox.button(QDialogButtonBox.Close).setShortcut(
self.form.buttonBox.button(QDialogButtonBox.StandardButton.Close).setShortcut(
QKeySequence("Ctrl+Return")
)
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)
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.setupUi(d)
restoreGeom(d, "htmlEditor")
@ -911,11 +911,11 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
form.buttonBox.helpRequested, lambda: openHelp(HelpPage.EDITING_FEATURES)
)
font = QFont("Courier")
font.setStyleHint(QFont.TypeWriter)
font.setStyleHint(QFont.StyleHint.TypeWriter)
form.textEdit.setFont(font)
form.textEdit.setPlainText(self.note.fields[field])
d.show()
form.textEdit.moveCursor(QTextCursor.End)
form.textEdit.moveCursor(QTextCursor.MoveOperation.End)
d.exec()
html = form.textEdit.toPlainText()
if html.find(">") > -1:
@ -997,7 +997,10 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
def onChangeCol(self) -> None:
if isLin:
new = QColorDialog.getColor(
QColor(self.fcolour), None, None, QColorDialog.DontUseNativeDialog
QColor(self.fcolour),
None,
None,
QColorDialog.ColorDialogOption.DontUseNativeDialog,
)
else:
new = QColorDialog.getColor(QColor(self.fcolour), None)
@ -1118,10 +1121,10 @@ class EditorWebView(AnkiWebView):
self._flagAnkiText()
def onCut(self) -> None:
self.triggerPageAction(QWebEnginePage.Cut)
self.triggerPageAction(QWebEnginePage.WebAction.Cut)
def onCopy(self) -> None:
self.triggerPageAction(QWebEnginePage.Copy)
self.triggerPageAction(QWebEnginePage.WebAction.Copy)
def _wantsExtendedPaste(self) -> bool:
strip_html = self.editor.mw.col.get_config_bool(
@ -1140,10 +1143,10 @@ class EditorWebView(AnkiWebView):
self.editor.doPaste(html, internal, extended)
def onPaste(self) -> None:
self._onPaste(QClipboard.Clipboard)
self._onPaste(QClipboard.Mode.Clipboard)
def onMiddleClickPaste(self) -> None:
self._onPaste(QClipboard.Selection)
self._onPaste(QClipboard.Mode.Selection)
def dragEnterEvent(self, evt: QDragEnterEvent) -> None:
evt.accept()

View file

@ -63,7 +63,7 @@ class EmptyCardsDialog(QDialog):
qconnect(self.finished, on_finished)
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)
qconnect(self._delete_button.clicked, self._on_delete)

View file

@ -31,7 +31,7 @@ class ExportDialog(QDialog):
did: DeckId | None = None,
cids: list[CardId] | None = None,
):
QDialog.__init__(self, mw, Qt.Window)
QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw
self.col = mw.col.weakref()
self.frm = aqt.forms.exporting.Ui_ExportDialog()
@ -64,7 +64,7 @@ class ExportDialog(QDialog):
self.frm.deck.addItems(self.decks)
# save button
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
if did:
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"]))
)
disable_help_button(self)
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
self.form.buttonBox.button(QDialogButtonBox.Cancel).setAutoDefault(False)
self.form.buttonBox.button(QDialogButtonBox.Save).setAutoDefault(False)
self.form.buttonBox.button(QDialogButtonBox.StandardButton.Help).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.fillFields()
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.setCurrentRow(open_at)
self.exec()
@ -77,15 +83,21 @@ class FieldDialog(QDialog):
def onDrop(self, ev: QDropEvent) -> None:
fieldList = self.form.fieldList
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
if dropPos == idx:
return
if indicatorPos == QAbstractItemView.OnViewport: # to bottom.
if (
indicatorPos == QAbstractItemView.DropIndicatorPosition.OnViewport
): # to bottom.
movePos = fieldList.count() - 1
elif indicatorPos == QAbstractItemView.AboveItem:
elif indicatorPos == QAbstractItemView.DropIndicatorPosition.AboveItem:
movePos = dropPos
elif indicatorPos == QAbstractItemView.BelowItem:
elif indicatorPos == QAbstractItemView.DropIndicatorPosition.BelowItem:
movePos = dropPos + 1
# the item in idx is removed thus subtract 1.
if idx < dropPos:

View file

@ -90,7 +90,7 @@ class FilteredDeckConfigDialog(QDialog):
QPushButton[label="hint"] {{ color: {grey} }}"""
)
disable_help_button(self)
self.setWindowModality(Qt.WindowModal)
self.setWindowModality(Qt.WindowModality.WindowModal)
qconnect(
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.FILTERED_DECK)
)
@ -117,7 +117,9 @@ class FilteredDeckConfigDialog(QDialog):
build_label = tr.actions_rebuild()
else:
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)
self._onReschedToggled(0)

View file

@ -1,17 +1,48 @@
load("@rules_python//python:defs.bzl", "py_binary")
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(
name = "forms_qt5",
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 = [
"//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(
name = name,
srcs = [ui_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,
py_file = py_file,
),
tools = [
"build_ui",
builder,
],
message = "Building UI",
)
def compile_all(group, srcs, visibility):
def compile_all(name, builder, srcs, suffix):
py_files = []
for ui_file in srcs:
name = ui_file.replace(".ui", "")
py_file = name + ".py"
fname = ui_file.replace(".ui", "") + suffix
py_file = fname + ".py"
py_files.append(py_file)
compile(name, ui_file, py_file)
compile(fname, ui_file, py_file, builder)
native.filegroup(
name = group,
srcs = py_files + ["__init__.py"],
visibility = visibility,
name = name,
srcs = py_files,
)

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