split browser dialogs into separate files

This commit is contained in:
Damien Elmes 2021-05-08 15:08:45 +10:00
parent 0b8733032d
commit b887032244
5 changed files with 180 additions and 160 deletions

View File

@ -7,8 +7,9 @@ import sys
import aqt
from .browser import Browser
from .dialogs import CardInfoDialog, ChangeModel, FindAndReplaceDialog
from .previewer import BrowserPreviewer, MultiCardPreviewer, Previewer
# aliases for legacy pathnames
from .change_notetype import ChangeModel
from .sidebar import (
SidebarItem,
SidebarItemType,
@ -35,7 +36,6 @@ from .table import (
Table,
)
# aliases for legacy pathnames
sys.modules["aqt.sidebar"] = sys.modules["aqt.browser.sidebar"]
aqt.sidebar = sys.modules["aqt.browser.sidebar"] # type: ignore
sys.modules["aqt.previewer"] = sys.modules["aqt.browser.previewer"]

View File

@ -13,15 +13,9 @@ from anki.consts import *
from anki.errors import NotFoundError
from anki.lang import without_unicode_isolation
from anki.notes import NoteId
from anki.stats import CardStats
from anki.tags import MARKED_TAG
from anki.utils import ids2str, isMac
from aqt import AnkiQt, gui_hooks
from aqt.browser.dialogs import CardInfoDialog, ChangeModel, FindAndReplaceDialog
from aqt.browser.previewer import BrowserPreviewer as PreviewDialog
from aqt.browser.previewer import Previewer
from aqt.browser.sidebar import SidebarTreeView
from aqt.browser.table import Table
from aqt.editor import Editor
from aqt.exporting import ExportDialog
from aqt.operations.card import set_card_deck, set_card_flag
@ -61,7 +55,14 @@ from aqt.utils import (
skip_if_selection_is_empty,
tr,
)
from aqt.webview import AnkiWebView
from .card_info import CardInfoDialog
from .change_notetype import ChangeModel
from .find_and_replace import FindAndReplaceDialog
from .previewer import BrowserPreviewer as PreviewDialog
from .previewer import Previewer
from .sidebar import SidebarTreeView
from .table import Table
class Browser(QMainWindow):
@ -478,34 +479,7 @@ class Browser(QMainWindow):
if not self.card:
return
info, cs = self._cardInfoData()
reps = self._revlogData(cs)
card_info_dialog = CardInfoDialog(self)
l = QVBoxLayout()
l.setContentsMargins(0, 0, 0, 0)
w = AnkiWebView(title="browser card info")
l.addWidget(w)
w.stdHtml(info + "<p>" + reps, context=card_info_dialog)
bb = QDialogButtonBox(QDialogButtonBox.Close)
l.addWidget(bb)
qconnect(bb.rejected, card_info_dialog.reject)
card_info_dialog.setLayout(l)
card_info_dialog.setWindowModality(Qt.WindowModal)
card_info_dialog.resize(500, 400)
restoreGeom(card_info_dialog, "revlog")
card_info_dialog.show()
def _cardInfoData(self) -> Tuple[str, CardStats]:
cs = CardStats(self.col, self.card)
rep = cs.report(include_revlog=True)
return rep, cs
# legacy - revlog used to be generated here, and some add-ons
# wrapped this function
def _revlogData(self, cs: CardStats) -> str:
return ""
CardInfoDialog(parent=self, mw=self.mw, card=self.card)
# Menu helpers
######################################################################

View File

@ -0,0 +1,39 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from __future__ import annotations
import aqt
from anki.cards import Card
from anki.stats import CardStats
from aqt.qt import *
from aqt.utils import disable_help_button, qconnect, restoreGeom, saveGeom
from aqt.webview import AnkiWebView
class CardInfoDialog(QDialog):
silentlyClose = True
def __init__(self, parent: QWidget, mw: aqt.AnkiQt, card: Card) -> None:
super().__init__(parent)
disable_help_button(self)
cs = CardStats(mw.col, card)
info = cs.report(include_revlog=True)
l = QVBoxLayout()
l.setContentsMargins(0, 0, 0, 0)
w = AnkiWebView(title="browser card info")
l.addWidget(w)
w.stdHtml(info + "<p>", context=self)
bb = QDialogButtonBox(QDialogButtonBox.Close)
l.addWidget(bb)
qconnect(bb.rejected, self.reject)
self.setLayout(l)
self.setWindowModality(Qt.WindowModal)
self.resize(500, 400)
restoreGeom(self, "revlog")
self.show()
def reject(self) -> None:
saveGeom(self, "revlog")
return QDialog.reject(self)

View File

@ -9,9 +9,7 @@ import aqt
from anki.consts import *
from anki.models import NotetypeDict
from anki.notes import NoteId
from aqt import AnkiQt, QWidget, gui_hooks
from aqt.operations.note import find_and_replace
from aqt.operations.tag import find_and_replace_tag
from aqt import QWidget, gui_hooks
from aqt.qt import *
from aqt.utils import (
HelpPage,
@ -19,13 +17,7 @@ from aqt.utils import (
disable_help_button,
openHelp,
qconnect,
restore_combo_history,
restore_combo_index_for_session,
restore_is_checked,
restoreGeom,
save_combo_history,
save_combo_index_for_session,
save_is_checked,
saveGeom,
tr,
)
@ -213,116 +205,3 @@ class ChangeModel(QDialog):
def onHelp(self) -> None:
openHelp(HelpPage.BROWSING_OTHER_MENU_ITEMS)
class CardInfoDialog(QDialog):
silentlyClose = True
def __init__(self, browser: aqt.browser.Browser) -> None:
super().__init__(browser)
self.browser = browser
disable_help_button(self)
def reject(self) -> None:
saveGeom(self, "revlog")
return QDialog.reject(self)
class FindAndReplaceDialog(QDialog):
COMBO_NAME = "BrowserFindAndReplace"
def __init__(
self, parent: QWidget, *, mw: AnkiQt, note_ids: Sequence[NoteId]
) -> None:
super().__init__(parent)
self.mw = mw
self.note_ids = note_ids
self.field_names: List[str] = []
# fetch field names and then show
mw.query_op(
lambda: mw.col.field_names_for_note_ids(note_ids),
success=self._show,
)
def _show(self, field_names: Sequence[str]) -> None:
# add "all fields" and "tags" to the top of the list
self.field_names = [
tr.browsing_all_fields(),
tr.editing_tags(),
] + list(field_names)
disable_help_button(self)
self.form = aqt.forms.findreplace.Ui_Dialog()
self.form.setupUi(self)
self.setWindowModality(Qt.WindowModal)
self._find_history = restore_combo_history(
self.form.find, self.COMBO_NAME + "Find"
)
self.form.find.completer().setCaseSensitivity(Qt.CaseSensitive)
self._replace_history = restore_combo_history(
self.form.replace, self.COMBO_NAME + "Replace"
)
self.form.replace.completer().setCaseSensitivity(Qt.CaseSensitive)
restore_is_checked(self.form.re, self.COMBO_NAME + "Regex")
restore_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")
self.form.field.addItems(self.field_names)
restore_combo_index_for_session(
self.form.field, self.field_names, self.COMBO_NAME + "Field"
)
qconnect(self.form.buttonBox.helpRequested, self.show_help)
restoreGeom(self, "findreplace")
self.show()
self.form.find.setFocus()
def accept(self) -> None:
saveGeom(self, "findreplace")
save_combo_index_for_session(self.form.field, self.COMBO_NAME + "Field")
search = save_combo_history(
self.form.find, self._find_history, self.COMBO_NAME + "Find"
)
replace = save_combo_history(
self.form.replace, self._replace_history, self.COMBO_NAME + "Replace"
)
regex = self.form.re.isChecked()
match_case = not self.form.ignoreCase.isChecked()
save_is_checked(self.form.re, self.COMBO_NAME + "Regex")
save_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")
# tags?
if self.form.field.currentIndex() == 1:
find_and_replace_tag(
parent=self.parentWidget(),
note_ids=self.note_ids,
search=search,
replacement=replace,
regex=regex,
match_case=match_case,
).run_in_background()
else:
# fields
if self.form.field.currentIndex() == 0:
field = None
else:
field = self.field_names[self.form.field.currentIndex() - 2]
find_and_replace(
parent=self.parentWidget(),
note_ids=self.note_ids,
search=search,
replacement=replace,
regex=regex,
field_name=field,
match_case=match_case,
).run_in_background()
super().accept()
def show_help(self) -> None:
openHelp(HelpPage.BROWSING_FIND_AND_REPLACE)

View File

@ -0,0 +1,128 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from __future__ import annotations
from typing import List, Sequence
import aqt
from anki.notes import NoteId
from aqt import AnkiQt
from aqt.operations.note import find_and_replace
from aqt.operations.tag import find_and_replace_tag
from aqt.qt import *
from aqt.utils import (
HelpPage,
disable_help_button,
openHelp,
qconnect,
restore_combo_history,
restore_combo_index_for_session,
restore_is_checked,
restoreGeom,
save_combo_history,
save_combo_index_for_session,
save_is_checked,
saveGeom,
tr,
)
class FindAndReplaceDialog(QDialog):
COMBO_NAME = "BrowserFindAndReplace"
def __init__(
self, parent: QWidget, *, mw: AnkiQt, note_ids: Sequence[NoteId]
) -> None:
super().__init__(parent)
self.mw = mw
self.note_ids = note_ids
self.field_names: List[str] = []
# fetch field names and then show
mw.query_op(
lambda: mw.col.field_names_for_note_ids(note_ids),
success=self._show,
)
def _show(self, field_names: Sequence[str]) -> None:
# add "all fields" and "tags" to the top of the list
self.field_names = [
tr.browsing_all_fields(),
tr.editing_tags(),
] + list(field_names)
disable_help_button(self)
self.form = aqt.forms.findreplace.Ui_Dialog()
self.form.setupUi(self)
self.setWindowModality(Qt.WindowModal)
self._find_history = restore_combo_history(
self.form.find, self.COMBO_NAME + "Find"
)
self.form.find.completer().setCaseSensitivity(Qt.CaseSensitive)
self._replace_history = restore_combo_history(
self.form.replace, self.COMBO_NAME + "Replace"
)
self.form.replace.completer().setCaseSensitivity(Qt.CaseSensitive)
restore_is_checked(self.form.re, self.COMBO_NAME + "Regex")
restore_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")
self.form.field.addItems(self.field_names)
restore_combo_index_for_session(
self.form.field, self.field_names, self.COMBO_NAME + "Field"
)
qconnect(self.form.buttonBox.helpRequested, self.show_help)
restoreGeom(self, "findreplace")
self.show()
self.form.find.setFocus()
def accept(self) -> None:
saveGeom(self, "findreplace")
save_combo_index_for_session(self.form.field, self.COMBO_NAME + "Field")
search = save_combo_history(
self.form.find, self._find_history, self.COMBO_NAME + "Find"
)
replace = save_combo_history(
self.form.replace, self._replace_history, self.COMBO_NAME + "Replace"
)
regex = self.form.re.isChecked()
match_case = not self.form.ignoreCase.isChecked()
save_is_checked(self.form.re, self.COMBO_NAME + "Regex")
save_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")
# tags?
if self.form.field.currentIndex() == 1:
find_and_replace_tag(
parent=self.parentWidget(),
note_ids=self.note_ids,
search=search,
replacement=replace,
regex=regex,
match_case=match_case,
).run_in_background()
else:
# fields
if self.form.field.currentIndex() == 0:
field = None
else:
field = self.field_names[self.form.field.currentIndex() - 2]
find_and_replace(
parent=self.parentWidget(),
note_ids=self.note_ids,
search=search,
replacement=replace,
regex=regex,
field_name=field,
match_case=match_case,
).run_in_background()
super().accept()
def show_help(self) -> None:
openHelp(HelpPage.BROWSING_FIND_AND_REPLACE)