switch to new-style PyQt scoped enums and Qt6

The enum changes should work on PyQt 5.x, and are required in PyQt 6.x.
They are not supported by the PyQt5 typings however, so we need to run
our tests with PyQt6.
This commit is contained in:
Damien Elmes 2021-10-05 13:53:01 +10:00
parent b0272f0336
commit a7812dedc0
56 changed files with 526 additions and 385 deletions

View file

@ -1,6 +1,6 @@
[MASTER]
persistent = no
extension-pkg-whitelist=PyQt5,PyQt6
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"),
],
)

View file

@ -50,7 +50,7 @@ aqt_deps = [
requirement("waitress"),
requirement("send2trash"),
requirement("jsonschema"),
"@pyqt5//:pkg",
"@pyqt6//:pkg",
] + select({
"@bazel_tools//src/conditions:host_windows": [
requirement("psutil"),

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,17 +365,17 @@ 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"
else:
category = "unknown"
@ -405,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"
@ -499,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
@ -535,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
@ -559,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

@ -40,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

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>377</width>
<height>224</height>
<width>479</width>
<height>247</height>
</rect>
</property>
<property name="windowTitle">
@ -31,7 +31,7 @@
<enum>QComboBox::NoInsert</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
@ -59,7 +59,7 @@
<item row="2" column="1">
<widget class="QComboBox" name="field">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
@ -95,7 +95,7 @@
<enum>QComboBox::NoInsert</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>

View file

@ -35,7 +35,7 @@ from aqt.utils import (
class ChangeMap(QDialog):
def __init__(self, mw: AnkiQt, model: dict, current: str) -> None:
QDialog.__init__(self, mw, Qt.Window)
QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw
self.model = model
self.frm = aqt.forms.changemap.Ui_ChangeMap()
@ -85,13 +85,14 @@ class ImportDialog(QDialog):
_DEFAULT_FILE_DELIMITER = "\t"
def __init__(self, mw: AnkiQt, importer: Any) -> None:
QDialog.__init__(self, mw, Qt.Window)
QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw
self.importer = importer
self.frm = aqt.forms.importing.Ui_ImportDialog()
self.frm.setupUi(self)
qconnect(
self.frm.buttonBox.button(QDialogButtonBox.Help).clicked, self.helpRequested
self.frm.buttonBox.button(QDialogButtonBox.StandardButton.Help).clicked,
self.helpRequested,
)
disable_help_button(self)
self.setupMappingFrame()
@ -108,7 +109,7 @@ class ImportDialog(QDialog):
self.frm.tagModified.setCol(self.mw.col)
# import button
b = QPushButton(tr.actions_import())
self.frm.buttonBox.addButton(b, QDialogButtonBox.AcceptRole)
self.frm.buttonBox.addButton(b, QDialogButtonBox.ButtonRole.AcceptRole)
self.exec()
def setupOptions(self) -> None:

View file

@ -107,10 +107,7 @@ class AnkiQt(QMainWindow):
self.pm = profileManager
# init rest of app
self.safeMode = (
bool(
cast(Qt.KeyboardModifier, self.app.queryKeyboardModifiers())
& Qt.ShiftModifier
)
bool(self.app.queryKeyboardModifiers() & Qt.KeyboardModifier.ShiftModifier)
or self.opts.safemode
)
try:
@ -817,15 +814,15 @@ title="{}" {}>{}</button>""".format(
self.form.setupUi(self)
# toolbar
tweb = self.toolbarWeb = aqt.webview.AnkiWebView(title="top toolbar")
tweb.setFocusPolicy(Qt.WheelFocus)
tweb.setFocusPolicy(Qt.FocusPolicy.WheelFocus)
self.toolbar = aqt.toolbar.Toolbar(self, tweb)
# main area
self.web = aqt.webview.AnkiWebView(title="main webview")
self.web.setFocusPolicy(Qt.WheelFocus)
self.web.setFocusPolicy(Qt.FocusPolicy.WheelFocus)
self.web.setMinimumWidth(400)
# bottom area
sweb = self.bottomWeb = aqt.webview.AnkiWebView(title="bottom toolbar")
sweb.setFocusPolicy(Qt.WheelFocus)
sweb.setFocusPolicy(Qt.FocusPolicy.WheelFocus)
# add in a layout
self.mainLayout = QVBoxLayout()
self.mainLayout.setContentsMargins(0, 0, 0, 0)
@ -991,7 +988,7 @@ title="{}" {}>{}</button>""".format(
def raiseMain(self) -> bool:
if not self.app.activeWindow():
# make sure window is shown
self.setWindowState(self.windowState() & ~Qt.WindowMinimized) # type: ignore
self.setWindowState(self.windowState() & ~Qt.WindowState.WindowMinimized) # type: ignore
return True
def setupStyle(self) -> None:
@ -1393,7 +1390,7 @@ title="{}" {}>{}</button>""".format(
frm.setupUi(d)
restoreGeom(d, "DebugConsoleWindow")
restoreSplitter(frm.splitter, "DebugConsoleWindow")
font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
font = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont)
font.setPointSize(frm.text.font().pointSize() + 1)
frm.text.setFont(font)
frm.log.setFont(font)
@ -1485,7 +1482,7 @@ title="{}" {}>{}</button>""".format(
def onDebugPrint(self, frm: aqt.forms.debug.Ui_Dialog) -> None:
cursor = frm.text.textCursor()
position = cursor.position()
cursor.select(QTextCursor.LineUnderCursor)
cursor.select(QTextCursor.SelectionType.LineUnderCursor)
line = cursor.selectedText()
pfx, sfx = "pp(", ")"
if not line.startswith(pfx):
@ -1566,7 +1563,7 @@ title="{}" {}>{}</button>""".format(
cast(QAction, action).setStatusTip("")
def onMacMinimize(self) -> None:
self.setWindowState(self.windowState() | Qt.WindowMinimized) # type: ignore
self.setWindowState(self.windowState() | Qt.WindowState.WindowMinimized) # type: ignore
# Single instance support
##########################################################################
@ -1606,7 +1603,7 @@ title="{}" {}>{}</button>""".format(
if isWin:
# on windows we can raise the window by minimizing and restoring
self.showMinimized()
self.setWindowState(Qt.WindowActive)
self.setWindowState(Qt.WindowState.WindowActive)
self.showNormal()
else:
# on osx we can raise the window. on unity the icon in the tray will just flash.

View file

@ -105,33 +105,33 @@ class MediaChecker:
text = QPlainTextEdit()
text.setReadOnly(True)
text.setPlainText(report)
text.setWordWrapMode(QTextOption.NoWrap)
text.setWordWrapMode(QTextOption.WrapMode.NoWrap)
layout.addWidget(text)
box = QDialogButtonBox(QDialogButtonBox.Close)
box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
layout.addWidget(box)
if output.unused:
b = QPushButton(tr.media_check_delete_unused())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
box.addButton(b, QDialogButtonBox.ButtonRole.RejectRole)
qconnect(b.clicked, lambda c: self._on_trash_files(output.unused))
if output.missing:
if any(map(lambda x: x.startswith("latex-"), output.missing)):
b = QPushButton(tr.media_check_render_latex())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
box.addButton(b, QDialogButtonBox.ButtonRole.RejectRole)
qconnect(b.clicked, self._on_render_latex)
if output.have_trash:
b = QPushButton(tr.media_check_empty_trash())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
box.addButton(b, QDialogButtonBox.ButtonRole.RejectRole)
qconnect(b.clicked, lambda c: self._on_empty_trash())
b = QPushButton(tr.media_check_restore_trash())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
box.addButton(b, QDialogButtonBox.ButtonRole.RejectRole)
qconnect(b.clicked, lambda c: self._on_restore_trash())
qconnect(box.rejected, diag.reject)

View file

@ -162,7 +162,9 @@ class MediaSyncDialog(QDialog):
self.abort_button = QPushButton(tr.sync_abort_button())
qconnect(self.abort_button.clicked, self._on_abort)
self.abort_button.setAutoDefault(False)
self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole)
self.form.buttonBox.addButton(
self.abort_button, QDialogButtonBox.ButtonRole.ActionRole
)
self.abort_button.setHidden(not self._syncer.is_syncing())
gui_hooks.media_sync_did_progress.append(self._on_log_entry)
@ -171,7 +173,7 @@ class MediaSyncDialog(QDialog):
self.form.plainTextEdit.setPlainText(
"\n".join(self._entry_to_text(x) for x in syncer.entries())
)
self.form.plainTextEdit.moveCursor(QTextCursor.End)
self.form.plainTextEdit.moveCursor(QTextCursor.MoveOperation.End)
self.show()
def reject(self) -> None:

View file

@ -48,7 +48,7 @@ class Models(QDialog):
parent = parent or mw
self.fromMain = fromMain
self.selected_notetype_id = selected_notetype_id
QDialog.__init__(self, parent, Qt.Window)
QDialog.__init__(self, parent, Qt.WindowType.Window)
self.col = mw.col.weakref()
assert self.col
self.mm = self.col.models
@ -97,7 +97,7 @@ class Models(QDialog):
default_buttons.append((tr.notetypes_options(), self.onAdvanced))
for label, func in gui_hooks.models_did_init_buttons(default_buttons, self):
button = box.addButton(label, QDialogButtonBox.ActionRole)
button = box.addButton(label, QDialogButtonBox.ButtonRole.ActionRole)
qconnect(button.clicked, func)
qconnect(f.modelsList.itemDoubleClicked, self.onRename)
@ -235,7 +235,7 @@ class AddModel(QDialog):
self.parent_ = parent or mw
self.mw = mw
self.col = mw.col
QDialog.__init__(self, self.parent_, Qt.Window)
QDialog.__init__(self, self.parent_, Qt.WindowType.Window)
self.model = None
self.dialog = aqt.forms.addmodel.Ui_Dialog()
self.dialog.setupUi(self)

View file

@ -93,7 +93,7 @@ def reposition_new_cards_dialog(
d = QDialog(parent)
disable_help_button(d)
d.setWindowModality(Qt.WindowModal)
d.setWindowModality(Qt.WindowModality.WindowModal)
frm = aqt.forms.reposition.Ui_Dialog()
frm.setupUi(d)

View file

@ -16,14 +16,18 @@ from aqt.utils import HelpPage, disable_help_button, openHelp, showInfo, showWar
class Preferences(QDialog):
def __init__(self, mw: AnkiQt) -> None:
QDialog.__init__(self, mw, Qt.Window)
QDialog.__init__(self, mw, Qt.WindowType.Window)
self.mw = mw
self.prof = self.mw.pm.profile
self.form = aqt.forms.preferences.Ui_Preferences()
self.form.setupUi(self)
disable_help_button(self)
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
self.form.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
self.form.buttonBox.button(QDialogButtonBox.StandardButton.Help).setAutoDefault(
False
)
self.form.buttonBox.button(
QDialogButtonBox.StandardButton.Close
).setAutoDefault(False)
qconnect(
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.PREFERENCES)
)

View file

@ -461,9 +461,9 @@ create table if not exists profiles
code = obj[1]
name = obj[0]
r = QMessageBox.question(
None, "Anki", tr.profiles_confirm_lang_choice(lang=name), QMessageBox.Yes | QMessageBox.No, QMessageBox.No # type: ignore
None, "Anki", tr.profiles_confirm_lang_choice(lang=name), QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No # type: ignore
)
if r != QMessageBox.Yes:
if r != QMessageBox.StandardButton.Yes:
return self.setDefaultLang(f.lang.currentRow())
self.setLang(code)

View file

@ -92,7 +92,7 @@ class ProgressManager:
self._win.form.progressBar.setTextVisible(False)
self._win.form.label.setText(label)
self._win.setWindowTitle("Anki")
self._win.setWindowModality(Qt.ApplicationModal)
self._win.setWindowModality(Qt.WindowModality.ApplicationModal)
self._win.setMinimumWidth(300)
self._busy_cursor_timer = QTimer(self.mw)
self._busy_cursor_timer.setSingleShot(True)
@ -177,7 +177,7 @@ class ProgressManager:
elap = time.time() - self._shown
if elap >= 0.5:
break
self.app.processEvents(QEventLoop.ExcludeUserInputEvents) # type: ignore #possibly related to https://github.com/python/mypy/issues/6910
self.app.processEvents(QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents) # type: ignore #possibly related to https://github.com/python/mypy/issues/6910
# if the parent window has been deleted, the progress dialog may have
# already been dropped; delete it if it hasn't been
if not sip.isdeleted(self._win):
@ -186,7 +186,7 @@ class ProgressManager:
self._shown = 0
def _set_busy_cursor(self) -> None:
self.mw.app.setOverrideCursor(QCursor(Qt.WaitCursor))
self.mw.app.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
def _restore_cursor(self) -> None:
self.app.restoreOverrideCursor()
@ -235,6 +235,6 @@ class ProgressDialog(QDialog):
evt.ignore()
def keyPressEvent(self, evt: QKeyEvent) -> None:
if evt.key() == Qt.Key_Escape:
if evt.key() == Qt.Key.Key_Escape:
evt.ignore()
self.wantCancel = True

View file

@ -9,14 +9,34 @@ import sys
import traceback
from typing import Callable, Union
from PyQt5.Qt import * # type: ignore
from PyQt5.QtCore import *
from PyQt5.QtCore import pyqtRemoveInputHook # pylint: disable=no-name-in-module
from PyQt5.QtGui import * # type: ignore
from PyQt5.QtNetwork import QLocalServer, QLocalSocket, QNetworkProxy
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import *
try:
from PyQt6 import sip
from PyQt6.QtCore import *
# conflicting Qt and qFuzzyCompare definitions require an ignore
from PyQt6.QtGui import * # type: ignore[misc]
from PyQt6.QtNetwork import QLocalServer, QLocalSocket, QNetworkProxy
from PyQt6.QtWebChannel import QWebChannel
from PyQt6.QtWebEngineCore import *
from PyQt6.QtWebEngineWidgets import *
from PyQt6.QtWidgets import *
except:
from PyQt5.QtCore import * # type: ignore
from PyQt5.QtGui import * # type: ignore
from PyQt5.QtNetwork import ( # type: ignore
QLocalServer,
QLocalSocket,
QNetworkProxy,
)
from PyQt5.QtWebChannel import QWebChannel # type: ignore
from PyQt5.QtWebEngineCore import * # type: ignore
from PyQt5.QtWebEngineWidgets import * # type: ignore
from PyQt5.QtWidgets import * # type: ignore
try:
from PyQt5 import sip # type: ignore
except ImportError:
import sip # type: ignore
from anki.utils import isMac, isWin
@ -24,12 +44,6 @@ from anki.utils import isMac, isWin
os.environ["LIBOVERLAY_SCROLLBAR"] = "0"
try:
from PyQt5 import sip
except ImportError:
import sip # type: ignore
def debug() -> None:
from pdb import set_trace

View file

@ -1,6 +1,8 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
# pylint: skip-file
"""
PyQt5-only code
"""

View file

@ -433,11 +433,11 @@ class Reviewer:
return [
("e", self.mw.onEditCurrent),
(" ", self.onEnterKey),
(Qt.Key_Return, self.onEnterKey),
(Qt.Key_Enter, self.onEnterKey),
(Qt.Key.Key_Return, self.onEnterKey),
(Qt.Key.Key_Enter, self.onEnterKey),
("m", self.showContextMenu),
("r", self.replayAudio),
(Qt.Key_F5, self.replayAudio),
(Qt.Key.Key_F5, self.replayAudio),
*(
(f"Ctrl+{flag.index}", self.set_flag_func(flag.index))
for flag in self.mw.flags.all()
@ -875,7 +875,7 @@ time = %(time)d;
part2 = tr.studying_minute(count=mins)
fin = tr.studying_finish()
diag = askUserDialog(f"{part1} {part2}", [tr.studying_continue(), fin])
diag.setIcon(QMessageBox.Information)
diag.setIcon(QMessageBox.Icon.Information)
if diag.run() == fin:
self.mw.moveToState("deckBrowser")
return True

View file

@ -666,15 +666,18 @@ class RecordDialog(QDialog):
hbox.addWidget(self.label)
v = QVBoxLayout()
v.addLayout(hbox)
buts = QDialogButtonBox.Save | QDialogButtonBox.Cancel
buts = (
QDialogButtonBox.StandardButton.Save
| QDialogButtonBox.StandardButton.Cancel
)
b = QDialogButtonBox(buts) # type: ignore
v.addWidget(b)
self.setLayout(v)
save_button = b.button(QDialogButtonBox.Save)
save_button = b.button(QDialogButtonBox.StandardButton.Save)
save_button.setDefault(True)
save_button.setAutoDefault(True)
qconnect(save_button.clicked, self.accept)
cancel_button = b.button(QDialogButtonBox.Cancel)
cancel_button = b.button(QDialogButtonBox.StandardButton.Cancel)
cancel_button.setDefault(False)
cancel_button.setAutoDefault(False)
qconnect(cancel_button.clicked, self.reject)

View file

@ -25,7 +25,7 @@ class NewDeckStats(QDialog):
"""New deck stats."""
def __init__(self, mw: aqt.main.AnkiQt) -> None:
QDialog.__init__(self, mw, Qt.Window)
QDialog.__init__(self, mw, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self)
self.mw = mw
self.name = "deckStats"
@ -40,7 +40,9 @@ class NewDeckStats(QDialog):
f.groupBox.setVisible(False)
f.groupBox_2.setVisible(False)
restoreGeom(self, self.name)
b = f.buttonBox.addButton(tr.statistics_save_pdf(), QDialogButtonBox.ActionRole)
b = f.buttonBox.addButton(
tr.statistics_save_pdf(), QDialogButtonBox.ButtonRole.ActionRole
)
qconnect(b.clicked, self.saveImage)
b.setAutoDefault(False)
maybeHideClose(self.form.buttonBox)
@ -104,7 +106,7 @@ class DeckStats(QDialog):
"""Legacy deck stats, used by some add-ons."""
def __init__(self, mw: aqt.main.AnkiQt) -> None:
QDialog.__init__(self, mw, Qt.Window)
QDialog.__init__(self, mw, Qt.WindowType.Window)
mw.garbage_collect_on_dialog_finish(self)
self.mw = mw
self.name = "deckStats"
@ -123,7 +125,9 @@ class DeckStats(QDialog):
self.setStyleSheet("QGroupBox { border: 0; }")
f.setupUi(self)
restoreGeom(self, self.name)
b = f.buttonBox.addButton(tr.statistics_save_pdf(), QDialogButtonBox.ActionRole)
b = f.buttonBox.addButton(
tr.statistics_save_pdf(), QDialogButtonBox.ButtonRole.ActionRole
)
qconnect(b.clicked, self.saveImage)
b.setAutoDefault(False)
qconnect(f.groups.clicked, lambda: self.changeScope("deck"))

View file

@ -49,18 +49,18 @@ class StudyDeck(QDialog):
disable_help_button(self)
if not cancel:
self.form.buttonBox.removeButton(
self.form.buttonBox.button(QDialogButtonBox.Cancel)
self.form.buttonBox.button(QDialogButtonBox.StandardButton.Cancel)
)
if buttons is not None:
for button_or_label in buttons:
self.form.buttonBox.addButton(
button_or_label, QDialogButtonBox.ActionRole
button_or_label, QDialogButtonBox.ButtonRole.ActionRole
)
else:
b = QPushButton(tr.actions_add())
b.setShortcut(QKeySequence("Ctrl+N"))
b.setToolTip(shortcut(tr.decks_add_new_deck_ctrlandn()))
self.form.buttonBox.addButton(b, QDialogButtonBox.ActionRole)
self.form.buttonBox.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
qconnect(b.clicked, self.onAddDeck)
if title:
self.setWindowTitle(title)
@ -78,9 +78,9 @@ class StudyDeck(QDialog):
self.origNames = names()
self.name: Optional[str] = None
self.ok = self.form.buttonBox.addButton(
accept or tr.decks_study(), QDialogButtonBox.AcceptRole
accept or tr.decks_study(), QDialogButtonBox.ButtonRole.AcceptRole
)
self.setWindowModality(Qt.WindowModal)
self.setWindowModality(Qt.WindowModality.WindowModal)
qconnect(self.form.buttonBox.helpRequested, lambda: openHelp(help))
qconnect(self.form.filter.textEdited, self.redraw)
qconnect(self.form.list.itemDoubleClicked, self.accept)
@ -90,20 +90,20 @@ class StudyDeck(QDialog):
self.exec()
def eventFilter(self, obj: QObject, evt: QEvent) -> bool:
if isinstance(evt, QKeyEvent) and evt.type() == QEvent.KeyPress:
if isinstance(evt, QKeyEvent) and evt.type() == QEvent.Type.KeyPress:
new_row = current_row = self.form.list.currentRow()
rows_count = self.form.list.count()
key = evt.key()
if key == Qt.Key_Up:
if key == Qt.Key.Key_Up:
new_row = current_row - 1
elif key == Qt.Key_Down:
elif key == Qt.Key.Key_Down:
new_row = current_row + 1
elif (
int(evt.modifiers()) & Qt.ControlModifier
and Qt.Key_1 <= key <= Qt.Key_9
evt.modifiers() & Qt.KeyboardModifier.ControlModifier
and Qt.Key.Key_1 <= key <= Qt.Key.Key_9
):
row_index = key - Qt.Key_1
row_index = key - Qt.Key.Key_1
if row_index < rows_count:
new_row = row_index
@ -126,7 +126,7 @@ class StudyDeck(QDialog):
else:
idx = 0
l.setCurrentRow(idx)
l.scrollToItem(l.item(idx), QAbstractItemView.PositionAtCenter)
l.scrollToItem(l.item(idx), QAbstractItemView.ScrollHint.PositionAtCenter)
def _matches(self, name: str, filt: str) -> bool:
name = name.lower()

View file

@ -28,7 +28,7 @@ class Switch(QAbstractButton):
super().__init__(parent=parent)
self.setCheckable(True)
super().setChecked(False)
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
self._left_label = left_label
self._right_label = right_label
self._left_color = left_color
@ -76,8 +76,8 @@ class Switch(QAbstractButton):
def paintEvent(self, _event: QPaintEvent) -> None:
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing, True)
painter.setPen(Qt.NoPen)
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
painter.setPen(Qt.PenStyle.NoPen)
self._paint_path(painter)
self._paint_knob(painter)
self._paint_label(painter)
@ -113,15 +113,17 @@ class Switch(QAbstractButton):
font = painter.font()
font.setPixelSize(int(1.2 * self._knob_radius))
painter.setFont(font)
painter.drawText(self._current_knob_rectangle(), Qt.AlignCenter, self.label)
painter.drawText(
self._current_knob_rectangle(), Qt.AlignmentFlag.AlignCenter, self.label
)
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
super().mouseReleaseEvent(event)
if event.button() == Qt.LeftButton:
if event.button() == Qt.MouseButton.LeftButton:
self._animate_toggle()
def enterEvent(self, event: QEvent) -> None:
self.setCursor(Qt.PointingHandCursor)
def enterEvent(self, event: QEnterEvent) -> None:
self.setCursor(Qt.CursorShape.PointingHandCursor)
super().enterEvent(event)
def toggle(self) -> None:

View file

@ -292,7 +292,7 @@ def get_id_and_pass_from_user(
diag = QDialog(mw)
diag.setWindowTitle("Anki")
disable_help_button(diag)
diag.setWindowModality(Qt.WindowModal)
diag.setWindowModality(Qt.WindowModality.WindowModal)
vbox = QVBoxLayout()
info_label = QLabel(
without_unicode_isolation(
@ -313,11 +313,11 @@ def get_id_and_pass_from_user(
g.addWidget(l2, 1, 0)
passwd = QLineEdit()
passwd.setText(password)
passwd.setEchoMode(QLineEdit.Password)
passwd.setEchoMode(QLineEdit.EchoMode.Password)
g.addWidget(passwd, 1, 1)
vbox.addLayout(g)
bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) # type: ignore
bb.button(QDialogButtonBox.Ok).setAutoDefault(True)
bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) # type: ignore
bb.button(QDialogButtonBox.StandardButton.Ok).setAutoDefault(True)
qconnect(bb.accepted, diag.accept)
qconnect(bb.rejected, diag.reject)
vbox.addWidget(bb)

View file

@ -26,9 +26,9 @@ class TagEdit(QLineEdit):
self._completer = TagCompleter(self.model, parent, self)
else:
self._completer = QCompleter(self.model, parent)
self._completer.setCompletionMode(QCompleter.PopupCompletion)
self._completer.setCaseSensitivity(Qt.CaseInsensitive)
self._completer.setFilterMode(Qt.MatchContains)
self._completer.setCompletionMode(QCompleter.CompletionMode.PopupCompletion)
self._completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
self._completer.setFilterMode(Qt.MatchFlag.MatchContains)
self.setCompleter(self._completer)
def setCol(self, col: Collection) -> None:
@ -45,12 +45,15 @@ class TagEdit(QLineEdit):
QLineEdit.focusInEvent(self, evt)
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):
# show completer on arrow key up/down
if not self._completer.popup().isVisible():
self.showCompleter()
return
if evt.key() == Qt.Key_Tab and int(evt.modifiers()) & Qt.ControlModifier:
if (
evt.key() == Qt.Key.Key_Tab
and evt.modifiers() & Qt.KeyboardModifier.ControlModifier
):
# select next completion
if not self._completer.popup().isVisible():
self.showCompleter()
@ -61,7 +64,7 @@ class TagEdit(QLineEdit):
self._completer.setCurrentRow(0)
return
if (
evt.key() in (Qt.Key_Enter, Qt.Key_Return)
evt.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return)
and self._completer.popup().isVisible()
):
# apply first completion if no suggestion selected
@ -78,13 +81,13 @@ class TagEdit(QLineEdit):
# if it's a modifier, don't show
return
if evt.key() not in (
Qt.Key_Enter,
Qt.Key_Return,
Qt.Key_Escape,
Qt.Key_Space,
Qt.Key_Tab,
Qt.Key_Backspace,
Qt.Key_Delete,
Qt.Key.Key_Enter,
Qt.Key.Key_Return,
Qt.Key.Key_Escape,
Qt.Key.Key_Space,
Qt.Key.Key_Tab,
Qt.Key.Key_Backspace,
Qt.Key.Key_Delete,
):
self.showCompleter()
gui_hooks.tag_editor_did_process_key(self, evt)

View file

@ -13,7 +13,7 @@ from aqt.utils import disable_help_button, restoreGeom, saveGeom, showWarning, t
class TagLimit(QDialog):
def __init__(self, mw: AnkiQt, parent: CustomStudy) -> None:
QDialog.__init__(self, parent, Qt.Window)
QDialog.__init__(self, parent, Qt.WindowType.Window)
self.tags: str = ""
self.tags_list: list[str] = []
self.mw = mw
@ -23,11 +23,15 @@ class TagLimit(QDialog):
self.dialog.setupUi(self)
disable_help_button(self)
s = QShortcut(
QKeySequence("ctrl+d"), self.dialog.activeList, context=Qt.WidgetShortcut
QKeySequence("ctrl+d"),
self.dialog.activeList,
context=Qt.ShortcutContext.WidgetShortcut,
)
qconnect(s.activated, self.dialog.activeList.clearSelection)
s = QShortcut(
QKeySequence("ctrl+d"), self.dialog.inactiveList, context=Qt.WidgetShortcut
QKeySequence("ctrl+d"),
self.dialog.inactiveList,
context=Qt.ShortcutContext.WidgetShortcut,
)
qconnect(s.activated, self.dialog.inactiveList.clearSelection)
self.rebuildTagList()
@ -54,19 +58,19 @@ class TagLimit(QDialog):
item = QListWidgetItem(t.replace("_", " "))
self.dialog.activeList.addItem(item)
if t in yesHash:
mode = QItemSelectionModel.Select
mode = QItemSelectionModel.SelectionFlag.Select
self.dialog.activeCheck.setChecked(True)
else:
mode = QItemSelectionModel.Deselect
mode = QItemSelectionModel.SelectionFlag.Deselect
idx = self.dialog.activeList.indexFromItem(item)
self.dialog.activeList.selectionModel().select(idx, mode)
# inactive
item = QListWidgetItem(t.replace("_", " "))
self.dialog.inactiveList.addItem(item)
if t in noHash:
mode = QItemSelectionModel.Select
mode = QItemSelectionModel.SelectionFlag.Select
else:
mode = QItemSelectionModel.Deselect
mode = QItemSelectionModel.SelectionFlag.Deselect
idx = self.dialog.inactiveList.indexFromItem(item)
self.dialog.inactiveList.selectionModel().select(idx, mode)

View file

@ -92,7 +92,9 @@ class ThemeManager:
icon = QIcon(path.path)
pixmap = icon.pixmap(16)
painter = QPainter(pixmap)
painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
painter.setCompositionMode(
QPainter.CompositionMode.CompositionMode_SourceIn
)
painter.fillRect(pixmap.rect(), QColor(path.current_color(self.night_mode)))
painter.end()
icon = QIcon(pixmap)
@ -207,34 +209,44 @@ QTabWidget {{ background-color: {}; }}
palette = QPalette()
text_fg = self.qcolor(colors.TEXT_FG)
palette.setColor(QPalette.WindowText, text_fg)
palette.setColor(QPalette.ToolTipText, text_fg)
palette.setColor(QPalette.Text, text_fg)
palette.setColor(QPalette.ButtonText, text_fg)
palette.setColor(QPalette.ColorRole.WindowText, text_fg)
palette.setColor(QPalette.ColorRole.ToolTipText, text_fg)
palette.setColor(QPalette.ColorRole.Text, text_fg)
palette.setColor(QPalette.ColorRole.ButtonText, text_fg)
hlbg = self.qcolor(colors.HIGHLIGHT_BG)
hlbg.setAlpha(64)
palette.setColor(QPalette.HighlightedText, self.qcolor(colors.HIGHLIGHT_FG))
palette.setColor(QPalette.Highlight, hlbg)
palette.setColor(
QPalette.ColorRole.HighlightedText, self.qcolor(colors.HIGHLIGHT_FG)
)
palette.setColor(QPalette.ColorRole.Highlight, hlbg)
window_bg = self.qcolor(colors.WINDOW_BG)
palette.setColor(QPalette.Window, window_bg)
palette.setColor(QPalette.AlternateBase, window_bg)
palette.setColor(QPalette.ColorRole.Window, window_bg)
palette.setColor(QPalette.ColorRole.AlternateBase, window_bg)
palette.setColor(QPalette.Button, QColor("#454545"))
palette.setColor(QPalette.ColorRole.Button, QColor("#454545"))
frame_bg = self.qcolor(colors.FRAME_BG)
palette.setColor(QPalette.Base, frame_bg)
palette.setColor(QPalette.ToolTipBase, frame_bg)
palette.setColor(QPalette.ColorRole.Base, frame_bg)
palette.setColor(QPalette.ColorRole.ToolTipBase, frame_bg)
disabled_color = self.qcolor(colors.DISABLED)
palette.setColor(QPalette.Disabled, QPalette.Text, disabled_color)
palette.setColor(QPalette.Disabled, QPalette.ButtonText, disabled_color)
palette.setColor(QPalette.Disabled, QPalette.HighlightedText, disabled_color)
palette.setColor(
QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text, disabled_color
)
palette.setColor(
QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, disabled_color
)
palette.setColor(
QPalette.ColorGroup.Disabled,
QPalette.ColorRole.HighlightedText,
disabled_color,
)
palette.setColor(QPalette.Link, self.qcolor(colors.LINK))
palette.setColor(QPalette.ColorRole.Link, self.qcolor(colors.LINK))
palette.setColor(QPalette.BrightText, Qt.red)
palette.setColor(QPalette.ColorRole.BrightText, Qt.GlobalColor.red)
app.setPalette(palette)

View file

@ -59,17 +59,17 @@ class LatestVersionFinder(QThread):
def askAndUpdate(mw: aqt.AnkiQt, ver: str) -> None:
baseStr = tr.qt_misc_anki_updatedanki_has_been_released(val=ver)
msg = QMessageBox(mw)
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore
msg.setIcon(QMessageBox.Information)
msg.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) # type: ignore
msg.setIcon(QMessageBox.Icon.Information)
msg.setText(baseStr + tr.qt_misc_would_you_like_to_download_it())
button = QPushButton(tr.qt_misc_ignore_this_update())
msg.addButton(button, QMessageBox.RejectRole)
msg.setDefaultButton(QMessageBox.Yes)
msg.addButton(button, QMessageBox.ButtonRole.RejectRole)
msg.setDefaultButton(QMessageBox.StandardButton.Yes)
ret = msg.exec()
if msg.clickedButton() == button:
# ignore this update
mw.pm.meta["suppressUpdate"] = ver
elif ret == QMessageBox.Yes:
elif ret == QMessageBox.StandardButton.Yes:
openLink(aqt.appWebsite)

View file

@ -7,7 +7,7 @@ import re
import subprocess
import sys
from functools import wraps
from typing import TYPE_CHECKING, Any, Literal, Sequence, cast
from typing import TYPE_CHECKING, Any, Literal, Sequence
import aqt
from anki.collection import Collection, HelpPage
@ -96,16 +96,16 @@ def showInfo(
else:
parent_widget = parent
if type == "warning":
icon = QMessageBox.Warning
icon = QMessageBox.Icon.Warning
elif type == "critical":
icon = QMessageBox.Critical
icon = QMessageBox.Icon.Critical
else:
icon = QMessageBox.Information
icon = QMessageBox.Icon.Information
mb = QMessageBox(parent_widget) #
if textFormat == "plain":
mb.setTextFormat(Qt.PlainText)
mb.setTextFormat(Qt.TextFormat.PlainText)
elif textFormat == "rich":
mb.setTextFormat(Qt.RichText)
mb.setTextFormat(Qt.TextFormat.RichText)
elif textFormat is not None:
raise Exception("unexpected textFormat type")
mb.setText(text)
@ -119,10 +119,10 @@ def showInfo(
default = b
mb.setDefaultButton(default)
else:
b = mb.addButton(QMessageBox.Ok)
b = mb.addButton(QMessageBox.StandardButton.Ok)
b.setDefault(True)
if help:
b = mb.addButton(QMessageBox.Help)
b = mb.addButton(QMessageBox.StandardButton.Help)
qconnect(b.clicked, lambda: openHelp(help))
b.setAutoDefault(False)
return mb.exec()
@ -152,7 +152,7 @@ def showText(
# used by the importer
text = QPlainTextEdit()
text.setReadOnly(True)
text.setWordWrapMode(QTextOption.NoWrap)
text.setWordWrapMode(QTextOption.WrapMode.NoWrap)
text.setPlainText(txt)
else:
text = QTextBrowser()
@ -162,7 +162,7 @@ def showText(
else:
text.setHtml(txt)
layout.addWidget(text)
box = QDialogButtonBox(QDialogButtonBox.Close)
box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
layout.addWidget(box)
if copyBtn:
@ -171,7 +171,7 @@ def showText(
btn = QPushButton(tr.qt_misc_copy_to_clipboard())
qconnect(btn.clicked, onCopy)
box.addButton(btn, QDialogButtonBox.ActionRole)
box.addButton(btn, QDialogButtonBox.ButtonRole.ActionRole)
def onReject() -> None:
if geomKey:
@ -209,20 +209,20 @@ def askUser(
parent = aqt.mw.app.activeWindow()
if not msgfunc:
msgfunc = QMessageBox.question
sb = QMessageBox.Yes | QMessageBox.No
sb = QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
if help:
sb |= QMessageBox.Help
sb |= QMessageBox.StandardButton.Help
while 1:
if defaultno:
default = QMessageBox.No
default = QMessageBox.StandardButton.No
else:
default = QMessageBox.Yes
r = msgfunc(parent, title, text, cast(QMessageBox.StandardButtons, sb), default)
if r == QMessageBox.Help:
default = QMessageBox.StandardButton.Yes
r = msgfunc(parent, title, text, sb, default)
if r == QMessageBox.StandardButton.Help:
openHelp(help)
else:
break
return r == QMessageBox.Yes
return r == QMessageBox.StandardButton.Yes
class ButtonedDialog(QMessageBox):
@ -238,12 +238,12 @@ class ButtonedDialog(QMessageBox):
self._buttons: list[QPushButton] = []
self.setWindowTitle(title)
self.help = help
self.setIcon(QMessageBox.Warning)
self.setIcon(QMessageBox.Icon.Warning)
self.setText(text)
for b in buttons:
self._buttons.append(self.addButton(b, QMessageBox.AcceptRole))
self._buttons.append(self.addButton(b, QMessageBox.ButtonRole.AcceptRole))
if help:
self.addButton(tr.actions_help(), QMessageBox.HelpRole)
self.addButton(tr.actions_help(), QMessageBox.ButtonRole.HelpRole)
buttons.append(tr.actions_help())
def run(self) -> str:
@ -300,16 +300,21 @@ class GetTextDialog(QDialog):
self.l.setText(default)
self.l.selectAll()
v.addWidget(self.l)
buts = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
buts = (
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
)
if help:
buts |= QDialogButtonBox.Help
buts |= QDialogButtonBox.StandardButton.Help
b = QDialogButtonBox(buts) # type: ignore
v.addWidget(b)
self.setLayout(v)
qconnect(b.button(QDialogButtonBox.Ok).clicked, self.accept)
qconnect(b.button(QDialogButtonBox.Cancel).clicked, self.reject)
qconnect(b.button(QDialogButtonBox.StandardButton.Ok).clicked, self.accept)
qconnect(b.button(QDialogButtonBox.StandardButton.Cancel).clicked, self.reject)
if help:
qconnect(b.button(QDialogButtonBox.Help).clicked, self.helpRequested)
qconnect(
b.button(QDialogButtonBox.StandardButton.Help).clicked,
self.helpRequested,
)
def accept(self) -> None:
return QDialog.accept(self)
@ -337,7 +342,7 @@ def getText(
d = GetTextDialog(
parent, prompt, help=help, edit=edit, default=default, title=title, **kwargs
)
d.setWindowModality(Qt.WindowModal)
d.setWindowModality(Qt.WindowModality.WindowModal)
if geomKey:
restoreGeom(d, geomKey)
ret = d.exec()
@ -363,7 +368,7 @@ def chooseList(
parent = aqt.mw.app.activeWindow()
d = QDialog(parent)
disable_help_button(d)
d.setWindowModality(Qt.WindowModal)
d.setWindowModality(Qt.WindowModality.WindowModal)
l = QVBoxLayout()
d.setLayout(l)
t = QLabel(prompt)
@ -372,7 +377,7 @@ def chooseList(
c.addItems(choices)
c.setCurrentRow(startrow)
l.addWidget(c)
bb = QDialogButtonBox(QDialogButtonBox.Ok)
bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok)
qconnect(bb.accepted, d.accept)
l.addWidget(bb)
d.exec()
@ -393,9 +398,9 @@ def getTag(
def disable_help_button(widget: QWidget) -> None:
"Disable the help button in the window titlebar."
flags_int = int(widget.windowFlags()) & ~Qt.WindowContextHelpButtonHint
flags = Qt.WindowFlags(flags_int) # type: ignore
widget.setWindowFlags(flags)
widget.setWindowFlags(
widget.windowFlags() & ~Qt.WindowType.WindowContextHelpButtonHint
)
# File handling
@ -420,7 +425,11 @@ def getFile(
else:
dirkey = None
d = QFileDialog(parent)
mode = QFileDialog.ExistingFiles if multi else QFileDialog.ExistingFile
mode = (
QFileDialog.FileMode.ExistingFiles
if multi
else QFileDialog.FileMode.ExistingFile
)
d.setFileMode(mode)
if os.path.exists(dir):
d.setDirectory(dir)
@ -459,7 +468,9 @@ def getSaveFile(
variable. The file dialog will default to open with FNAME."""
config_key = f"{dir_description}Directory"
defaultPath = QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation)
defaultPath = QStandardPaths.writableLocation(
QStandardPaths.StandardLocation.DocumentsLocation
)
base = aqt.mw.pm.profile.get(config_key, defaultPath)
path = os.path.join(base, fname)
file = QFileDialog.getSaveFileName(
@ -467,7 +478,7 @@ def getSaveFile(
title,
path,
f"{key} (*{ext})",
options=QFileDialog.DontConfirmOverwrite,
options=QFileDialog.Option.DontConfirmOverwrite,
)[0]
if file:
# add extension
@ -485,7 +496,7 @@ def getSaveFile(
def saveGeom(widget: QWidget, key: str) -> None:
key += "Geom"
if isMac and int(widget.windowState()) & Qt.WindowFullScreen:
if isMac and (widget.windowState() & Qt.WindowState.WindowFullScreen):
geom = None
else:
geom = widget.saveGeometry()
@ -646,7 +657,7 @@ def shortcut(key: str) -> str:
def maybeHideClose(bbox: QDialogButtonBox) -> None:
if isMac:
b = bbox.button(QDialogButtonBox.Close)
b = bbox.button(QDialogButtonBox.StandardButton.Close)
if b:
bbox.removeButton(b)
@ -706,13 +717,13 @@ def tooltip(
</table>""",
aw,
)
lab.setFrameStyle(QFrame.Panel)
lab.setFrameStyle(QFrame.Shape.Panel)
lab.setLineWidth(2)
lab.setWindowFlags(Qt.ToolTip)
lab.setWindowFlags(Qt.WindowType.ToolTip)
if not theme_manager.night_mode:
p = QPalette()
p.setColor(QPalette.Window, QColor("#feffc4"))
p.setColor(QPalette.WindowText, QColor("#000000"))
p.setColor(QPalette.ColorRole.Window, QColor("#feffc4"))
p.setColor(QPalette.ColorRole.WindowText, QColor("#000000"))
lab.setPalette(p)
lab.move(aw.mapToGlobal(QPoint(0 + x_offset, aw.height() - y_offset)))
lab.show()
@ -888,7 +899,7 @@ def opengl_vendor() -> str | None:
# Can't use versionFunctions there
return None
vp = QOpenGLVersionProfile() # type: ignore
vp = QOpenGLVersionProfile() # type: ignore # pylint: disable=undefined-variable
vp.setVersion(2, 0)
try:
@ -969,16 +980,16 @@ class KeyboardModifiersPressed:
def __init__(self) -> None:
from aqt import mw
self._modifiers = int(mw.app.keyboardModifiers())
self._modifiers = mw.app.keyboardModifiers()
@property
def shift(self) -> bool:
return bool(self._modifiers & Qt.ShiftModifier)
return bool(self._modifiers & Qt.KeyboardModifier.ShiftModifier)
@property
def control(self) -> bool:
return bool(self._modifiers & Qt.ControlModifier)
return bool(self._modifiers & Qt.KeyboardModifier.ControlModifier)
@property
def alt(self) -> bool:
return bool(self._modifiers & Qt.AltModifier)
return bool(self._modifiers & Qt.KeyboardModifier.AltModifier)

View file

@ -48,7 +48,7 @@ class AnkiWebPage(QWebEnginePage):
qwebchannel = ":/qtwebchannel/qwebchannel.js"
jsfile = QFile(qwebchannel)
if not jsfile.open(QIODevice.ReadOnly):
if not jsfile.open(QIODevice.OpenModeFlag.ReadOnly):
print(f"Error opening '{qwebchannel}': {jsfile.error()}", file=sys.stderr)
jstext = bytes(cast(bytes, jsfile.readAll())).decode("utf-8")
jsfile.close()
@ -74,8 +74,8 @@ class AnkiWebPage(QWebEnginePage):
});
"""
)
script.setWorldId(QWebEngineScript.MainWorld)
script.setInjectionPoint(QWebEngineScript.DocumentReady)
script.setWorldId(QWebEngineScript.ScriptWorldId.MainWorld)
script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
script.setRunsOnSubFrames(False)
self.profile().scripts().insert(script)
@ -92,11 +92,11 @@ class AnkiWebPage(QWebEnginePage):
srcID = ""
else:
srcID = serverbaseurl.sub("", srcID[:80], 1)
if level == QWebEnginePage.InfoMessageLevel:
if level == QWebEnginePage.JavaScriptConsoleMessageLevel.InfoMessageLevel:
level_str = "info"
elif level == QWebEnginePage.WarningMessageLevel:
elif level == QWebEnginePage.JavaScriptConsoleMessageLevel.WarningMessageLevel:
level_str = "warning"
elif level == QWebEnginePage.ErrorMessageLevel:
elif level == QWebEnginePage.JavaScriptConsoleMessageLevel.ErrorMessageLevel:
level_str = "error"
else:
level_str = str(level)
@ -135,7 +135,9 @@ class AnkiWebPage(QWebEnginePage):
# catch buggy <a href='#' onclick='func()'> links
from aqt import mw
if url.matches(QUrl(mw.serverURL()), cast(Any, QUrl.RemoveFragment)):
if url.matches(
QUrl(mw.serverURL()), cast(Any, QUrl.UrlFormattingOption.RemoveFragment)
):
print("onclick handler needs to return false")
return False
# load all other links in browser
@ -240,14 +242,14 @@ class AnkiWebView(QWebEngineView):
self.requiresCol = True
self.setPage(self._page)
self._page.profile().setHttpCacheType(QWebEngineProfile.NoCache)
self._page.profile().setHttpCacheType(QWebEngineProfile.HttpCacheType.NoCache)
self.resetHandlers()
self.allowDrops = False
self._filterSet = False
QShortcut( # type: ignore
QKeySequence("Esc"),
self,
context=Qt.WidgetWithChildrenShortcut,
context=Qt.ShortcutContext.WidgetWithChildrenShortcut,
activated=self.onEsc,
)
@ -258,8 +260,11 @@ class AnkiWebView(QWebEngineView):
# disable pinch to zoom gesture
if isinstance(evt, QNativeGestureEvent):
return True
elif isinstance(evt, QMouseEvent) and evt.type() == QEvent.MouseButtonRelease:
if evt.button() == Qt.MidButton and isLin:
elif (
isinstance(evt, QMouseEvent)
and evt.type() == QEvent.Type.MouseButtonRelease
):
if evt.button() == Qt.MouseButton.MiddleButton and isLin:
self.onMiddleClickPaste()
return True
return False
@ -286,19 +291,19 @@ class AnkiWebView(QWebEngineView):
w = w.parent()
def onCopy(self) -> None:
self.triggerPageAction(QWebEnginePage.Copy)
self.triggerPageAction(QWebEnginePage.WebAction.Copy)
def onCut(self) -> None:
self.triggerPageAction(QWebEnginePage.Cut)
self.triggerPageAction(QWebEnginePage.WebAction.Cut)
def onPaste(self) -> None:
self.triggerPageAction(QWebEnginePage.Paste)
self.triggerPageAction(QWebEnginePage.WebAction.Paste)
def onMiddleClickPaste(self) -> None:
self.triggerPageAction(QWebEnginePage.Paste)
self.triggerPageAction(QWebEnginePage.WebAction.Paste)
def onSelectAll(self) -> None:
self.triggerPageAction(QWebEnginePage.SelectAll)
self.triggerPageAction(QWebEnginePage.WebAction.SelectAll)
def contextMenuEvent(self, evt: QContextMenuEvent) -> None:
m = QMenu(self)
@ -386,11 +391,11 @@ class AnkiWebView(QWebEngineView):
# standard palette does not return correct window color on macOS
return QColor("#ececec")
else:
return theme_manager.default_palette.color(QPalette.Window)
return theme_manager.default_palette.color(QPalette.ColorRole.Window)
def standard_css(self) -> str:
palette = theme_manager.default_palette
color_hl = palette.color(QPalette.Highlight).name()
color_hl = palette.color(QPalette.ColorRole.Highlight).name()
if isWin:
# T: include a font for your language on Windows, eg: "Segoe UI", "MS Mincho"
@ -406,8 +411,8 @@ button { -webkit-appearance: none; background: #fff; border: 1px solid #ccc;
border-radius:5px; font-family: Helvetica }"""
else:
family = self.font().family()
color_hl_txt = palette.color(QPalette.HighlightedText).name()
color_btn = palette.color(QPalette.Button).name()
color_hl_txt = palette.color(QPalette.ColorRole.HighlightedText).name()
color_btn = palette.color(QPalette.ColorRole.Button).name()
font = f'font-size:14px;font-family:"{family}";'
button_style = """
/* Buttons */

View file

@ -36,7 +36,7 @@ if subprocess.run(
os.path.abspath("pip/stubs/extendsitepkgs"),
],
env={
"MYPYPATH": "bazel-bin/qt/dmypy.runfiles/pyqt5",
"MYPYPATH": "bazel-bin/qt/dmypy.runfiles/pyqt6",
"EXTRA_SITE_PACKAGES": os.path.abspath(os.getenv("EXTRA_SITE_PACKAGES")),
},
cwd=workspace,

View file

@ -54,6 +54,7 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-PyQt5.*]
ignore_errors = True
ignore_missing_imports = True
[mypy-win32com.client]
ignore_missing_imports = True
[mypy-darkdetect]