mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Move find_and_replace.py into browser/dialogs
This commit is contained in:
parent
7ee40e3dce
commit
88086596b6
4 changed files with 125 additions and 133 deletions
|
@ -1,10 +1,13 @@
|
|||
# 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 sys
|
||||
|
||||
import aqt
|
||||
|
||||
from .browser import Browser
|
||||
from .dialogs import CardInfoDialog, ChangeModel, FindDupesDialog
|
||||
from .dialogs import CardInfoDialog, ChangeModel, FindAndReplaceDialog, FindDupesDialog
|
||||
from .sidebar import (
|
||||
SidebarItem,
|
||||
SidebarItemType,
|
||||
|
@ -30,3 +33,7 @@ from .table import (
|
|||
StatusDelegate,
|
||||
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
|
||||
|
|
|
@ -18,12 +18,16 @@ 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, FindDupesDialog
|
||||
from aqt.browser.dialogs import (
|
||||
CardInfoDialog,
|
||||
ChangeModel,
|
||||
FindAndReplaceDialog,
|
||||
FindDupesDialog,
|
||||
)
|
||||
from aqt.browser.sidebar import SidebarTreeView
|
||||
from aqt.browser.table import Table
|
||||
from aqt.editor import Editor
|
||||
from aqt.exporting import ExportDialog
|
||||
from aqt.find_and_replace import FindAndReplaceDialog
|
||||
from aqt.main import ResetReason
|
||||
from aqt.operations.card import set_card_deck, set_card_flag
|
||||
from aqt.operations.collection import undo
|
||||
|
|
|
@ -10,14 +10,23 @@ import aqt
|
|||
from anki.consts import *
|
||||
from anki.models import NotetypeDict
|
||||
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.utils import (
|
||||
HelpPage,
|
||||
askUser,
|
||||
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,
|
||||
)
|
||||
|
@ -224,3 +233,103 @@ class CardInfoDialog(QDialog):
|
|||
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,
|
||||
)
|
||||
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)
|
||||
|
|
|
@ -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)
|
Loading…
Reference in a new issue