Aufgabe 1 (#88): AiFailureMessageTranslator auf public gesetzt, damit der Verlauf-Tab die technischen Fehlermeldungen in benutzerfreundliche deutsche Texte übersetzen kann. Aufgabe 2 (#77): Vollständige Bestandsaufnahme aller interaktiven GUI-Elemente. 13 neue Konstanten in GuiTooltipTexts ergänzt (Provider-Felder, Verarbeitungs- limits, optionale Pfade, Vorschau-Navigation, Prompt-Buttons, Dateiname-Textfeld). Alle fehlenden Tooltips in GuiConfigurationEditorWorkspace, GuiPromptEditorTab, PdfPreviewPane und FileNameEditorPane gesetzt. Hartcodierte Strings in GuiPromptEditorTab durch Konstantenreferenzen ersetzt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+8
@@ -1573,10 +1573,12 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
TextField lockField = boundTextField(
|
||||
editorState.values().runtimeLockFile(),
|
||||
val -> updateValues(editorState.values().withRuntimeLockFile(val)));
|
||||
applyTooltip(lockField, GuiTooltipTexts.PFADE_LOCK_DATEI);
|
||||
|
||||
TextField logDirField = boundTextField(
|
||||
editorState.values().logDirectory(),
|
||||
val -> updateValues(editorState.values().withLogDirectory(val)));
|
||||
applyTooltip(logDirField, GuiTooltipTexts.PFADE_LOG_VERZEICHNIS);
|
||||
|
||||
VBox optionalContent = new VBox(4);
|
||||
optionalContent.setPadding(new Insets(6, 0, 0, 0));
|
||||
@@ -1858,6 +1860,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
val, pState2.model(), pState2.timeoutSeconds(), pState2.apiKey())));
|
||||
Label baseUrlError = createFieldErrorLabel();
|
||||
fieldErrorLabels.put(ns + "baseUrl", baseUrlError);
|
||||
applyTooltip(baseUrlField, GuiTooltipTexts.PROVIDER_BASIS_URL);
|
||||
HBox baseUrlBox = new HBox(4, baseUrlField);
|
||||
HBox.setHgrow(baseUrlField, Priority.ALWAYS);
|
||||
fieldGrid.add(new Label("Basis-URL:"), 0, gridRow);
|
||||
@@ -1866,6 +1869,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
TextField timeoutField = boundTextField(pState.timeoutSeconds(),
|
||||
val -> updateProviderField(family, pState2 -> new GuiProviderConfigurationState(
|
||||
pState2.baseUrl(), pState2.model(), val, pState2.apiKey())));
|
||||
applyTooltip(timeoutField, GuiTooltipTexts.PROVIDER_TIMEOUT);
|
||||
Label timeoutError = createFieldErrorLabel();
|
||||
fieldErrorLabels.put(ns + "timeoutSeconds", timeoutError);
|
||||
fieldGrid.add(new Label("Timeout (Sek.):"), 2, gridRow);
|
||||
@@ -1924,6 +1928,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
val -> updateProviderField(family, pState2 -> new GuiProviderConfigurationState(
|
||||
pState2.baseUrl(), pState2.model(), pState2.timeoutSeconds(),
|
||||
GuiProviderApiKeyState.unresolved(val))));
|
||||
applyTooltip(apiKeyField, GuiTooltipTexts.PROVIDER_API_KEY);
|
||||
Label apiKeyError = createFieldErrorLabel();
|
||||
fieldErrorLabels.put(ns + "apiKey", apiKeyError);
|
||||
Label apiKeyOriginLabel = createApiKeyOriginLabel();
|
||||
@@ -2015,6 +2020,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
TextField maxRetriesField = boundTextField(
|
||||
editorState.values().maxRetriesTransient(),
|
||||
val -> updateValues(editorState.values().withMaxRetriesTransient(val)));
|
||||
applyTooltip(maxRetriesField, GuiTooltipTexts.LIMITS_MAX_RETRIES);
|
||||
grid.add(new Label("Max. Retries:"), 2, row);
|
||||
grid.add(maxRetriesField, 3, row);
|
||||
row++;
|
||||
@@ -2023,6 +2029,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
TextField logLevelField = boundTextField(
|
||||
editorState.values().logLevel(),
|
||||
val -> updateValues(editorState.values().withLogLevel(val)));
|
||||
applyTooltip(logLevelField, GuiTooltipTexts.LIMITS_LOG_LEVEL);
|
||||
grid.add(new Label("Log-Level:"), 0, row);
|
||||
grid.add(logLevelField, 1, row);
|
||||
|
||||
@@ -2032,6 +2039,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
sensitiveCheck.setSelected(sensitive);
|
||||
sensitiveCheck.selectedProperty().addListener((obs, oldVal, newVal) ->
|
||||
updateValues(editorState.values().withLogAiSensitive(Boolean.toString(newVal))));
|
||||
applyTooltip(sensitiveCheck, GuiTooltipTexts.LIMITS_SENSIBLE_KI_AUSGABE);
|
||||
grid.add(new Label(), 2, row);
|
||||
grid.add(sensitiveCheck, 3, row);
|
||||
|
||||
|
||||
+3
-5
@@ -8,7 +8,6 @@ import java.util.function.Function;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiTooltipTexts;
|
||||
import de.gecheckt.pdf.umbenenner.application.port.out.PromptLoadingFailure;
|
||||
import de.gecheckt.pdf.umbenenner.application.port.out.PromptLoadingSuccess;
|
||||
import de.gecheckt.pdf.umbenenner.application.port.out.PromptSaveResult;
|
||||
@@ -245,14 +244,13 @@ public class GuiPromptEditorTab {
|
||||
statusLabel.setStyle("-fx-text-fill: #555555;");
|
||||
|
||||
// Buttons verdrahten
|
||||
saveButton.setTooltip(new Tooltip("Prompt-Datei speichern (atomar, UTF-8)."));
|
||||
saveButton.setTooltip(new Tooltip(GuiTooltipTexts.PROMPT_SPEICHERN));
|
||||
saveButton.setOnAction(e -> requestSave());
|
||||
|
||||
resetButton.setTooltip(new Tooltip("Textfeld mit dem Standard-Prompt-Inhalt befüllen, ohne zu speichern."));
|
||||
resetButton.setTooltip(new Tooltip(GuiTooltipTexts.PROMPT_ZURUECKSETZEN));
|
||||
resetButton.setOnAction(e -> resetToDefault());
|
||||
|
||||
createDefaultButton.setTooltip(new Tooltip(
|
||||
"Standard-Prompt-Datei am konfigurierten Pfad anlegen."));
|
||||
createDefaultButton.setTooltip(new Tooltip(GuiTooltipTexts.PROMPT_STANDARD_ANLEGEN));
|
||||
createDefaultButton.setOnAction(e -> requestCreateDefault());
|
||||
createDefaultButton.setVisible(false);
|
||||
createDefaultButton.setManaged(false);
|
||||
|
||||
+56
@@ -65,6 +65,14 @@ public final class GuiTooltipTexts {
|
||||
public static final String PFADE_PROMPT =
|
||||
"Externe Textdatei mit den KI-Anweisungen.";
|
||||
|
||||
/** Tooltip für das Eingabefeld „Lock-Datei". */
|
||||
public static final String PFADE_LOCK_DATEI =
|
||||
"Pfad zur Lock-Datei, die parallele Instanzen verhindert (optional).";
|
||||
|
||||
/** Tooltip für das Eingabefeld „Log-Verzeichnis". */
|
||||
public static final String PFADE_LOG_VERZEICHNIS =
|
||||
"Verzeichnis für Log-Dateien. Leer = Standardverzeichnis logs/ im Programmverzeichnis.";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Konfigurationstab – Provider
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -77,6 +85,18 @@ public final class GuiTooltipTexts {
|
||||
public static final String PROVIDER_MODELL =
|
||||
"Das konkrete Sprachmodell des gewählten Providers.";
|
||||
|
||||
/** Tooltip für das Eingabefeld „Basis-URL". */
|
||||
public static final String PROVIDER_BASIS_URL =
|
||||
"Basis-URL des KI-Dienstes (z. B. https://api.openai.com/v1).";
|
||||
|
||||
/** Tooltip für das Eingabefeld „Timeout". */
|
||||
public static final String PROVIDER_TIMEOUT =
|
||||
"Zeitlimit für KI-Anfragen in Sekunden.";
|
||||
|
||||
/** Tooltip für das Eingabefeld „API-Key". */
|
||||
public static final String PROVIDER_API_KEY =
|
||||
"API-Schlüssel für den konfigurierten KI-Dienst. Umgebungsvariable hat Vorrang.";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Konfigurationstab – Verarbeitungslimits
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -93,10 +113,26 @@ public final class GuiTooltipTexts {
|
||||
public static final String LIMITS_MAX_TITLE_LENGTH =
|
||||
"Maximale Länge des Dateinamens in Zeichen (ohne Datum und Erweiterung). Gültig: 10–120.";
|
||||
|
||||
/** Tooltip für das Eingabefeld „max.retries.transient". */
|
||||
public static final String LIMITS_MAX_RETRIES =
|
||||
"Maximale Anzahl transienter Wiederholversuche je Dokument (Ganzzahl ≥ 1).";
|
||||
|
||||
/** Tooltip für das Eingabefeld „Log-Level". */
|
||||
public static final String LIMITS_LOG_LEVEL =
|
||||
"Log-Detailstufe (z. B. INFO, DEBUG, WARN). Leer = Standardwert INFO.";
|
||||
|
||||
/** Tooltip für die Checkbox „Sensible KI-Ausgabe". */
|
||||
public static final String LIMITS_SENSIBLE_KI_AUSGABE =
|
||||
"Vollständige KI-Antworten in die Log-Datei schreiben (nur für Diagnosezwecke empfohlen).";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Verarbeitungslauf-Tab – Dateiname-Editor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Tooltip für das Dateiname-Textfeld im Dateiname-Editor. */
|
||||
public static final String DATEINAME_TEXTFELD =
|
||||
"Dateiname bearbeiten. Format: JJJJ-MM-TT - Titel.pdf";
|
||||
|
||||
/** Tooltip für den Button „Dateiname übernehmen". */
|
||||
public static final String DATEINAME_UEBERNEHMEN =
|
||||
"Benennt die Zieldatei um und aktualisiert die Datenbank. Nicht rückgängig zu machen.";
|
||||
@@ -133,6 +169,14 @@ public final class GuiTooltipTexts {
|
||||
public static final String BATCHRUN_MESSAGE_AREA =
|
||||
"Statusmeldungen und Fortschrittsinformationen des aktuellen Verarbeitungslaufs.";
|
||||
|
||||
/** Tooltip für den Navigations-Button „Vorherige Seite" in der PDF-Vorschau. */
|
||||
public static final String PREVIEW_VORHERIGE_SEITE =
|
||||
"Vorherige Seite der Vorschau anzeigen.";
|
||||
|
||||
/** Tooltip für den Navigations-Button „Nächste Seite" in der PDF-Vorschau. */
|
||||
public static final String PREVIEW_NAECHSTE_SEITE =
|
||||
"Nächste Seite der Vorschau anzeigen.";
|
||||
|
||||
/** Tooltip für Spalte „Status" in der Verarbeitungslauf-Tabelle. */
|
||||
public static final String BATCHRUN_COL_STATUS =
|
||||
"Verarbeitungsergebnis: Erfolg, Fehler oder übersprungen.";
|
||||
@@ -233,6 +277,18 @@ public final class GuiTooltipTexts {
|
||||
public static final String PROMPT_TEXTAREA =
|
||||
"KI-Anweisungstext. Dieser Prompt wird bei jedem Verarbeitungsversuch an das Sprachmodell gesendet.";
|
||||
|
||||
/** Tooltip für den Button „Speichern" im Prompt-Editor-Tab. */
|
||||
public static final String PROMPT_SPEICHERN =
|
||||
"Prompt-Datei speichern (atomar, UTF-8).";
|
||||
|
||||
/** Tooltip für den Button „Auf Standard zurücksetzen" im Prompt-Editor-Tab. */
|
||||
public static final String PROMPT_ZURUECKSETZEN =
|
||||
"Textfeld mit dem Standard-Prompt-Inhalt befüllen, ohne zu speichern.";
|
||||
|
||||
/** Tooltip für den Button „Standard-Prompt erstellen" im Prompt-Editor-Tab. */
|
||||
public static final String PROMPT_STANDARD_ANLEGEN =
|
||||
"Standard-Prompt-Datei am konfigurierten Pfad anlegen.";
|
||||
|
||||
/** Nicht instanziierbar – reine Konstantenklasse. */
|
||||
private GuiTooltipTexts() {
|
||||
throw new UnsupportedOperationException("Nicht instanziierbar");
|
||||
|
||||
+5
-3
@@ -2,7 +2,7 @@ package de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun;
|
||||
|
||||
/**
|
||||
* Übersetzt strukturierte Fehlermeldungen aus der Anwendungsschicht in
|
||||
* benutzerfreundliche deutsche Texte für den Detailbereich des Verarbeitungslauf-Tabs.
|
||||
* benutzerfreundliche deutsche Texte für die Darstellungsschicht der GUI.
|
||||
* <p>
|
||||
* Die Klasse wertet die englischsprachige Fehlermeldung aus dem Verarbeitungsversuch
|
||||
* musterbasiert aus und liefert eine für den Endbenutzer lesbare Beschreibung des
|
||||
@@ -12,8 +12,10 @@ package de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun;
|
||||
* Die Mustererkennung erfolgt ohne Berücksichtigung der Groß-/Kleinschreibung
|
||||
* und prüft die definierten Schlüsselbegriffe in festgelegter Reihenfolge,
|
||||
* damit spezifischere Muster vor allgemeineren greifen.
|
||||
* <p>
|
||||
* Die Klasse wird sowohl im Verarbeitungslauf-Tab als auch im Verlauf-Tab verwendet.
|
||||
*/
|
||||
final class AiFailureMessageTranslator {
|
||||
public final class AiFailureMessageTranslator {
|
||||
|
||||
private AiFailureMessageTranslator() {
|
||||
}
|
||||
@@ -28,7 +30,7 @@ final class AiFailureMessageTranslator {
|
||||
* @param technicalMessage die rohe technische Fehlermeldung; darf {@code null} sein
|
||||
* @return eine nicht-leere deutsche Benutzerfehlermeldung ohne führendes Warnsymbol
|
||||
*/
|
||||
static String translate(String technicalMessage) {
|
||||
public static String translate(String technicalMessage) {
|
||||
if (technicalMessage == null || technicalMessage.isBlank()) {
|
||||
return "Verarbeitung fehlgeschlagen. Bitte Konfiguration prüfen und ggf. erneut verarbeiten.";
|
||||
}
|
||||
|
||||
+3
@@ -76,6 +76,9 @@ public final class FileNameEditorPane {
|
||||
sectionTitle.setStyle("-fx-font-weight: bold;");
|
||||
|
||||
textField.setId("filename-editor-text-field");
|
||||
Tooltip textFieldTooltip = new Tooltip(GuiTooltipTexts.DATEINAME_TEXTFELD);
|
||||
textFieldTooltip.setShowDelay(Duration.millis(300));
|
||||
textField.setTooltip(textFieldTooltip);
|
||||
HBox.setHgrow(textField, Priority.ALWAYS);
|
||||
|
||||
HBox inputRow = new HBox(4, textField);
|
||||
|
||||
+9
@@ -22,10 +22,13 @@ import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.geometry.Bounds;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiTooltipTexts;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.util.Duration;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.ScrollEvent;
|
||||
@@ -213,9 +216,15 @@ public final class PdfPreviewPane {
|
||||
|
||||
prevButton.setId("pdf-preview-prev-button");
|
||||
prevButton.setOnAction(e -> navigateToPreviousPage());
|
||||
Tooltip prevTooltip = new Tooltip(GuiTooltipTexts.PREVIEW_VORHERIGE_SEITE);
|
||||
prevTooltip.setShowDelay(Duration.millis(300));
|
||||
prevButton.setTooltip(prevTooltip);
|
||||
|
||||
nextButton.setId("pdf-preview-next-button");
|
||||
nextButton.setOnAction(e -> navigateToNextPage());
|
||||
Tooltip nextTooltip = new Tooltip(GuiTooltipTexts.PREVIEW_NAECHSTE_SEITE);
|
||||
nextTooltip.setShowDelay(Duration.millis(300));
|
||||
nextButton.setTooltip(nextTooltip);
|
||||
|
||||
pageLabel.setId("pdf-preview-page-label");
|
||||
pageLabel.setStyle("-fx-text-fill: #555555;");
|
||||
|
||||
+3
-1
@@ -16,6 +16,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiTooltipTexts;
|
||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.AiFailureMessageTranslator;
|
||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.ProcessingStatusPresentation;
|
||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecord;
|
||||
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingAttempt;
|
||||
@@ -810,7 +811,8 @@ public final class GuiHistoryTab {
|
||||
}
|
||||
}
|
||||
|
||||
failureArea.setText(failureMessage != null ? failureMessage : "");
|
||||
failureArea.setText(failureMessage != null
|
||||
? AiFailureMessageTranslator.translate(failureMessage) : "");
|
||||
failureArea.setPromptText("Keine Fehlerdetails gespeichert.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user