Skip to content

Commit

Permalink
Separate settings for checker dialogs
Browse files Browse the repository at this point in the history
Suspects-only  and Sort method are now stored for
each checker dialog.
  • Loading branch information
windymilla committed Dec 31, 2024
1 parent 4a5553c commit 66b28fb
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 50 deletions.
5 changes: 2 additions & 3 deletions src/guiguts/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import unicodedata
import webbrowser

from guiguts.checkers import CheckerSortType
from guiguts.data import themes
from guiguts.file import File, the_file, NUM_RECENT_FILES
from guiguts.footnotes import footnote_check, FootnoteIndexStyle
Expand Down Expand Up @@ -354,8 +353,8 @@ def initialize_preferences(self) -> None:
preferences.set_default(PrefKey.WFDIALOG_IGNORE_CASE, False)
preferences.set_default(PrefKey.WFDIALOG_DISPLAY_TYPE, WFDisplayType.ALL_WORDS)
preferences.set_default(PrefKey.WFDIALOG_SORT_TYPE, WFSortType.ALPHABETIC)
preferences.set_default(PrefKey.CHECKERDIALOG_SORT_TYPE, CheckerSortType.ROWCOL)
preferences.set_default(PrefKey.CHECKERDIALOG_SUSPECTS_ONLY, False)
preferences.set_default(PrefKey.CHECKERDIALOG_SORT_TYPE_DICT, {})
preferences.set_default(PrefKey.CHECKERDIALOG_SUSPECTS_ONLY_DICT, {})
preferences.set_default(PrefKey.WFDIALOG_ITALIC_THRESHOLD, ["4"])
preferences.set_default(PrefKey.WFDIALOG_REGEX, [])
preferences.set_default(
Expand Down
45 changes: 31 additions & 14 deletions src/guiguts/checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@

from guiguts.maintext import maintext
from guiguts.mainwindow import ScrolledReadOnlyText
from guiguts.preferences import (
PersistentString,
PersistentBoolean,
PrefKey,
preferences,
)
from guiguts.preferences import PrefKey
from guiguts.root import root
from guiguts.utilities import (
IndexRowCol,
Expand Down Expand Up @@ -151,11 +146,22 @@ def __init__(
self.count_label.grid(row=0, column=0, sticky="NSW")
self.suspects_only_btn: Optional[ttk.Checkbutton]
if show_suspects_only:
# Can't use a PersistentBoolean directly, since we save this value for each checker dialog
suspects_only_var = tk.BooleanVar(
self, self.get_dialog_pref(PrefKey.CHECKERDIALOG_SUSPECTS_ONLY_DICT)
)

def suspects_only_changed() -> None:
self.save_dialog_pref(
PrefKey.CHECKERDIALOG_SUSPECTS_ONLY_DICT, suspects_only_var.get()
)
self.display_entries()

self.suspects_only_btn = ttk.Checkbutton(
left_frame,
text="Suspects Only",
variable=PersistentBoolean(PrefKey.CHECKERDIALOG_SUSPECTS_ONLY),
command=self.display_entries,
variable=suspects_only_var,
command=suspects_only_changed,
takefocus=False,
)
self.suspects_only_btn.grid(row=0, column=1, sticky="NSW", padx=(10, 0))
Expand All @@ -174,19 +180,30 @@ def copy_errors() -> None:
left_frame,
text="Sort:",
).grid(row=0, column=3, sticky="NSE", padx=5)
sort_type = PersistentString(PrefKey.CHECKERDIALOG_SORT_TYPE)

# Can't use a PersistentString directly, since we save this value for each checker dialog
sort_type = tk.StringVar(
self,
self.get_dialog_pref(PrefKey.CHECKERDIALOG_SORT_TYPE_DICT)
or CheckerSortType.ROWCOL,
)

def sort_type_changed() -> None:
self.save_dialog_pref(PrefKey.CHECKERDIALOG_SORT_TYPE_DICT, sort_type.get())
self.display_entries()

ttk.Radiobutton(
left_frame,
text="Line & Col",
command=self.display_entries,
command=sort_type_changed,
variable=sort_type,
value=CheckerSortType.ROWCOL,
takefocus=False,
).grid(row=0, column=4, sticky="NSE", padx=2)
ttk.Radiobutton(
left_frame,
text="Alpha/Type",
command=self.display_entries,
command=sort_type_changed,
variable=sort_type,
value=CheckerSortType.ALPHABETIC,
takefocus=False,
Expand Down Expand Up @@ -486,7 +503,7 @@ def display_entries(self, auto_select_line: bool = True) -> None:
Busy.busy()
sort_key: Callable[[CheckerEntry], tuple]
if (
preferences.get(PrefKey.CHECKERDIALOG_SORT_TYPE)
self.get_dialog_pref(PrefKey.CHECKERDIALOG_SORT_TYPE_DICT)
== CheckerSortType.ALPHABETIC
):
sort_key = self.alpha_key
Expand Down Expand Up @@ -589,8 +606,8 @@ def showing_suspects_only(self) -> bool:
Returns: True if there's a Suspects Only button that is switched on.
"""
return self.suspects_only_btn is not None and preferences.get(
PrefKey.CHECKERDIALOG_SUSPECTS_ONLY
return self.suspects_only_btn is not None and self.get_dialog_pref(
PrefKey.CHECKERDIALOG_SUSPECTS_ONLY_DICT
)

def skip_suspect_entry(self, entry: CheckerEntry) -> bool:
Expand Down
56 changes: 34 additions & 22 deletions src/guiguts/illo_sn_fixup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

logger = logging.getLogger(__package__)

_the_illosn_checker: Optional["IlloSNChecker"] = None # pylint: disable=invalid-name
_the_illo_checker: Optional["IlloSNChecker"] = None # pylint: disable=invalid-name
_the_sn_checker: Optional["IlloSNChecker"] = None # pylint: disable=invalid-name


class IlloSNRecord:
Expand Down Expand Up @@ -96,9 +97,8 @@ def get_selected_illosn_record(
Line number index of first line of the record; e.g. '5.0'
Line number index of last line of the record; e.g. '6.14'
"""
assert _the_illosn_checker is not None
# We built a list of Illo or SN records with start/end RowCol details.
records = _the_illosn_checker.get_illosn_records()
records = self.get_illosn_records()
# Get record of the selected tag
selected_record = records[selected_illosn_index]
# Get line number index of the first line of the selected record.
Expand All @@ -116,14 +116,13 @@ def get_selected_illosn_index(self) -> int:
Returns:
Index into self.illosn_records array, negative if none selected."""
assert _the_illosn_checker is not None
cur_idx = self.checker_dialog.current_entry_index()
if cur_idx is None:
return -1
text_range = self.checker_dialog.entries[cur_idx].text_range
assert text_range is not None
illosn_start = text_range.start
illosn_records = _the_illosn_checker.get_illosn_records()
illosn_records = self.get_illosn_records()
for illosn_index, illosn_record in enumerate(illosn_records):
if illosn_record.start == illosn_start:
return illosn_index
Expand Down Expand Up @@ -286,7 +285,7 @@ def update_after_move(self, tag_type: str, selected_illosn_index: int) -> None:
# Update illosn_records list
self.run_check(tag_type)
# Update dialog
display_illosn_entries()
display_illosn_entries(tag_type)
# Select again the tag we have just moved so it is highlighted.
self.checker_dialog.select_entry_by_index(selected_illosn_index)

Expand Down Expand Up @@ -414,7 +413,6 @@ def move_selection_up(self, tag_type: str) -> None:
Args:
tag_type: a string which is either "Sidenote" or "Illustration".
"""
assert _the_illosn_checker is not None
selected_illosn_index = self.get_selected_illosn_index()
if selected_illosn_index < 0:
return # No selection.
Expand Down Expand Up @@ -503,7 +501,6 @@ def move_selection_down(self, tag_type: str) -> None:
Args:
tag_type: a string which is either "Sidenote" or "Illustration".
"""
assert _the_illosn_checker is not None
selected_illosn_index = self.get_selected_illosn_index()
if selected_illosn_index < 0:
return # No selection
Expand Down Expand Up @@ -587,7 +584,8 @@ def illosn_check(tag_type: str) -> None:
Args:
tag_type: which tag to check for - "Illustration" or "Sidenote"
"""
global _the_illosn_checker
global _the_illo_checker
global _the_sn_checker

if not tool_save():
return
Expand All @@ -598,10 +596,18 @@ def illosn_check(tag_type: str) -> None:
rerun_command=lambda: illosn_check(tag_type),
show_suspects_only=True,
)
if _the_illosn_checker is None:
_the_illosn_checker = IlloSNChecker(checker_dialog)
elif not _the_illosn_checker.checker_dialog.winfo_exists():
_the_illosn_checker.checker_dialog = checker_dialog
if tag_type == "Illustration":
if _the_illo_checker is None:
_the_illo_checker = IlloSNChecker(checker_dialog)
elif not _the_illo_checker.checker_dialog.winfo_exists():
_the_illo_checker.checker_dialog = checker_dialog
the_checker = _the_illo_checker
else:
if _the_sn_checker is None:
_the_sn_checker = IlloSNChecker(checker_dialog)
elif not _the_sn_checker.checker_dialog.winfo_exists():
_the_sn_checker.checker_dialog = checker_dialog
the_checker = _the_sn_checker

ToolTip(
checker_dialog.text,
Expand All @@ -620,23 +626,29 @@ def illosn_check(tag_type: str) -> None:
ttk.Button(
frame,
text="Move Selection Up",
command=lambda: _the_illosn_checker.move_selection_up(tag_type),
command=lambda: the_checker.move_selection_up(tag_type),
).grid(column=0, row=0, sticky="NSW")
ttk.Button(
frame,
text="Move Selection Down",
command=lambda: _the_illosn_checker.move_selection_down(tag_type),
command=lambda: the_checker.move_selection_down(tag_type),
).grid(column=1, row=0, sticky="NSW")
_the_illosn_checker.run_check(tag_type)
display_illosn_entries()
the_checker.run_check(tag_type)
display_illosn_entries(tag_type)


def display_illosn_entries() -> None:
"""(Re-)display the requested Illo/SN tag types in the checker dialog."""
assert _the_illosn_checker is not None
checker_dialog = _the_illosn_checker.checker_dialog
def display_illosn_entries(tag_type: str) -> None:
"""(Re-)display the requested Illo/SN tag types in the checker dialog.
Args:
tag_type: which tag to check for - "Illustration" or "Sidenote"
"""
assert tag_type in ("Illustration", "Sidenote")
the_checker = _the_illo_checker if tag_type == "Illustration" else _the_sn_checker
assert the_checker is not None
checker_dialog = the_checker.checker_dialog
checker_dialog.reset()
illosn_records = _the_illosn_checker.get_illosn_records()
illosn_records = the_checker.get_illosn_records()
for illosn_record in illosn_records:
error_prefix = ""
if illosn_record.mid_para:
Expand Down
4 changes: 2 additions & 2 deletions src/guiguts/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class PrefKey(StrEnum):
WFDIALOG_SORT_TYPE = auto()
WFDIALOG_ITALIC_THRESHOLD = auto()
WFDIALOG_REGEX = auto()
CHECKERDIALOG_SORT_TYPE = auto()
CHECKERDIALOG_SUSPECTS_ONLY = auto()
CHECKERDIALOG_SORT_TYPE_DICT = auto()
CHECKERDIALOG_SUSPECTS_ONLY_DICT = auto()
DIALOG_GEOMETRY = auto()
ROOT_GEOMETRY = auto()
ROOT_GEOMETRY_STATE = auto()
Expand Down
43 changes: 34 additions & 9 deletions src/guiguts/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,7 @@ def _get_pref_geometry(self) -> str:
Returns:
String containing geometry, or empty string if none stored.
"""
config_dict = preferences.get(PrefKey.DIALOG_GEOMETRY)
try:
return config_dict[self.__class__.__name__]
except KeyError:
return ""
return self.get_dialog_pref(PrefKey.DIALOG_GEOMETRY)

def allow_geometry_save(self) -> None:
"""Enable the saving of geometry changes via Configure events.
Expand Down Expand Up @@ -274,12 +270,41 @@ def _save_config(self) -> None:
dialog creation and resizing. Only the first will actually
do a save, because the flag will only be true on the first call."""
if self.save_config:
config_dict = preferences.get(PrefKey.DIALOG_GEOMETRY)
key = self.__class__.__name__
config_dict[key] = self.geometry()
preferences.set(PrefKey.DIALOG_GEOMETRY, config_dict)
self.save_dialog_pref(PrefKey.DIALOG_GEOMETRY, self.geometry())
self.save_config = False

def save_dialog_pref(self, key: PrefKey, value: Any) -> None:
"""Save a preference that is unique to the dialog class.
Dictionary indexed by classname is saved in the prefs file,
so a preference can be saved per dialog.
Args:
key: Preference to be saved.
value: New value for preference.
"""
config_dict = preferences.get(key)
config_dict[self.__class__.__name__] = value
preferences.set(key, config_dict)

def get_dialog_pref(self, key: PrefKey) -> Any:
"""Get a preference that is unique to the dialog class.
Dictionary in prefs file is indexed by classname,
so a preference can be obtained per dialog.
Args:
key: Preference to be fetched.
Returns:
Preference value.
"""
config_dict = preferences.get(key)
try:
return config_dict[self.__class__.__name__]
except KeyError:
return None


class OkApplyCancelDialog(ToplevelDialog):
"""A ToplevelDialog with OK, Apply & Cancel buttons."""
Expand Down

0 comments on commit 66b28fb

Please sign in to comment.