diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 270421f1..13ed3106 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -52,7 +52,7 @@ JavaFX ObservableList / UI state ## Configuration and Layout Persistence -- The current `preferences.xml` configuration version is 7. Version 6 introduced optional managed leaf-column widths below `guiOptions`, identified by stable table and column IDs. Parent-column widths remain derived from their leaf columns. +- Configuration and layout live in the `preferences.xml` of the **active operator profile**; see "Operator Profiles and Per-Profile Persistence" below. The current `preferences.xml` configuration version is 7. Version 6 introduced optional managed leaf-column widths below `guiOptions`, identified by stable table and column IDs. Parent-column widths remain derived from their leaf columns. - `GUIstationMapClusteringEnabled` is a layout preference below `guiOptions`. It defaults to `true`, is selectively autosaved and controls only screen-based clustering of nearby map markers. Missing or malformed values retain the enabled default for backward compatibility. - Stored widths take precedence. Without a usable entry, a managed column is sized once when meaningful table data first becomes available. Message and similar free-text columns use a flexible initial width instead of following the longest value. - Main-window and separate-monitor DXCluster/QSO tables use distinct layout IDs even though they share the underlying message stores. @@ -61,6 +61,27 @@ JavaFX ObservableList / UI state - Full and selective writes are synchronized and replace `preferences.xml` atomically. Missing, unknown or malformed width entries do not prevent loading and fall back to initial sizing. - Older configuration files require no migration. Older KST4Contest versions can ignore the additional elements; a complete rewrite by such a version may discard column widths without invalidating the remaining file. +## Operator Profiles and Per-Profile Persistence + +- One operator profile owns one `preferences.xml` and one worked-station database. Everything else under `~/.praktiKST/` stays global: CSS, audio files, DEM and terrain packages, the error log and the version-info feed. +- The **root profile** is the historic flat installation: `preferences.xml` and `praktiKST.db` directly below the application directory. It is never moved, and it always uses the common station database, because that database is the installation's own. +- Additional profiles live under `profiles//`. `profileId` is a stable, file-system-safe slug assigned once; renaming a profile changes only its display name and never moves a directory. +- The registry `profiles.xml` is created lazily. An installation that has only the flat layout gets no registry and no `profiles/` directory; the root profile is synthesised in memory. Startup with no or exactly one profile therefore asks nothing and writes nothing, and a downgrade to an older release is a no-op. +- The registry stores `profileId`, `displayName`, `rootProfile` and `sharedWorkedDatabase`, never a path. Both file names are derived in `OperatorProfilePaths` alone, so a stored path cannot drift apart from the flag that produced it. +- `sharedWorkedDatabase` resolves to a path, not to a schema change: a sharing profile points at the flat `praktiKST.db`, an owning profile at its own file. There is no owner column, and no SQL statement in `DBController` knows about profiles. +- A profile database is created **empty**. The bundled `/praktiKST.db` resource carries several thousand foreign callsigns and `user_version = 0`; seeding an additional profile from it would show a new operator foreign data and trigger the full callsign-normalization rebuild. Only the root installation is seeded from the resource. `preferences.xml` of a new profile *is* seeded from `/praktiKSTpreferences.xml`, because its defaults are what a first installation gets. +- Worked-state semantics are unchanged and now apply per database file: normalized base callsign as key, worked state shared across suffix variants, three-day expiry, manual reset. +- `stn_loginCallSign` and `stn_loginCallSignRaw` default to empty. The preferences reader treats an empty element as "not set" and falls back to the field default, so a non-empty default would make a profile created without credentials come up carrying a compiled-in callsign. +- Passwords remain plaintext per profile. Profiles separate configuration; they are explicitly not an access-control boundary. This is documented in both manuals. + +### Runtime profile switching + +- A switch tears the current runtime down through `Kst4ContestApplication.shutdownRuntime()` and builds a **new** `Kst4ContestApplication` instance. Reusing the instance is not possible: many controls are inline-initialised instance fields, so a second `start()` would re-parent mounted nodes and register every listener twice. The approach is only sound because the class holds no mutable static state. +- `Platform.setImplicitExit(false)` is required, because closing every window during a switch would otherwise end the process. All exits therefore run through `ApplicationRuntimeLauncher.exitApplication()`, including the main window's close handler; JavaFX calls `stop()` only on the instance it launched itself. +- `shutdownRuntime()` is idempotent and must release everything that outlives a disconnect: the ON4KST supervisor thread, the sked reminder scheduler, the reachability executor, the PSTRotator retry scheduler, the map tile proxy, the station map bridge listeners and its coalescing animation, both view timers and every owned stage. Several of these were real leaks before; they only became visible once a second runtime could exist. +- `ApplicationConstants.sessionRuntimeUniqueId` must not be regenerated during a switch, so UDP readers started earlier still recognise their own poison pill. +- The layout autosave is flushed and then cancelled before a switch, so a pending debounced write cannot land after the profile changed. + ## External Interfaces Treat current implementation/tests and authoritative upstream documentation as source of truth before modifying any interface. diff --git a/github_docs/de-Changelog.md b/github_docs/de-Changelog.md index 622bb446..531ae147 100644 --- a/github_docs/de-Changelog.md +++ b/github_docs/de-Changelog.md @@ -8,6 +8,39 @@ Die veröffentlichten Stable-Versionen und ihre Programmpakete stehen unter [Git --- +## v1.50 (in Entwicklung) + +**Operator-Profile** + +Mehrere Operateure an einem Rechner können jetzt eigene Rufzeichen, Locators und Layouts verwenden, ohne sich gegenseitig die Konfiguration zu überschreiben. Damit ist [Issue #57](https://github.com/praktimarc/kst4contest/issues/57) umgesetzt. + +### Neu + +- **Operator-Profile:** Jedes Profil hat seine eigene `preferences.xml` und damit eigene fachliche Einstellungen und einen eigenen Layoutstand. Verwaltet werden Profile im neuen Reiter **Profiles** des Einstellungsfensters: anlegen, duplizieren, umbenennen, löschen und aktivieren. + +- **Gemeinsame oder eigene gearbeitete Stationen:** Pro Profil wird entschieden, ob es eine eigene Worked-Datenbank bekommt oder die gemeinsame Stationsdatenbank benutzt. Eine Multi-OP-Station mit einem einzigen Stationslog teilt den Worked-Status, zwei OMs mit verschiedenen Rufzeichen an einem Rechner trennen ihn. + +- **Profilwahl beim Start:** Mit nur einem Profil fragt KST4Contest beim Start nichts und verhält sich unverändert. Ab zwei Profilen erscheint eine kleine Auswahl mit vorausgewähltem letzten Profil; Enter oder Doppelklick starten sofort. Der Aufrufparameter `--profile=` überspringt die Auswahl. + +- **Profilwechsel im laufenden Betrieb:** **File → Switch operator profile...** trennt die Verbindung und baut die Oberfläche mit den Einstellungen des gewählten Profils neu auf, ohne Programmneustart. + +### Geändert + +- **Rufzeichen-Vorgabe ist leer:** Fehlt in der `preferences.xml` ein Login-Rufzeichen, bleibt das Feld jetzt leer, statt auf ein im Programm hinterlegtes Rufzeichen zurückzufallen. Ein neu angelegtes Profil startet damit bewusst ohne Anmeldedaten. + +### Behoben + +- **Freigegebene Hintergrundressourcen:** Der ON4KST-Überwachungsthread, der Sked-Erinnerungs-Scheduler, der Reachability-Executor, der PSTRotator-Wiederholungs-Scheduler und der Kachel-Proxy der Karte werden beim Schließen des Chatcontrollers freigegeben. Bisher liefen sie bis zum Programmende weiter. + +### Hinweise zur Aktualisierung + +- Bestehende Installationen werden **nicht** verändert: `preferences.xml` und `praktiKST.db` bleiben genau dort liegen, wo sie sind, und werden zum Profil **Default**. Es wird keine Datei verschoben oder kopiert. +- Eine Profil-Registry entsteht erst beim Anlegen des zweiten Profils. Wer nur ein Profil benutzt, merkt von der Änderung nichts. +- Eine Rückkehr zu einer älteren KST4Contest-Version bleibt möglich; sie findet ihre Dateien unverändert vor. +- Passwörter stehen weiterhin im Klartext in der `preferences.xml` des jeweiligen Profils. Profile trennen die Konfiguration, sie sind kein Zugriffsschutz. + +--- + ## v1.43.1 (2026-09-03) **Korrigierte Versionsmetadaten** diff --git a/github_docs/de-Konfiguration.md b/github_docs/de-Konfiguration.md index 89e454a8..62a6e001 100644 --- a/github_docs/de-Konfiguration.md +++ b/github_docs/de-Konfiguration.md @@ -878,6 +878,59 @@ Anzeige und Herleitung: [Gearbeitete Rufzeichen, neue Bänder und neue Großfeld --- +## Operator-Profile (ab v1.50) + +Mehrere Operateure an einem Rechner brauchen unterschiedliche Rufzeichen, Locators und Layouts. Ein Operator-Profil bündelt genau das: **jedes Profil hat seine eigene `preferences.xml` und damit seine eigenen fachlichen Einstellungen und seinen eigenen Layoutstand.** + +### Wo die Profile liegen + +| Profil | Einstellungen | Gearbeitete Stationen | +|---|---|---| +| **Default** | `~/.praktiKST/preferences.xml` | `~/.praktiKST/praktiKST.db` | +| weitere Profile | `~/.praktiKST/profiles//preferences.xml` | je nach Einstellung gemeinsam oder `~/.praktiKST/profiles//praktiKST.db` | + +Unter Windows entsprechend unterhalb von `%USERPROFILE%\.praktiKST\`. + +Das Profil **Default** benutzt weiterhin genau die Dateien, die eine bestehende Installation schon hat. **Bei der Aktualisierung auf v1.50 wird keine Datei verschoben, kopiert oder umgeschrieben.** Wer eine ältere KST4Contest-Version wieder installiert, findet seine Konfiguration und seine gearbeiteten Stationen unverändert vor. + +### Gemeinsame oder eigene gearbeitete Stationen + +Beim Anlegen eines Profils wird entschieden, woher dessen Worked-, NOT-QRV- und Großfeld-Daten kommen: + +- **Eigene gearbeitete Stationen** (Vorgabe): Das Profil bekommt eine eigene, zunächst leere Datenbank. Sinnvoll, wenn sich zwei OMs mit verschiedenen Rufzeichen einen Rechner teilen. +- **Gemeinsame Stationsdatenbank**: Das Profil benutzt `~/.praktiKST/praktiKST.db`, also dieselbe Datenbank wie das Profil **Default**. Das ist der Fall der **Multi-OP-Station**: es gibt nur ein Stationslog, also soll auch der Worked-Status für alle Operateure derselbe sein. + +Ein Wechsel zwischen beiden Einstellungen verschiebt keine Daten. Bereits gesammelte Worked-Daten bleiben dort liegen, wo sie entstanden sind. Der Drei-Tage-Ablauf und die Reset-Schaltfläche wirken jeweils auf die Datenbank des gerade aktiven Profils. + +### Profile verwalten + +Der Reiter **Profiles** im Einstellungsfenster zeigt alle Profile mit Name, Art der Worked-Daten und letzter Benutzung. + +- **New profile...** legt ein Profil an. Es startet **ohne Rufzeichen und ohne Passwort**; beides wird anschließend im Reiter **Station** eingetragen. +- **Duplicate...** übernimmt die komplette Konfiguration des gewählten Profils — Antenne, Locator, Layout, Beacon, Integrationen — **außer Rufzeichen und Passwort**. Gearbeitete Stationen werden nie mitkopiert. +- **Rename...** ändert nur den angezeigten Namen. Verzeichnisse und Dateien bleiben unberührt. +- **Delete...** entfernt das Profilverzeichnis endgültig. Das Profil **Default** und das gerade aktive Profil lassen sich nicht löschen. Bei einem Profil mit gemeinsamer Stationsdatenbank bleibt diese unangetastet. +- **Change worked stations...** schaltet zwischen gemeinsamer und eigener Datenbank um. +- **Switch to selected profile...** wechselt das Profil im laufenden Betrieb. + +### Profilwahl beim Start + +- Solange nur **ein** Profil existiert, fragt KST4Contest beim Start **nichts** und startet wie bisher. Es wird auch keine Profil-Registry angelegt. Erst das Anlegen des zweiten Profils erzeugt `~/.praktiKST/profiles.xml`. +- Ab **zwei** Profilen erscheint beim Start eine kleine Auswahl. Das zuletzt benutzte Profil ist vorausgewählt, **Enter** oder ein Doppelklick starten sofort. +- Der Aufrufparameter `--profile=` überspringt die Auswahl und startet direkt das genannte Profil. Erlaubt sind die Profil-ID und der angezeigte Name, Groß- und Kleinschreibung spielen keine Rolle. Ein unbekannter Name führt zu einem Hinweis und danach zur normalen Auswahl — der Start wird nie verweigert. + +### Profil im laufenden Betrieb wechseln + +**File → Switch operator profile...** oder die Schaltfläche im Reiter **Profiles** wechseln ohne Programmneustart. Nach einer Sicherheitsabfrage wird die ON4KST-Verbindung getrennt und die Oberfläche mit den Einstellungen und dem Layout des gewählten Profils neu aufgebaut. Der Layoutstand des bisherigen Profils wird vorher gesichert; noch nicht mit **Save Settings** bestätigte fachliche Änderungen gehen dabei verloren. + +Sobald mehr als ein Profil existiert, zeigt die Titelzeile des Hauptfensters zusätzlich den Profilnamen. + +### Hinweis zu Passwörtern + +Das ON4KST-Passwort steht wie bisher im Klartext in der `preferences.xml` des jeweiligen Profils. Auf einem gemeinsam genutzten Rechner kann jeder, der Zugriff auf das Benutzerkonto hat, die Passwörter aller Profile lesen. Profile trennen die Konfiguration, sie sind **kein** Zugriffsschutz. + +--- + ## Dark Mode (ab v1.26) Der Dark Mode wird über **Windows → Use dark mode design** aktiviert. Mit **Windows → Use default mode design** wird wieder das normale helle Farbschema geladen. diff --git a/github_docs/en-Changelog.md b/github_docs/en-Changelog.md index af1cb47b..a15f4e08 100644 --- a/github_docs/en-Changelog.md +++ b/github_docs/en-Changelog.md @@ -8,6 +8,39 @@ Published Stable versions and their application packages are available under [Gi --- +## v1.50 (in development) + +**Operator profiles** + +Several operators sharing one computer can now use their own callsigns, locators and layouts without overwriting each other's configuration. This implements [Issue #57](https://github.com/praktimarc/kst4contest/issues/57). + +### New + +- **Operator profiles:** every profile has its own `preferences.xml`, and therefore its own settings and its own window layout. Profiles are managed on the new **Profiles** tab of the settings window: create, duplicate, rename, delete and activate. + +- **Shared or own worked stations:** each profile decides whether it gets its own worked database or uses the common station database. A multi operator station with a single station log shares the worked state; two operators with different callsigns on one computer keep it apart. + +- **Choosing a profile at startup:** with only one profile, KST4Contest asks nothing at startup and behaves exactly as before. From two profiles on, a small selection appears with the last used profile preselected; Enter or a double click start immediately. The `--profile=` argument skips the selection. + +- **Switching profiles while running:** **File > Switch operator profile...** closes the connection and rebuilds the user interface with the settings of the selected profile, without restarting the program. + +### Changed + +- **The default login callsign is empty:** if `preferences.xml` has no login callsign, the field now stays empty instead of falling back to a callsign compiled into the program. A newly created profile therefore deliberately starts without credentials. + +### Fixed + +- **Background resources are released:** the ON4KST supervisor thread, the sked reminder scheduler, the reachability executor, the PSTRotator retry scheduler and the map tile proxy are released when the chat controller is closed. They used to keep running until the program ended. + +### Upgrade notes + +- Existing installations are **not** modified: `preferences.xml` and `praktiKST.db` stay exactly where they are and become the **Default** profile. No file is moved or copied. +- A profile registry only appears when the second profile is created. Anyone using a single profile will not notice the change. +- Going back to an older KST4Contest release stays possible; it finds its files unchanged. +- Passwords are still stored in clear text in each profile's `preferences.xml`. Profiles separate configuration; they are not an access control mechanism. + +--- + ## v1.43.1 (2026-09-03) **Corrected version metadata** diff --git a/github_docs/en-Configuration.md b/github_docs/en-Configuration.md index a1a9c373..85c0a55d 100644 --- a/github_docs/en-Configuration.md +++ b/github_docs/en-Configuration.md @@ -935,6 +935,59 @@ Display and derivation: [Worked Callsigns, New Bands and New Grid Squares](en-Fe --- +## Operator Profiles (from v1.50) + +Several operators sharing one computer need different callsigns, locators and layouts. An operator profile bundles exactly that: **every profile has its own `preferences.xml`, and therefore its own settings and its own window layout.** + +### Where the profiles live + +| Profile | Settings | Worked stations | +|---|---|---| +| **Default** | `~/.praktiKST/preferences.xml` | `~/.praktiKST/praktiKST.db` | +| additional profiles | `~/.praktiKST/profiles//preferences.xml` | shared, or `~/.praktiKST/profiles//praktiKST.db` | + +On Windows the same files live below `%USERPROFILE%\.praktiKST\`. + +The **Default** profile keeps using exactly the files an existing installation already has. **Upgrading to v1.50 moves, copies and rewrites nothing.** Anyone reinstalling an older KST4Contest release finds their configuration and their worked stations unchanged. + +### Shared or own worked stations + +When a profile is created you decide where its worked, NOT-QRV and grid data come from: + +- **Own worked stations** (default): the profile gets its own, initially empty database. This is what two operators with different callsigns sharing a private computer want. +- **Common station database**: the profile uses `~/.praktiKST/praktiKST.db`, the same database as the **Default** profile. This is the **multi operator station** case: there is only one station log, so the worked state should be the same for every operator. + +Switching between the two settings moves no data. Worked data already collected stays where it was created. The three day expiry and the reset button always act on the database of the currently active profile. + +### Managing profiles + +The **Profiles** tab in the settings window lists all profiles with their name, the kind of worked data they use and when they were last used. + +- **New profile...** creates a profile. It starts **without callsign and password**; both are entered afterwards on the **Station** tab. +- **Duplicate...** copies the complete configuration of the selected profile - antenna, locator, layout, beacon, integrations - **except callsign and password**. Worked stations are never copied. +- **Rename...** changes the displayed name only. Folders and files are untouched. +- **Delete...** removes the profile folder permanently. The **Default** profile and the currently active profile cannot be deleted. For a profile using the common station database, that database is left untouched. +- **Change worked stations...** switches between the common and an own database. +- **Switch to selected profile...** changes the profile while the application is running. + +### Choosing a profile at startup + +- As long as only **one** profile exists, KST4Contest asks **nothing** at startup and starts exactly as before. No profile registry is created either; only creating the second profile writes `~/.praktiKST/profiles.xml`. +- From **two** profiles on, a small selection appears at startup. The last used profile is preselected, and **Enter** or a double click start immediately. +- The `--profile=` argument skips the selection and starts the named profile directly. Both the profile ID and the displayed name are accepted, case insensitively. An unknown name produces a note and then the normal selection - startup is never refused. + +### Switching profiles while running + +**File > Switch operator profile...**, or the button on the **Profiles** tab, switches without restarting the program. After a confirmation the ON4KST connection is closed and the user interface is rebuilt with the settings and layout of the selected profile. The layout of the previous profile is saved first; settings not yet confirmed with **Save Settings** are lost. + +Once more than one profile exists, the main window title also shows the profile name. + +### A note about passwords + +As before, the ON4KST password is stored in clear text in the `preferences.xml` of each profile. On a shared computer, anyone with access to the user account can read the passwords of all profiles. Profiles separate configuration; they are **not** an access control mechanism. + +--- + ## Dark Mode (from v1.26) Enable Dark Mode through **Windows → Use dark mode design**. Use **Windows → Use default mode design** to restore the normal light colour scheme.