mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-09-06 03:20:49 +02:00
Clear every read-only marker when the store becomes writable again
"Erneut prüfen" refreshed the banner but left the window title and the status bar reading "NUR LESEN" -- both were built once and never updated -- while the banner itself asked for a restart that the recheck exists to avoid. Title, status bar and banner are refreshed from one place now, so none of them can be left behind, and the main window owns the title instead of app.py setting it once at startup. The banner points at "Erneut prüfen" and says outright that no restart is needed. Since the startup pass was skipped, its task list is empty rather than current, so a successful recheck offers the housekeeper run that fills it. UI tests cover both directions of the recheck; their Tk root moved into a shared conftest fixture, because a second root in another module invalidates the icon images bound to the first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ae53c168fd
commit
528c24ad42
+34
-22
@@ -105,7 +105,6 @@ class MainWindow(ttk.Frame):
|
||||
# visible no matter which member, asset or housekeeper tab is in front.
|
||||
self.messages = MessageBannerList(self)
|
||||
self.messages.grid(row=1, column=0, sticky="ew", pady=(10, 0))
|
||||
self._refresh_store_messages()
|
||||
self.notebook = ttk.Notebook(self)
|
||||
self.notebook.grid(row=2, column=0, sticky="nsew", pady=(10, 0))
|
||||
self.tabs = TabManager(self.notebook)
|
||||
@@ -128,46 +127,59 @@ class MainWindow(ttk.Frame):
|
||||
ttk.Label(status, textvariable=self.status_var, style="Status.TLabel").grid(
|
||||
row=0, column=0, sticky="w"
|
||||
)
|
||||
store_label = f"STORE {self.repository.root}"
|
||||
if self.repository.read_only:
|
||||
store_label = f"{store_label} · NUR LESEN"
|
||||
ttk.Label(
|
||||
status,
|
||||
text=f"{store_label} · VERSION {__version__}",
|
||||
style="Status.TLabel",
|
||||
).grid(row=0, column=1, sticky="e")
|
||||
self.store_var = tk.StringVar()
|
||||
ttk.Label(status, textvariable=self.store_var, style="Status.TLabel").grid(
|
||||
row=0, column=1, sticky="e"
|
||||
)
|
||||
# Everything that reflects write access is refreshed from one place, so a
|
||||
# store that becomes writable mid-session updates all of it together.
|
||||
self._refresh_store_state()
|
||||
|
||||
def _refresh_store_messages(self) -> None:
|
||||
def _refresh_store_state(self) -> None:
|
||||
"""Window title, status bar and banner all say whether the store can be
|
||||
written to -- they are rebuilt together so none of them can be left behind."""
|
||||
read_only = self.repository.read_only
|
||||
title = f"CCMA · v{__version__}"
|
||||
self.master.title(f"{title} · NUR LESEN (Store schreibgeschützt)" if read_only else title)
|
||||
store_label = f"STORE {self.repository.root}"
|
||||
if read_only:
|
||||
store_label = f"{store_label} · NUR LESEN"
|
||||
self.store_var.set(f"{store_label} · VERSION {__version__}")
|
||||
messages = []
|
||||
if self.repository.read_only:
|
||||
if read_only:
|
||||
messages.append(
|
||||
TabMessage(
|
||||
"warning",
|
||||
"ACHTUNG: Der Mitglieder-Store ist schreibgeschützt eingebunden. "
|
||||
"Alle Daten sind nur lesbar – Änderungen, Dokumente, E-Mails und der "
|
||||
"Hausmeister sind deaktiviert. Zum Bearbeiten den Store mit "
|
||||
"Schreibrechten einbinden und CCMA neu starten.",
|
||||
"Hausmeister sind deaktiviert. Den Store mit Schreibrechten einbinden "
|
||||
"und hier auf „Erneut prüfen“ klicken – ein Neustart ist dafür nicht "
|
||||
"nötig.",
|
||||
MessageAction("Erneut prüfen", self._recheck_store_access),
|
||||
)
|
||||
)
|
||||
self.messages.set_messages(messages)
|
||||
|
||||
def _recheck_store_access(self) -> None:
|
||||
"""Lets the board re-mount the volume without restarting first -- if it came
|
||||
back writable, the notice disappears and the housekeeper works again."""
|
||||
"""Lets the board remount the volume without restarting first -- if it came
|
||||
back writable, every read-only marker goes away and the housekeeper, skipped
|
||||
at startup, can run right away."""
|
||||
if self.repository.refresh_read_only():
|
||||
self._refresh_store_state()
|
||||
self.status_var.set("Der Store ist weiterhin schreibgeschützt.")
|
||||
self._refresh_store_messages()
|
||||
return
|
||||
self._refresh_store_messages()
|
||||
self._refresh_ribbon_icons()
|
||||
self._refresh_store_state()
|
||||
self.status_var.set("Der Store ist wieder beschreibbar.")
|
||||
messagebox.showinfo(
|
||||
# The startup pass was skipped, so the task list is empty rather than current:
|
||||
# offer the run that fills it instead of leaving a misleading dashboard.
|
||||
if messagebox.askyesno(
|
||||
"Store beschreibbar",
|
||||
"Der Mitglieder-Store ist jetzt mit Schreibrechten eingebunden. "
|
||||
"Der Hausmeister wurde beim Start übersprungen und kann nun ausgeführt werden.",
|
||||
"Der Mitglieder-Store ist jetzt mit Schreibrechten eingebunden. Der "
|
||||
"Hausmeister wurde beim Start übersprungen, seine Vorgangsliste ist daher "
|
||||
"noch leer.\n\nJetzt einen Hausmeisterlauf starten?",
|
||||
parent=self,
|
||||
)
|
||||
):
|
||||
self.run_housekeeper()
|
||||
|
||||
def _refuse_read_only(self, action: str) -> bool:
|
||||
if not self.repository.read_only:
|
||||
|
||||
Reference in New Issue
Block a user