Move find_and_replace.py into browser/dialogs

This commit is contained in:
RumovZ 2021-04-13 11:21:36 +02:00
parent 7ee40e3dce
commit 88086596b6
4 changed files with 125 additions and 133 deletions

View file

@ -1,10 +1,13 @@
# Copyright: Ankitects Pty Ltd and contributors # Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from __future__ import annotations from __future__ import annotations
import sys
import aqt
from .browser import Browser from .browser import Browser
from .dialogs import CardInfoDialog, ChangeModel, FindDupesDialog from .dialogs import CardInfoDialog, ChangeModel, FindAndReplaceDialog, FindDupesDialog
from .sidebar import ( from .sidebar import (
SidebarItem, SidebarItem,
SidebarItemType, SidebarItemType,
@ -30,3 +33,7 @@ from .table import (
StatusDelegate, StatusDelegate,
Table, Table,
) )
# aliases for legacy pathnames
sys.modules["aqt.find_and_replace"] = sys.modules["aqt.browser.dialogs"]
aqt.find_and_replace = sys.modules["aqt.browser.dialogs"] # type: ignore

View file

@ -18,12 +18,16 @@ from anki.stats import CardStats
from anki.tags import MARKED_TAG from anki.tags import MARKED_TAG
from anki.utils import ids2str, isMac from anki.utils import ids2str, isMac
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.browser.dialogs import CardInfoDialog, ChangeModel, FindDupesDialog from aqt.browser.dialogs import (
CardInfoDialog,
ChangeModel,
FindAndReplaceDialog,
FindDupesDialog,
)
from aqt.browser.sidebar import SidebarTreeView from aqt.browser.sidebar import SidebarTreeView
from aqt.browser.table import Table from aqt.browser.table import Table
from aqt.editor import Editor from aqt.editor import Editor
from aqt.exporting import ExportDialog from aqt.exporting import ExportDialog
from aqt.find_and_replace import FindAndReplaceDialog
from aqt.main import ResetReason from aqt.main import ResetReason
from aqt.operations.card import set_card_deck, set_card_flag from aqt.operations.card import set_card_deck, set_card_flag
from aqt.operations.collection import undo from aqt.operations.collection import undo

View file

@ -10,14 +10,23 @@ import aqt
from anki.consts import * from anki.consts import *
from anki.models import NotetypeDict from anki.models import NotetypeDict
from anki.notes import NoteId from anki.notes import NoteId
from aqt import gui_hooks 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.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import (
HelpPage, HelpPage,
askUser, askUser,
disable_help_button, disable_help_button,
openHelp, openHelp,
qconnect,
restore_combo_history,
restore_combo_index_for_session,
restore_is_checked,
restoreGeom, restoreGeom,
save_combo_history,
save_combo_index_for_session,
save_is_checked,
saveGeom, saveGeom,
tr, tr,
) )
@ -224,3 +233,103 @@ class CardInfoDialog(QDialog):
def reject(self) -> None: def reject(self) -> None:
saveGeom(self, "revlog") saveGeom(self, "revlog")
return QDialog.reject(self) 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,
)
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,
)
super().accept()
def show_help(self) -> None:
openHelp(HelpPage.BROWSING_FIND_AND_REPLACE)

View file

@ -1,128 +0,0 @@
# 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, QWidget
from aqt.operations.note import find_and_replace
from aqt.operations.tag import find_and_replace_tag
from aqt.qt import QDialog, Qt
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,
)
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,
)
super().accept()
def show_help(self) -> None:
openHelp(HelpPage.BROWSING_FIND_AND_REPLACE)