mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Enable strict_optional for aqt/tagedit, utils, sync (#3578)
* Enable strict_optional for tagedit * Fix mypy errors * Enable strict_optional for utils * Fix mypy errors * Enable strict_optional for sync * Fix mypy errors --------- Co-authored-by: Abdo <abdo@abdnh.net>
This commit is contained in:
parent
29f714d973
commit
9d09c32ece
6 changed files with 111 additions and 49 deletions
|
@ -104,6 +104,12 @@ strict_optional = True
|
||||||
strict_optional = True
|
strict_optional = True
|
||||||
[mypy-aqt.progress]
|
[mypy-aqt.progress]
|
||||||
strict_optional = True
|
strict_optional = True
|
||||||
|
[mypy-aqt.tagedit]
|
||||||
|
strict_optional = True
|
||||||
|
[mypy-aqt.utils]
|
||||||
|
strict_optional = True
|
||||||
|
[mypy-aqt.sync]
|
||||||
|
strict_optional = True
|
||||||
[mypy-anki.scheduler.base]
|
[mypy-anki.scheduler.base]
|
||||||
strict_optional = True
|
strict_optional = True
|
||||||
[mypy-anki._backend.rsbridge]
|
[mypy-anki._backend.rsbridge]
|
||||||
|
|
|
@ -1128,7 +1128,7 @@ class Collection(DeprecatedNamesMixin):
|
||||||
self._backend.abort_sync()
|
self._backend.abort_sync()
|
||||||
|
|
||||||
def full_upload_or_download(
|
def full_upload_or_download(
|
||||||
self, *, auth: SyncAuth, server_usn: int | None, upload: bool
|
self, *, auth: SyncAuth | None, server_usn: int | None, upload: bool
|
||||||
) -> None:
|
) -> None:
|
||||||
self._backend.full_upload_or_download(
|
self._backend.full_upload_or_download(
|
||||||
sync_pb2.FullUploadOrDownloadRequest(
|
sync_pb2.FullUploadOrDownloadRequest(
|
||||||
|
|
|
@ -94,7 +94,7 @@ class NewDeckStats(QDialog):
|
||||||
lambda _: self.refresh()
|
lambda _: self.refresh()
|
||||||
).run_in_background()
|
).run_in_background()
|
||||||
|
|
||||||
def _imagePath(self) -> str:
|
def _imagePath(self) -> str | None:
|
||||||
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time()))
|
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time()))
|
||||||
name = f"anki-{tr.statistics_stats()}{name}"
|
name = f"anki-{tr.statistics_stats()}{name}"
|
||||||
file = getSaveFile(
|
file = getSaveFile(
|
||||||
|
@ -196,7 +196,7 @@ class DeckStats(QDialog):
|
||||||
self.reject()
|
self.reject()
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
def _imagePath(self) -> str:
|
def _imagePath(self) -> str | None:
|
||||||
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time()))
|
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time()))
|
||||||
name = f"anki-{tr.statistics_stats()}{name}"
|
name = f"anki-{tr.statistics_stats()}{name}"
|
||||||
file = getSaveFile(
|
file = getSaveFile(
|
||||||
|
|
|
@ -168,7 +168,7 @@ def full_sync(
|
||||||
|
|
||||||
|
|
||||||
def confirm_full_download(
|
def confirm_full_download(
|
||||||
mw: aqt.main.AnkiQt, server_usn: int, on_done: Callable[[], None]
|
mw: aqt.main.AnkiQt, server_usn: int | None, on_done: Callable[[], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
# confirmation step required, as some users customize their notetypes
|
# confirmation step required, as some users customize their notetypes
|
||||||
# in an empty collection, then want to upload them
|
# in an empty collection, then want to upload them
|
||||||
|
@ -184,7 +184,7 @@ def confirm_full_download(
|
||||||
|
|
||||||
|
|
||||||
def confirm_full_upload(
|
def confirm_full_upload(
|
||||||
mw: aqt.main.AnkiQt, server_usn: int, on_done: Callable[[], None]
|
mw: aqt.main.AnkiQt, server_usn: int | None, on_done: Callable[[], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
# confirmation step required, as some users have reported an upload
|
# confirmation step required, as some users have reported an upload
|
||||||
# happening despite having their AnkiWeb collection not being empty
|
# happening despite having their AnkiWeb collection not being empty
|
||||||
|
@ -220,7 +220,7 @@ def on_full_sync_timer(mw: aqt.main.AnkiQt, label: str) -> None:
|
||||||
|
|
||||||
|
|
||||||
def full_download(
|
def full_download(
|
||||||
mw: aqt.main.AnkiQt, server_usn: int, on_done: Callable[[], None]
|
mw: aqt.main.AnkiQt, server_usn: int | None, on_done: Callable[[], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
label = tr.sync_downloading_from_ankiweb()
|
label = tr.sync_downloading_from_ankiweb()
|
||||||
|
|
||||||
|
@ -372,7 +372,9 @@ def get_id_and_pass_from_user(
|
||||||
l2.setBuddy(passwd)
|
l2.setBuddy(passwd)
|
||||||
vbox.addLayout(g)
|
vbox.addLayout(g)
|
||||||
bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) # type: ignore
|
bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) # type: ignore
|
||||||
bb.button(QDialogButtonBox.StandardButton.Ok).setAutoDefault(True)
|
ok_button = bb.button(QDialogButtonBox.StandardButton.Ok)
|
||||||
|
assert ok_button is not None
|
||||||
|
ok_button.setAutoDefault(True)
|
||||||
qconnect(bb.accepted, diag.accept)
|
qconnect(bb.accepted, diag.accept)
|
||||||
qconnect(bb.rejected, diag.reject)
|
qconnect(bb.rejected, diag.reject)
|
||||||
vbox.addWidget(bb)
|
vbox.addWidget(bb)
|
||||||
|
|
|
@ -42,13 +42,17 @@ class TagEdit(QLineEdit):
|
||||||
l = (d.name for d in self.col.decks.all_names_and_ids())
|
l = (d.name for d in self.col.decks.all_names_and_ids())
|
||||||
self.model.setStringList(l)
|
self.model.setStringList(l)
|
||||||
|
|
||||||
def focusInEvent(self, evt: QFocusEvent) -> None:
|
def focusInEvent(self, evt: QFocusEvent | None) -> None:
|
||||||
QLineEdit.focusInEvent(self, evt)
|
QLineEdit.focusInEvent(self, evt)
|
||||||
|
|
||||||
def keyPressEvent(self, evt: QKeyEvent) -> None:
|
def keyPressEvent(self, evt: QKeyEvent | None) -> None:
|
||||||
|
assert evt is not None
|
||||||
|
popup = self._completer.popup()
|
||||||
|
assert popup is not None
|
||||||
|
|
||||||
if evt.key() in (Qt.Key.Key_Up, Qt.Key.Key_Down):
|
if evt.key() in (Qt.Key.Key_Up, Qt.Key.Key_Down):
|
||||||
# show completer on arrow key up/down
|
# show completer on arrow key up/down
|
||||||
if not self._completer.popup().isVisible():
|
if not popup.isVisible():
|
||||||
self.showCompleter()
|
self.showCompleter()
|
||||||
return
|
return
|
||||||
if (
|
if (
|
||||||
|
@ -56,24 +60,21 @@ class TagEdit(QLineEdit):
|
||||||
and evt.modifiers() & Qt.KeyboardModifier.ControlModifier
|
and evt.modifiers() & Qt.KeyboardModifier.ControlModifier
|
||||||
):
|
):
|
||||||
# select next completion
|
# select next completion
|
||||||
if not self._completer.popup().isVisible():
|
if not popup.isVisible():
|
||||||
self.showCompleter()
|
self.showCompleter()
|
||||||
index = self._completer.currentIndex()
|
index = self._completer.currentIndex()
|
||||||
self._completer.popup().setCurrentIndex(index)
|
popup.setCurrentIndex(index)
|
||||||
cur_row = index.row()
|
cur_row = index.row()
|
||||||
if not self._completer.setCurrentRow(cur_row + 1):
|
if not self._completer.setCurrentRow(cur_row + 1):
|
||||||
self._completer.setCurrentRow(0)
|
self._completer.setCurrentRow(0)
|
||||||
return
|
return
|
||||||
if (
|
if evt.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return) and popup.isVisible():
|
||||||
evt.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return)
|
|
||||||
and self._completer.popup().isVisible()
|
|
||||||
):
|
|
||||||
# apply first completion if no suggestion selected
|
# apply first completion if no suggestion selected
|
||||||
selected_row = self._completer.popup().currentIndex().row()
|
selected_row = popup.currentIndex().row()
|
||||||
if selected_row == -1:
|
if selected_row == -1:
|
||||||
self._completer.setCurrentRow(0)
|
self._completer.setCurrentRow(0)
|
||||||
index = self._completer.currentIndex()
|
index = self._completer.currentIndex()
|
||||||
self._completer.popup().setCurrentIndex(index)
|
popup.setCurrentIndex(index)
|
||||||
self.hideCompleter()
|
self.hideCompleter()
|
||||||
QWidget.keyPressEvent(self, evt)
|
QWidget.keyPressEvent(self, evt)
|
||||||
return
|
return
|
||||||
|
@ -97,15 +98,19 @@ class TagEdit(QLineEdit):
|
||||||
self._completer.setCompletionPrefix(self.text())
|
self._completer.setCompletionPrefix(self.text())
|
||||||
self._completer.complete()
|
self._completer.complete()
|
||||||
|
|
||||||
def focusOutEvent(self, evt: QFocusEvent) -> None:
|
def focusOutEvent(self, evt: QFocusEvent | None) -> None:
|
||||||
QLineEdit.focusOutEvent(self, evt)
|
QLineEdit.focusOutEvent(self, evt)
|
||||||
self.lostFocus.emit() # type: ignore
|
self.lostFocus.emit() # type: ignore
|
||||||
self._completer.popup().hide()
|
popup = self._completer.popup()
|
||||||
|
assert popup is not None
|
||||||
|
popup.hide()
|
||||||
|
|
||||||
def hideCompleter(self) -> None:
|
def hideCompleter(self) -> None:
|
||||||
if sip.isdeleted(self._completer): # type: ignore
|
if sip.isdeleted(self._completer): # type: ignore
|
||||||
return
|
return
|
||||||
self._completer.popup().hide()
|
popup = self._completer.popup()
|
||||||
|
assert popup is not None
|
||||||
|
popup.hide()
|
||||||
|
|
||||||
|
|
||||||
class TagCompleter(QCompleter):
|
class TagCompleter(QCompleter):
|
||||||
|
@ -120,7 +125,9 @@ class TagCompleter(QCompleter):
|
||||||
self.edit = edit
|
self.edit = edit
|
||||||
self.cursor: int | None = None
|
self.cursor: int | None = None
|
||||||
|
|
||||||
def splitPath(self, tags: str) -> list[str]:
|
def splitPath(self, tags: str | None) -> list[str]:
|
||||||
|
assert tags is not None
|
||||||
|
assert self.edit.col is not None
|
||||||
stripped_tags = tags.strip()
|
stripped_tags = tags.strip()
|
||||||
stripped_tags = re.sub(" +", " ", stripped_tags)
|
stripped_tags = re.sub(" +", " ", stripped_tags)
|
||||||
self.tags = self.edit.col.tags.split(stripped_tags)
|
self.tags = self.edit.col.tags.split(stripped_tags)
|
||||||
|
|
101
qt/aqt/utils.py
101
qt/aqt/utils.py
|
@ -118,10 +118,13 @@ HelpPageArgument = Union["HelpPage.V", str]
|
||||||
|
|
||||||
|
|
||||||
def openHelp(section: HelpPageArgument) -> None:
|
def openHelp(section: HelpPageArgument) -> None:
|
||||||
|
assert tr.backend is not None
|
||||||
|
backend = tr.backend()
|
||||||
|
assert backend is not None
|
||||||
if isinstance(section, str):
|
if isinstance(section, str):
|
||||||
link = tr.backend().help_page_link(page=HelpPage.INDEX) + section
|
link = backend.help_page_link(page=HelpPage.INDEX) + section
|
||||||
else:
|
else:
|
||||||
link = tr.backend().help_page_link(page=section)
|
link = backend.help_page_link(page=section)
|
||||||
openLink(link)
|
openLink(link)
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,17 +173,20 @@ class MessageBox(QMessageBox):
|
||||||
b = self.addButton(button)
|
b = self.addButton(button)
|
||||||
# a translator has complained the default Qt translation is inappropriate, so we override it
|
# a translator has complained the default Qt translation is inappropriate, so we override it
|
||||||
if button == QMessageBox.StandardButton.Discard:
|
if button == QMessageBox.StandardButton.Discard:
|
||||||
|
assert b is not None
|
||||||
b.setText(tr.actions_discard())
|
b.setText(tr.actions_discard())
|
||||||
elif isinstance(button, tuple):
|
elif isinstance(button, tuple):
|
||||||
b = self.addButton(button[0], button[1])
|
b = self.addButton(button[0], button[1])
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
if callback is not None:
|
if callback is not None:
|
||||||
|
assert b is not None
|
||||||
qconnect(b.clicked, partial(callback, i))
|
qconnect(b.clicked, partial(callback, i))
|
||||||
if i == default_button:
|
if i == default_button:
|
||||||
self.setDefaultButton(b)
|
self.setDefaultButton(b)
|
||||||
if help is not None:
|
if help is not None:
|
||||||
b = self.addButton(QMessageBox.StandardButton.Help)
|
b = self.addButton(QMessageBox.StandardButton.Help)
|
||||||
|
assert b is not None
|
||||||
qconnect(b.clicked, lambda: openHelp(help))
|
qconnect(b.clicked, lambda: openHelp(help))
|
||||||
self.open()
|
self.open()
|
||||||
|
|
||||||
|
@ -316,9 +322,11 @@ def showInfo(
|
||||||
mb.setDefaultButton(default)
|
mb.setDefaultButton(default)
|
||||||
else:
|
else:
|
||||||
b = mb.addButton(QMessageBox.StandardButton.Ok)
|
b = mb.addButton(QMessageBox.StandardButton.Ok)
|
||||||
|
assert b is not None
|
||||||
b.setDefault(True)
|
b.setDefault(True)
|
||||||
if help is not None:
|
if help is not None:
|
||||||
b = mb.addButton(QMessageBox.StandardButton.Help)
|
b = mb.addButton(QMessageBox.StandardButton.Help)
|
||||||
|
assert b is not None
|
||||||
qconnect(b.clicked, lambda: openHelp(help))
|
qconnect(b.clicked, lambda: openHelp(help))
|
||||||
b.setAutoDefault(False)
|
b.setAutoDefault(False)
|
||||||
return mb.exec()
|
return mb.exec()
|
||||||
|
@ -363,7 +371,9 @@ def showText(
|
||||||
if copyBtn:
|
if copyBtn:
|
||||||
|
|
||||||
def onCopy() -> None:
|
def onCopy() -> None:
|
||||||
QApplication.clipboard().setText(text.toPlainText())
|
clipboard = QApplication.clipboard()
|
||||||
|
assert clipboard is not None
|
||||||
|
clipboard.setText(text.toPlainText())
|
||||||
|
|
||||||
btn = QPushButton(tr.qt_misc_copy_to_clipboard())
|
btn = QPushButton(tr.qt_misc_copy_to_clipboard())
|
||||||
qconnect(btn.clicked, onCopy)
|
qconnect(btn.clicked, onCopy)
|
||||||
|
@ -415,6 +425,7 @@ def askUser(
|
||||||
default = QMessageBox.StandardButton.Yes
|
default = QMessageBox.StandardButton.Yes
|
||||||
r = msgfunc(parent, title, text, sb, default)
|
r = msgfunc(parent, title, text, sb, default)
|
||||||
if r == QMessageBox.StandardButton.Help:
|
if r == QMessageBox.StandardButton.Help:
|
||||||
|
assert help is not None
|
||||||
openHelp(help)
|
openHelp(help)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
@ -431,7 +442,7 @@ class ButtonedDialog(QMessageBox):
|
||||||
title: str = "Anki",
|
title: str = "Anki",
|
||||||
):
|
):
|
||||||
QMessageBox.__init__(self, parent)
|
QMessageBox.__init__(self, parent)
|
||||||
self._buttons: list[QPushButton] = []
|
self._buttons: list[QPushButton | None] = []
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
self.help = help
|
self.help = help
|
||||||
self.setIcon(QMessageBox.Icon.Warning)
|
self.setIcon(QMessageBox.Icon.Warning)
|
||||||
|
@ -444,11 +455,13 @@ class ButtonedDialog(QMessageBox):
|
||||||
|
|
||||||
def run(self) -> str:
|
def run(self) -> str:
|
||||||
self.exec()
|
self.exec()
|
||||||
but = self.clickedButton().text()
|
clicked_button = self.clickedButton()
|
||||||
if but == "Help":
|
assert clicked_button is not None
|
||||||
|
txt = clicked_button.text()
|
||||||
|
if txt == "Help":
|
||||||
# FIXME stop dialog closing?
|
# FIXME stop dialog closing?
|
||||||
|
assert self.help is not None
|
||||||
openHelp(self.help)
|
openHelp(self.help)
|
||||||
txt = self.clickedButton().text()
|
|
||||||
# work around KDE 'helpfully' adding accelerators to button text of Qt apps
|
# work around KDE 'helpfully' adding accelerators to button text of Qt apps
|
||||||
return txt.replace("&", "")
|
return txt.replace("&", "")
|
||||||
|
|
||||||
|
@ -504,13 +517,18 @@ class GetTextDialog(QDialog):
|
||||||
b = QDialogButtonBox(buts) # type: ignore
|
b = QDialogButtonBox(buts) # type: ignore
|
||||||
v.addWidget(b)
|
v.addWidget(b)
|
||||||
self.setLayout(v)
|
self.setLayout(v)
|
||||||
qconnect(b.button(QDialogButtonBox.StandardButton.Ok).clicked, self.accept)
|
ok_button = b.button(QDialogButtonBox.StandardButton.Ok)
|
||||||
qconnect(b.button(QDialogButtonBox.StandardButton.Cancel).clicked, self.reject)
|
assert ok_button is not None
|
||||||
|
qconnect(ok_button.clicked, self.accept)
|
||||||
|
|
||||||
|
cancel_button = b.button(QDialogButtonBox.StandardButton.Cancel)
|
||||||
|
assert cancel_button is not None
|
||||||
|
qconnect(cancel_button.clicked, self.reject)
|
||||||
|
|
||||||
if help:
|
if help:
|
||||||
qconnect(
|
help_button = b.button(QDialogButtonBox.StandardButton.Help)
|
||||||
b.button(QDialogButtonBox.StandardButton.Help).clicked,
|
assert help_button is not None
|
||||||
self.helpRequested,
|
qconnect(help_button.clicked, self.helpRequested)
|
||||||
)
|
|
||||||
self.l.setFocus()
|
self.l.setFocus()
|
||||||
|
|
||||||
def accept(self) -> None:
|
def accept(self) -> None:
|
||||||
|
@ -520,7 +538,8 @@ class GetTextDialog(QDialog):
|
||||||
return QDialog.reject(self)
|
return QDialog.reject(self)
|
||||||
|
|
||||||
def helpRequested(self) -> None:
|
def helpRequested(self) -> None:
|
||||||
openHelp(self.help)
|
if self.help is not None:
|
||||||
|
openHelp(self.help)
|
||||||
|
|
||||||
|
|
||||||
def getText(
|
def getText(
|
||||||
|
@ -624,6 +643,7 @@ def getFile(
|
||||||
if dir and key:
|
if dir and key:
|
||||||
raise Exception("expected dir or key")
|
raise Exception("expected dir or key")
|
||||||
if not dir:
|
if not dir:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
dirkey = f"{key}Directory"
|
dirkey = f"{key}Directory"
|
||||||
dir = aqt.mw.pm.profile.get(dirkey, "")
|
dir = aqt.mw.pm.profile.get(dirkey, "")
|
||||||
else:
|
else:
|
||||||
|
@ -635,6 +655,7 @@ def getFile(
|
||||||
else QFileDialog.FileMode.ExistingFile
|
else QFileDialog.FileMode.ExistingFile
|
||||||
)
|
)
|
||||||
d.setFileMode(mode)
|
d.setFileMode(mode)
|
||||||
|
assert dir is not None
|
||||||
if os.path.exists(dir):
|
if os.path.exists(dir):
|
||||||
d.setDirectory(dir)
|
d.setDirectory(dir)
|
||||||
d.setWindowTitle(title)
|
d.setWindowTitle(title)
|
||||||
|
@ -644,6 +665,7 @@ def getFile(
|
||||||
def accept() -> None:
|
def accept() -> None:
|
||||||
files = list(d.selectedFiles())
|
files = list(d.selectedFiles())
|
||||||
if dirkey:
|
if dirkey:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
dir = os.path.dirname(files[0])
|
dir = os.path.dirname(files[0])
|
||||||
aqt.mw.pm.profile[dirkey] = dir
|
aqt.mw.pm.profile[dirkey] = dir
|
||||||
result = files if multi else files[0]
|
result = files if multi else files[0]
|
||||||
|
@ -683,10 +705,11 @@ def getSaveFile(
|
||||||
dir_description: str,
|
dir_description: str,
|
||||||
key: str,
|
key: str,
|
||||||
ext: str,
|
ext: str,
|
||||||
fname: str | None = None,
|
fname: str = "",
|
||||||
) -> str:
|
) -> str | None:
|
||||||
"""Ask the user for a file to save. Use DIR_DESCRIPTION as config
|
"""Ask the user for a file to save. Use DIR_DESCRIPTION as config
|
||||||
variable. The file dialog will default to open with FNAME."""
|
variable. The file dialog will default to open with FNAME."""
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
config_key = f"{dir_description}Directory"
|
config_key = f"{dir_description}Directory"
|
||||||
|
|
||||||
defaultPath = QStandardPaths.writableLocation(
|
defaultPath = QStandardPaths.writableLocation(
|
||||||
|
@ -709,9 +732,10 @@ def getSaveFile(
|
||||||
dir = os.path.dirname(file)
|
dir = os.path.dirname(file)
|
||||||
aqt.mw.pm.profile[config_key] = dir
|
aqt.mw.pm.profile[config_key] = dir
|
||||||
# check if it exists
|
# check if it exists
|
||||||
if os.path.exists(file):
|
if os.path.exists(file) and not askUser(
|
||||||
if not askUser(tr.qt_misc_this_file_exists_are_you_sure(), parent):
|
tr.qt_misc_this_file_exists_are_you_sure(), parent
|
||||||
return None
|
):
|
||||||
|
return None
|
||||||
return file
|
return file
|
||||||
|
|
||||||
|
|
||||||
|
@ -735,6 +759,7 @@ def _qt_state_key(kind: _QtStateKeyKind, key: str) -> str:
|
||||||
def saveGeom(widget: QWidget, key: str) -> None:
|
def saveGeom(widget: QWidget, key: str) -> None:
|
||||||
# restoring a fullscreen window breaks the tab functionality of 5.15
|
# restoring a fullscreen window breaks the tab functionality of 5.15
|
||||||
if not widget.isFullScreen() or qtmajor == 6:
|
if not widget.isFullScreen() or qtmajor == 6:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.GEOMETRY, key)
|
key = _qt_state_key(_QtStateKeyKind.GEOMETRY, key)
|
||||||
aqt.mw.pm.profile[key] = widget.saveGeometry()
|
aqt.mw.pm.profile[key] = widget.saveGeometry()
|
||||||
|
|
||||||
|
@ -745,6 +770,7 @@ def restoreGeom(
|
||||||
adjustSize: bool = False,
|
adjustSize: bool = False,
|
||||||
default_size: tuple[int, int] | None = None,
|
default_size: tuple[int, int] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.GEOMETRY, key)
|
key = _qt_state_key(_QtStateKeyKind.GEOMETRY, key)
|
||||||
if existing_geom := aqt.mw.pm.profile.get(key):
|
if existing_geom := aqt.mw.pm.profile.get(key):
|
||||||
widget.restoreGeometry(existing_geom)
|
widget.restoreGeometry(existing_geom)
|
||||||
|
@ -756,7 +782,9 @@ def restoreGeom(
|
||||||
|
|
||||||
|
|
||||||
def ensureWidgetInScreenBoundaries(widget: QWidget) -> None:
|
def ensureWidgetInScreenBoundaries(widget: QWidget) -> None:
|
||||||
handle = widget.window().windowHandle()
|
window = widget.window()
|
||||||
|
assert window is not None
|
||||||
|
handle = window.windowHandle()
|
||||||
if not handle:
|
if not handle:
|
||||||
# window has not yet been shown, retry later
|
# window has not yet been shown, retry later
|
||||||
aqt.mw.progress.timer(
|
aqt.mw.progress.timer(
|
||||||
|
@ -765,7 +793,9 @@ def ensureWidgetInScreenBoundaries(widget: QWidget) -> None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# ensure widget is smaller than screen bounds
|
# ensure widget is smaller than screen bounds
|
||||||
geom = handle.screen().availableGeometry()
|
screen = handle.screen()
|
||||||
|
assert screen is not None
|
||||||
|
geom = screen.availableGeometry()
|
||||||
wsize = widget.size()
|
wsize = widget.size()
|
||||||
cappedWidth = min(geom.width(), wsize.width())
|
cappedWidth = min(geom.width(), wsize.width())
|
||||||
cappedHeight = min(geom.height(), wsize.height())
|
cappedHeight = min(geom.height(), wsize.height())
|
||||||
|
@ -784,44 +814,52 @@ def ensureWidgetInScreenBoundaries(widget: QWidget) -> None:
|
||||||
|
|
||||||
|
|
||||||
def saveState(widget: QFileDialog | QMainWindow, key: str) -> None:
|
def saveState(widget: QFileDialog | QMainWindow, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.STATE, key)
|
key = _qt_state_key(_QtStateKeyKind.STATE, key)
|
||||||
aqt.mw.pm.profile[key] = widget.saveState()
|
aqt.mw.pm.profile[key] = widget.saveState()
|
||||||
|
|
||||||
|
|
||||||
def restoreState(widget: QFileDialog | QMainWindow, key: str) -> None:
|
def restoreState(widget: QFileDialog | QMainWindow, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.STATE, key)
|
key = _qt_state_key(_QtStateKeyKind.STATE, key)
|
||||||
if data := aqt.mw.pm.profile.get(key):
|
if data := aqt.mw.pm.profile.get(key):
|
||||||
widget.restoreState(data)
|
widget.restoreState(data)
|
||||||
|
|
||||||
|
|
||||||
def saveSplitter(widget: QSplitter, key: str) -> None:
|
def saveSplitter(widget: QSplitter, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.SPLITTER, key)
|
key = _qt_state_key(_QtStateKeyKind.SPLITTER, key)
|
||||||
aqt.mw.pm.profile[key] = widget.saveState()
|
aqt.mw.pm.profile[key] = widget.saveState()
|
||||||
|
|
||||||
|
|
||||||
def restoreSplitter(widget: QSplitter, key: str) -> None:
|
def restoreSplitter(widget: QSplitter, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.SPLITTER, key)
|
key = _qt_state_key(_QtStateKeyKind.SPLITTER, key)
|
||||||
if data := aqt.mw.pm.profile.get(key):
|
if data := aqt.mw.pm.profile.get(key):
|
||||||
widget.restoreState(data)
|
widget.restoreState(data)
|
||||||
|
|
||||||
|
|
||||||
def saveHeader(widget: QHeaderView, key: str) -> None:
|
def saveHeader(widget: QHeaderView, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.HEADER, key)
|
key = _qt_state_key(_QtStateKeyKind.HEADER, key)
|
||||||
aqt.mw.pm.profile[key] = widget.saveState()
|
aqt.mw.pm.profile[key] = widget.saveState()
|
||||||
|
|
||||||
|
|
||||||
def restoreHeader(widget: QHeaderView, key: str) -> None:
|
def restoreHeader(widget: QHeaderView, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key = _qt_state_key(_QtStateKeyKind.HEADER, key)
|
key = _qt_state_key(_QtStateKeyKind.HEADER, key)
|
||||||
if state := aqt.mw.pm.profile.get(key):
|
if state := aqt.mw.pm.profile.get(key):
|
||||||
widget.restoreState(state)
|
widget.restoreState(state)
|
||||||
|
|
||||||
|
|
||||||
def save_is_checked(widget: QCheckBox, key: str) -> None:
|
def save_is_checked(widget: QCheckBox, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key += "IsChecked"
|
key += "IsChecked"
|
||||||
aqt.mw.pm.profile[key] = widget.isChecked()
|
aqt.mw.pm.profile[key] = widget.isChecked()
|
||||||
|
|
||||||
|
|
||||||
def restore_is_checked(widget: QCheckBox, key: str) -> None:
|
def restore_is_checked(widget: QCheckBox, key: str) -> None:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
key += "IsChecked"
|
key += "IsChecked"
|
||||||
if aqt.mw.pm.profile.get(key) is not None:
|
if aqt.mw.pm.profile.get(key) is not None:
|
||||||
widget.setChecked(aqt.mw.pm.profile[key])
|
widget.setChecked(aqt.mw.pm.profile[key])
|
||||||
|
@ -847,8 +885,11 @@ def restore_combo_index_for_session(
|
||||||
|
|
||||||
|
|
||||||
def save_combo_history(comboBox: QComboBox, history: list[str], name: str) -> str:
|
def save_combo_history(comboBox: QComboBox, history: list[str], name: str) -> str:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
name += "BoxHistory"
|
name += "BoxHistory"
|
||||||
text_input = comboBox.lineEdit().text()
|
line_edit = comboBox.lineEdit()
|
||||||
|
assert line_edit is not None
|
||||||
|
text_input = line_edit.text()
|
||||||
if text_input in history:
|
if text_input in history:
|
||||||
history.remove(text_input)
|
history.remove(text_input)
|
||||||
history.insert(0, text_input)
|
history.insert(0, text_input)
|
||||||
|
@ -861,14 +902,17 @@ def save_combo_history(comboBox: QComboBox, history: list[str], name: str) -> st
|
||||||
|
|
||||||
|
|
||||||
def restore_combo_history(comboBox: QComboBox, name: str) -> list[str]:
|
def restore_combo_history(comboBox: QComboBox, name: str) -> list[str]:
|
||||||
|
assert aqt.mw.pm.profile is not None
|
||||||
name += "BoxHistory"
|
name += "BoxHistory"
|
||||||
history = aqt.mw.pm.profile.get(name, [])
|
history = aqt.mw.pm.profile.get(name, [])
|
||||||
comboBox.addItems([""] + history)
|
comboBox.addItems([""] + history)
|
||||||
if history:
|
if history:
|
||||||
session_input = aqt.mw.pm.session.get(name)
|
session_input = aqt.mw.pm.session.get(name)
|
||||||
if session_input and session_input == history[0]:
|
if session_input and session_input == history[0]:
|
||||||
comboBox.lineEdit().setText(session_input)
|
line_edit = comboBox.lineEdit()
|
||||||
comboBox.lineEdit().selectAll()
|
assert line_edit is not None
|
||||||
|
line_edit.setText(session_input)
|
||||||
|
line_edit.selectAll()
|
||||||
return history
|
return history
|
||||||
|
|
||||||
|
|
||||||
|
@ -980,7 +1024,7 @@ def send_to_trash(path: Path) -> None:
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# Linux users may not have a trash folder set up
|
# Linux users may not have a trash folder set up
|
||||||
print("trash failure:", path, exc)
|
print("trash failure:", path, exc)
|
||||||
if path.is_dir:
|
if path.is_dir():
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
else:
|
else:
|
||||||
path.unlink()
|
path.unlink()
|
||||||
|
@ -1005,7 +1049,8 @@ def tooltip(
|
||||||
class CustomLabel(QLabel):
|
class CustomLabel(QLabel):
|
||||||
silentlyClose = True
|
silentlyClose = True
|
||||||
|
|
||||||
def mousePressEvent(self, evt: QMouseEvent) -> None:
|
def mousePressEvent(self, evt: QMouseEvent | None) -> None:
|
||||||
|
assert evt is not None
|
||||||
evt.accept()
|
evt.accept()
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
|
@ -1074,7 +1119,7 @@ class MenuList:
|
||||||
print(
|
print(
|
||||||
"MenuList will be removed; please copy it into your add-on's code if you need it."
|
"MenuList will be removed; please copy it into your add-on's code if you need it."
|
||||||
)
|
)
|
||||||
self.children: list[MenuListChild] = []
|
self.children: list[MenuListChild | None] = []
|
||||||
|
|
||||||
def addItem(self, title: str, func: Callable) -> MenuItem:
|
def addItem(self, title: str, func: Callable) -> MenuItem:
|
||||||
item = MenuItem(title, func)
|
item = MenuItem(title, func)
|
||||||
|
@ -1114,6 +1159,7 @@ class SubMenu(MenuList):
|
||||||
|
|
||||||
def renderTo(self, menu: QMenu) -> None:
|
def renderTo(self, menu: QMenu) -> None:
|
||||||
submenu = menu.addMenu(self.title)
|
submenu = menu.addMenu(self.title)
|
||||||
|
assert submenu is not None
|
||||||
super().renderTo(submenu)
|
super().renderTo(submenu)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1124,6 +1170,7 @@ class MenuItem:
|
||||||
|
|
||||||
def renderTo(self, qmenu: QMenu) -> None:
|
def renderTo(self, qmenu: QMenu) -> None:
|
||||||
a = qmenu.addAction(self.title)
|
a = qmenu.addAction(self.title)
|
||||||
|
assert a is not None
|
||||||
qconnect(a.triggered, self.func)
|
qconnect(a.triggered, self.func)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue