From 2023b2cb28e9f3a5a6d63887efc91e62ccc3f851 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 07:36:27 +0000 Subject: [PATCH] Allow preferences and chat controller to be bound to a file set ChatPreferences gains a constructor taking a preferences file name relative to the application directory, so "profiles/OP2/preferences.xml" is as valid as the historic flat "preferences.xml". A missing file is still seeded from the bundled template, which gives an additional operator the same clean defaults a first installation gets. ChatController gains a constructor that passes both relative file names and the seed flag through to ChatPreferences and DBController. The existing constructors delegate to the historic file names, so nothing changes yet. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm --- .../controller/ChatController.java | 30 +++++++++++++++++-- .../kst4contest/model/ChatPreferences.java | 21 ++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/main/java/kst4contest/controller/ChatController.java b/src/main/java/kst4contest/controller/ChatController.java index dfe9fa17..6e9d0bcd 100644 --- a/src/main/java/kst4contest/controller/ChatController.java +++ b/src/main/java/kst4contest/controller/ChatController.java @@ -2866,9 +2866,35 @@ private ObservableList * @param setOwnChatMemberObject */ public ChatController(ChatMember setOwnChatMemberObject,StatusUpdateListener listener) { + this(setOwnChatMemberObject, + listener, + ChatPreferences.PREFERENCES_FILE, + DBController.DATABASE_FILE, + true); + } + + /** + * Creates a chat controller bound to the files of one operator profile. + * + *

Both file names are resolved below the application directory. This is the only + * place where the active operator profile enters the controller; everything below + * works on the resulting {@link ChatPreferences} and {@link DBController} instances + * without knowing about profiles at all.

+ * + * @param setOwnChatMemberObject chat member object representing the local station + * @param listener callback for thread status updates + * @param preferencesRelativeFileName preferences file name relative to the application directory + * @param workedDatabaseRelativeFileName worked-station database file name relative to the application directory + * @param seedWorkedDatabaseFromResource true to seed a missing database from the bundled template + */ + public ChatController(ChatMember setOwnChatMemberObject, + StatusUpdateListener listener, + String preferencesRelativeFileName, + String workedDatabaseRelativeFileName, + boolean seedWorkedDatabaseFromResource) { super(); - chatPreferences = new ChatPreferences(); + chatPreferences = new ChatPreferences(preferencesRelativeFileName); chatPreferences.readPreferencesFromXmlFile(); // this.statusListener = listener; lstNotify_QSOSniffer_sniffedCallSignList = @@ -2930,7 +2956,7 @@ private ObservableList } }); - dbHandler = new DBController(); + dbHandler = new DBController(workedDatabaseRelativeFileName, seedWorkedDatabaseFromResource); reachabilityService = new ReachabilityService(this); rebuildWorkedGrossFieldCacheFromDatabase(); diff --git a/src/main/java/kst4contest/model/ChatPreferences.java b/src/main/java/kst4contest/model/ChatPreferences.java index 5bcf7ad5..f07015ef 100644 --- a/src/main/java/kst4contest/model/ChatPreferences.java +++ b/src/main/java/kst4contest/model/ChatPreferences.java @@ -79,7 +79,26 @@ public class ChatPreferences { * TODO: delete this from the kst4contest.view/Main.java! */ public ChatPreferences() { - ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, PREFERENCE_RESOURCE, PREFERENCES_FILE); + this(PREFERENCES_FILE); + } + + /** + * Creates preferences bound to one operator profile. + * + *

The file name is resolved below the application directory, so both + * "preferences.xml" for the root installation and "profiles/OP2/preferences.xml" + * for an additional operator profile are valid. A missing file is seeded from the + * bundled template, which gives a new profile the same clean defaults a first-ever + * installation gets.

+ * + * @param applicationRelativeFileName preferences file name relative to the application directory + */ + public ChatPreferences(final String applicationRelativeFileName) { + ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, PREFERENCE_RESOURCE, applicationRelativeFileName); + this.storeAndRestorePreferencesFileName = ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, + applicationRelativeFileName + ); // lstNotify_QSOSniffer_sniffedCallSignList.add("DF0GEB");