diff --git a/app-desktop/src/main/i18n/strings_de.properties b/app-desktop/src/main/i18n/strings_de.properties index 4c420961..c994505a 100644 --- a/app-desktop/src/main/i18n/strings_de.properties +++ b/app-desktop/src/main/i18n/strings_de.properties @@ -67,6 +67,9 @@ messageHandling.autoAnswerSection=Automatische Antwort auf Privatnachrichten messageHandling.autoAnswerText=Antworttext messageHandling.qrgAnswerEnabled=Eine QRG-Anfrage mit der aktuellen Frequenz beantworten messageHandling.qrgAnswerSection=Automatische Antwort auf eine QRG-Anfrage +messageHandling.debugToFileEnabled=Die vollständige Sitzung in eine Datei aufzeichnen +messageHandling.debugToFileHint=Zeichnet den kompletten ON4KST-Sende- und Empfangsverkehr in Messagehistory.raw auf und schreibt zusätzliche Diagnosedetails in kst4contest-errors.log. Anmeldepasswörter werden geschwärzt. Warnungen und Fehler werden immer protokolliert. +messageHandling.diagnosticsSection=Diagnose notification.addCallsignToList=Ein Rufzeichen zur Überwachungsliste hinzufügen notification.addMonitored=Überwachtes Rufzeichen hinzufügen notification.bandUpgradeHint=Auf einen möglichen Bandwechsel hinweisen, wenn ein QSO geloggt wird diff --git a/app-desktop/src/main/i18n/strings_en.properties b/app-desktop/src/main/i18n/strings_en.properties index 8283e188..79d6016e 100644 --- a/app-desktop/src/main/i18n/strings_en.properties +++ b/app-desktop/src/main/i18n/strings_en.properties @@ -76,6 +76,9 @@ messageHandling.autoAnswerSection=Automatic answer to private messages messageHandling.autoAnswerText=Answer text messageHandling.qrgAnswerEnabled=Answer a QRG request with the current frequency messageHandling.qrgAnswerSection=Automatic answer to a QRG request +messageHandling.debugToFileEnabled=Record the whole session to file +messageHandling.debugToFileHint=Records complete ON4KST RX/TX session traffic in Messagehistory.raw and adds diagnostic details to kst4contest-errors.log. Login passwords are redacted. Warnings and errors are always logged. +messageHandling.diagnosticsSection=Diagnostics notification.addCallsignToList=Add a callsign to the monitoring list notification.addMonitored=Add monitored callsign notification.bandUpgradeHint=Hint at a band upgrade when a QSO is logged diff --git a/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java b/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java index e3c4f9c2..b42d52cf 100644 --- a/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java +++ b/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java @@ -3947,6 +3947,23 @@ public class Kst4ContestApplication implements StatusUpdateListener, SettingsHos // intentionally empty: no JavaFX text field left to follow } + @Override + public void applyDebugModeToFile(boolean enabled) { + /* + * The preference itself is written by the settings tab. What only the application + * can do is open and close the error-log file handler and the recorder, in the + * order the JavaFX checkbox kept: on the way up the log opens before the recorder + * starts, on the way down the recorder stops before the log closes. + */ + if (enabled) { + setDebugFileLoggingEnabled(true); + chatcontroller.setMessageHistoryRecordingEnabled(true); + } else { + chatcontroller.setMessageHistoryRecordingEnabled(false); + setDebugFileLoggingEnabled(false); + } + } + /** * The worked-stations rows are a snapshot the tab takes from the roster itself, so * there is nothing for this class to redraw. The JavaFX table needed an explicit diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt index 64d75b80..e4cb6a10 100644 --- a/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt @@ -65,6 +65,15 @@ interface SettingsHost { /** Attaches or detaches the follower that mirrors the own QRG into the station field. */ fun applyOwnQrgFollower(enabled: Boolean) + /** + * Turns file recording of the whole session on or off, with the history recorder. + * + * Lives here and not on the controller because enabling it opens the error-log file + * handler, which the application owns. The order — log before recorder when enabling, + * recorder before log when disabling — is the one the JavaFX checkbox kept. + */ + fun applyDebugModeToFile(enabled: Boolean) + /** Re-reads the worked-stations table for display. */ fun refreshWorkedStationsView() @@ -202,7 +211,7 @@ fun buildSettingsTabs( SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabNotification }) { NotificationTab(notificationState, reportRefusal) }, SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabShortcuts }) { ShortcutsTab(shortcutsState, reportRefusal) }, SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabBeacon }) { BeaconTab(beaconState, reportRefusal) }, - SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabMessageHandling }) { MessageHandlingTab(MessageHandlingTabState(prefs)) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabMessageHandling }) { MessageHandlingTab(MessageHandlingTabState(prefs, host::applyDebugModeToFile)) }, /* * Selecting this tab re-read the database in the JavaFX window; the list is a * snapshot and would otherwise show what was true when the window opened. diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt index e757e8cb..f89ed4ac 100644 --- a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt @@ -3,6 +3,8 @@ package kst4contest.view.compose.tabs import kst4contest.view.i18n.LocalStrings import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -29,5 +31,16 @@ fun MessageHandlingTab(state: MessageHandlingTabState) { state.autoAnswerToQRGRequestEnabled, ) { state.autoAnswerToQRGRequestEnabled = it } } + + Form.section(strings.messageHandlingDiagnosticsSection) { + Form.check( + strings.messageHandlingDebugToFileEnabled, + state.debugModeToFileEnabled, + ) { state.debugModeToFileEnabled = it } + Text( + strings.messageHandlingDebugToFileHint, + style = MaterialTheme.typography.bodySmall, + ) + } } } diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt index baf604fe..ff4e61bc 100644 --- a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt @@ -11,7 +11,10 @@ import kst4contest.model.ChatPreferences * that: a tab that wrote only the main category would leave the second chat on its * previous value, which no part of the window ever displayed. */ -class MessageHandlingTabState(private val prefs: ChatPreferences) { +class MessageHandlingTabState( + private val prefs: ChatPreferences, + private val applyDebugModeToFile: (Boolean) -> Unit = {}, +) { /** Drives both category flags, as the single JavaFX checkbox did. */ var autoAnswerEnabled: Boolean @@ -33,4 +36,16 @@ class MessageHandlingTabState(private val prefs: ChatPreferences) { var autoAnswerToQRGRequestEnabled: Boolean get() = prefs.isMessageHandling_autoAnswerToQRGRequestEnabled() set(value) { prefs.setMessageHandling_autoAnswerToQRGRequestEnabled(value) } + + /** + * Records the whole session to file. Beyond the preference it opens or closes the + * error-log handler and the history recorder, which only the application can sequence; + * [applyDebugModeToFile] carries that out in the order the JavaFX checkbox kept. + */ + var debugModeToFileEnabled: Boolean + get() = prefs.isMessageHandling_debugModeToFileEnabled() + set(value) { + prefs.setMessageHandling_debugModeToFileEnabled(value) + applyDebugModeToFile(value) + } }