Skip to content

Commit 9e34662

Browse files
Lukas Geigerclaude
andcommitted
fix(settings): _apply_settings() uebertraegt ai.model und max_tokens (B-001); roter Rahmen in NewProjectDialog wird bei textChanged zurueckgesetzt (B-002)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b744401 commit 9e34662

4 files changed

Lines changed: 75 additions & 12 deletions

File tree

BUGS.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ Format: `[Status] Titel — Kurzbeschreibung`
77

88
## Offen
99

10+
_(Keine offenen Bugs)_
11+
12+
---
13+
14+
## Behoben
15+
1016
### B-001: Modell-Auswahl nicht funktional
11-
**Status:** Offen
17+
**Status:** Behoben (2026-06-05)
1218
**Datei:** `src/gui/main_window.py``_apply_settings()`
13-
**Schwere:** Mittel (Feature silent broken)
14-
**Beschreibung:**
15-
`_apply_settings()` liest `ai.model` aus den Einstellungen, ruft aber `ai_service.set_model()` nie auf. Der gespeicherte Wert ist zudem der Anzeigename (z. B. "Claude Haiku") statt der API-ID. Die Modell-Auswahl in den Einstellungen wird daher vollständig ignoriert.
16-
**Workaround:** Keiner. Das KI-Modell bleibt beim Standardwert der `AIService`-Instanz.
19+
**Fix:** `_apply_settings()` liest nun `ai.model` und ruft `set_model()` mit dem korrekten `AIModel`-Enum-Wert auf. Auch `max_tokens` wird übertragen.
1720

1821
### B-002: Rotes Validierungs-Rahmen in NewProjectDialog wird nicht zurückgesetzt
19-
**Status:** Offen
20-
**Datei:** `src/gui/dialogs/new_project_dialog.py``_validate_input()` / `name_edit`
21-
**Schwere:** Gering (kosmetischer UX-Defekt)
22-
**Beschreibung:**
23-
Wenn der Benutzer im `NewProjectDialog` einen ungültigen Projektnamen eingibt und auf "Erstellen" klickt, setzt `_validate_input()` einen roten Rahmen auf `name_edit`. Sobald der Benutzer dann wieder zu tippen beginnt, wird dieser Rahmen nicht automatisch zurückgesetzt. Der rote Rahmen bleibt, bis das Formular neu validiert wird.
24-
**Workaround:** Nutzer muss das Formular erneut absenden, um den Rahmen zu entfernen.
22+
**Status:** Behoben (2026-06-05)
23+
**Datei:** `src/gui/dialogs/new_project_dialog.py``_reset_name_style()`
24+
**Fix:** `name_edit.textChanged` ist nun mit `_reset_name_style()` verbunden, das `setStyleSheet("")` aufruft und so den roten Rahmen beim nächsten Tastendruck löscht.
2525

2626
---
2727

src/gui/dialogs/new_project_dialog.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def _setup_ui(self):
4343
self.name_edit = QLineEdit()
4444
self.name_edit.setPlaceholderText("Mein Python Projekt")
4545
self.name_edit.textChanged.connect(self._update_path)
46+
self.name_edit.textChanged.connect(self._reset_name_style)
4647
details_layout.addRow("Name:", self.name_edit)
4748

4849
# Speicherort
@@ -184,6 +185,10 @@ def _apply_styles(self):
184185
}
185186
""")
186187

188+
def _reset_name_style(self):
189+
"""Setzt den roten Validierungsrahmen zurück wenn der Nutzer zu tippen beginnt."""
190+
self.name_edit.setStyleSheet("")
191+
187192
def _browse_path(self):
188193
"""Öffnet den Verzeichnis-Dialog"""
189194
path = QFileDialog.getExistingDirectory(

src/gui/main_window.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,21 @@ def _apply_settings(self):
10731073
"""Wendet geänderte Einstellungen an"""
10741074
# API-Key aktualisieren
10751075
self.ai_service.set_api_key(self.settings.get('ai.api_key', ''))
1076-
1076+
1077+
# Modell aktualisieren (Anzeigename → AIModel-Enum)
1078+
from modules.ai_assistant.ai_service import AIModel
1079+
_MODEL_MAP = {
1080+
'Claude Sonnet': AIModel.CLAUDE_SONNET,
1081+
'Claude Opus': AIModel.CLAUDE_OPUS,
1082+
'Claude Haiku': AIModel.CLAUDE_HAIKU,
1083+
}
1084+
model_name = self.settings.get('ai.model', 'Claude Sonnet')
1085+
if model_name in _MODEL_MAP:
1086+
self.ai_service.set_model(_MODEL_MAP[model_name])
1087+
1088+
# Max Tokens aktualisieren
1089+
self.ai_service.max_tokens = self.settings.get('ai.max_tokens', 4096)
1090+
10771091
# Editor-Einstellungen auf alle offenen Editoren anwenden
10781092
for index in range(self.editor_tabs.count()):
10791093
widget = self.editor_tabs.widget(index)

tests/test_core.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,50 @@ def test_new_lanczos_api_used(self):
12541254
"WindowsStorePublisher_3.py muss Image.Resampling.LANCZOS verwenden")
12551255

12561256

1257+
class TestApplySettingsUpdatesModel(unittest.TestCase):
1258+
"""Bug B-001: _apply_settings() muss set_model() aufrufen."""
1259+
1260+
def test_apply_settings_calls_set_model(self):
1261+
"""_apply_settings() muss ai.model lesen und set_model() aufrufen — ohne Fix wird
1262+
die Modell-Auswahl in den Einstellungen vollständig ignoriert."""
1263+
import inspect
1264+
from gui.main_window import MainWindow
1265+
source = inspect.getsource(MainWindow._apply_settings)
1266+
self.assertIn('set_model', source,
1267+
"_apply_settings() muss set_model() aufrufen")
1268+
self.assertIn('ai.model', source,
1269+
"_apply_settings() muss ai.model aus den Einstellungen lesen")
1270+
1271+
def test_apply_settings_updates_max_tokens(self):
1272+
"""_apply_settings() muss auch ai.max_tokens auf den Service übertragen."""
1273+
import inspect
1274+
from gui.main_window import MainWindow
1275+
source = inspect.getsource(MainWindow._apply_settings)
1276+
self.assertIn('max_tokens', source,
1277+
"_apply_settings() muss ai.max_tokens auf ai_service übertragen")
1278+
1279+
1280+
class TestNewProjectDialogBorderReset(unittest.TestCase):
1281+
"""Bug B-002: Roter Validierungsrahmen muss bei textChanged zurückgesetzt werden."""
1282+
1283+
def test_name_edit_textchanged_resets_style(self):
1284+
"""name_edit.textChanged muss mit _reset_name_style verbunden sein — ohne Fix
1285+
bleibt der rote Rahmen auch nach Korrektur des Namens sichtbar."""
1286+
import inspect
1287+
from gui.dialogs.new_project_dialog import NewProjectDialog
1288+
source = inspect.getsource(NewProjectDialog._setup_ui)
1289+
self.assertIn('_reset_name_style', source,
1290+
"name_edit.textChanged muss mit _reset_name_style verbunden sein")
1291+
1292+
def test_reset_name_style_clears_stylesheet(self):
1293+
"""_reset_name_style() muss das Stylesheet löschen (leerer String)."""
1294+
import inspect
1295+
from gui.dialogs.new_project_dialog import NewProjectDialog
1296+
source = inspect.getsource(NewProjectDialog._reset_name_style)
1297+
self.assertIn('setStyleSheet("")', source,
1298+
"_reset_name_style() muss setStyleSheet('') aufrufen")
1299+
1300+
12571301
if __name__ == "__main__":
12581302
# Verbose Output
12591303
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)