-
-
Notifications
You must be signed in to change notification settings - Fork 1
Architektur Blattschutz
Diese Seite richtet sich an Entwickler, die am Plugin-Code arbeiten. Für die Bedienung des fertigen Plugins siehe Turnieransicht. Diese Seite ist ein Überblick; die vollständige, im Code-Repository gepflegte Referenz (inkl. Named-Ranges-Pflichtregeln beim Registrieren neuer Blattschutz-Konfigurationen und Lebenszyklus-Verhalten bei Sheet-Umbenennung/ -Verschiebung/-Kopie) steht in
turniersysteme/BLATTSCHUTZ.md.
Der Turnier-Modus (Kiosk-Modus) dient der vereinfachten Ergebnis-Erfassung
durch Laien, nicht der Darstellung. Beim Aktivieren werden alle nicht dafür benötigten
Calc-Bedienelemente ausgeblendet; die Sheets des aktiven Turniersystems werden zusätzlich
tab-geschützt. Ausschließlich die für die Erfassung nötigen Zellen bleiben über
CellProtection.IsLocked = false editierbar.
| Klasse | Paket | Zweck |
|---|---|---|
TurnierModus |
toolbar/ |
Orchestriert das Aus-/Einblenden der UI-Elemente (Kiosk-Modus) und stößt den Blattschutz an |
IBlattschutzKonfiguration |
helper/sheet/blattschutz/ |
Interface – eine Implementierung pro Turniersystem |
SheetSchutzInfo |
helper/sheet/blattschutz/ |
Record: Sheet + editierbare Bereiche |
BlattschutzManager |
helper/sheet/blattschutz/ |
Singleton-Orchestrator |
BlattschutzRegistry |
helper/sheet/blattschutz/ |
Registry (Open/Closed Principle) |
TurnierModus.aktivierenIntern() / deaktivierenIntern() delegieren per Registry — kein
if (SUPERMELEE) nötig, neue Systeme werden nur per BlattschutzRegistry.register() eingetragen.
-
zelleStylesAktualisieren(ws)— vor jedemprotect(), sonst LibreOffice-RuntimeException - Sheet ggf. entsperren (
BlattschutzManager.entsperreSheet, idempotent viaXProtectable.isProtected()) - Editierbare Bereiche mit
CellProtection.IsLocked = falsefreigeben XProtectable.protect("")
- Klasse:
com.sun.star.util.CellProtection(nichtsheet!) - Editierbar-Flag:
IsLocked(nichtIsProtected) - Immer den alten Wert lesen, ein neues
CellProtection-Objekt schreiben und dabei alle übrigen Flags (IsHidden,IsFormulaHidden,IsPrintHidden) unverändert übernehmen – nicht einfach ein frisches Objekt nur mitIsLockedsetzen, sonst gehen die anderen Flags verloren
BlattschutzManager bündelt die Pflicht-Reihenfolge pro SheetRunner-Kommando in einem
thread-lokalen, referenzgezählten Scope, damit ein Kommando höchstens ein physisches Entsperren
und garantiert ein abschließendes Schützen auslöst:
| Methode | Zweck |
|---|---|
beginCommandScope(konfig, ws) |
Öffnet den Scope; entsperrt noch nicht |
ensureUnprotectedInScope() |
Entsperrt lazy beim ersten Bedarf; weitere Aufrufe im selben Scope sind No-Ops |
endCommandScope() |
Schließt den äußersten Scope; führt immer ein abschließendes doSchuetzen() aus – auch wenn ensureUnprotectedInScope() nie gefeuert hat |
scopeFuer(TurnierSystem, WorkingSpreadsheet) |
Convenience-AutoCloseable für Aufrufer außerhalb eines SheetRunner (z. B. modale Dialoge im ProtocolHandler-Pfad) |
mitFallbackEntsperrt(sheet, Runnable) |
Physische Absicherung direkt am Schreibpunkt, falls der globale TurnierModus.istAktiv()-Flag vom tatsächlichen Sheet-Zustand abweicht |
Innerhalb eines aktiven Scopes sind die öffentlichen schuetzen()/entsperren()-Aufrufe No-Ops.
Außerhalb eines Scopes wirft ensureUnprotectedInScope() eine IllegalStateException, wenn der
Turnier-Modus aktiv ist — Style-/Conditional-Format-Mutationen müssen also innerhalb eines
SheetRunner.run() bzw. eines scopeFuer(...)-Blocks laufen.
xPropSet.setPropertyValue("ConditionalFormat", xEntries) ruft intern ReplaceConditionalFormat
auf. Bei einem tab-geschützten Sheet kehrt die Methode lautlos ohne Exception zurück — LO hat
aber zuvor bereits alle CF-Daten gelöscht, sodass alle bedingten Formatierungen spurlos
verschwinden.
| Operation | Verhalten bei Sheet-Schutz |
|---|---|
CellStyleHelper.apply() (Styles) |
Wirft RuntimeException → gefangen → WARN |
setPropertyValue("ConditionalFormat", ...) |
return; ohne Exception → lautlos, kein Log-Eintrag |
Aktuelles Muster für alle Style-/CF-mutierenden Operationen (ConditionalFormatHelper,
RangeHelper.clearRange/setDataInRange):
BlattschutzManager.get().ensureUnprotectedInScope();
// ... Style-/ConditionalFormat-Mutation ...
// Schützen NICHT hier – passiert automatisch am Ende des umschließenden
// BlattschutzManager.endCommandScope() (bzw. scopeFuer(...)-try-with-resources)BlattschutzManager.mitGlobalenSchutzInfos() ergänzt automatisch das Teilnehmer-Sheet als
vollständig gesperrt — unabhängig von der systemspezifischen IBlattschutzKonfiguration. Eine
neue Konfiguration muss dieses Sheet also nicht separat behandeln.
-
FooBlattschutzKonfiguration implements IBlattschutzKonfigurationinfoo/blattschutz/anlegen — Vorbild:supermelee/blattschutz/SupermeleeBlattschutzKonfiguration.java - In
BlattschutzRegistry, static-Block:REGISTRY.put(TurnierSystem.FOO, FooBlattschutzKonfiguration.get()) - Editierbare Bereiche per
SheetMetadataHelper.findeSheet()+getSchluesselMitPrefix()ermitteln - Zeilengrenzen aus vorhandenen Konstanten übernehmen (z. B.
MeldungenSpalte.MAX_ANZ_MELDUNGEN) — keine Magic Numbers
Einstieg Home Installation Download
Turniersysteme Supermêlée Schweizer System Liga Jeder gegen Jeden K.-O.-System Poule-A/B Maastrichter System Kaskaden-K.O. Formule X Trip-Tête / Trio Kölner Sextet Dänisches System Monrad-System Tête-Series Crazy-Mêlée Arena-Pétanque Systemvergleich
Referenz Turnieransicht Sidebar Konfiguration WhatsApp Webserver Composite Views Webserver-Regie Turnier-Startseite FTP-Server KI-Assistent Siegergeld Planungsrechner Formeln Makros & Formeln Zeitplan-Feature Für Entwickler Entwicklungsumgebung Architektur: Threading Architektur: Blattschutz