Fix prefs state churn and sound-only role speech
Some settings were being reset when tab changed and a key was pressed, e.g. control. Radio buttons were still announced even with sound only set. Controls for AI assistant tab were vanishing after being set.
This commit is contained in:
@@ -2563,22 +2563,20 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
|||||||
self._updateAIControlsState(enabled)
|
self._updateAIControlsState(enabled)
|
||||||
|
|
||||||
def _updateAIControlsState(self, enabled):
|
def _updateAIControlsState(self, enabled):
|
||||||
"""Enable or disable AI controls based on AI enabled state."""
|
"""Refresh AI controls while keeping configuration fields editable."""
|
||||||
self.aiProviderCombo.set_sensitive(enabled)
|
_ = enabled # kept for signal/call compatibility
|
||||||
self.aiApiKeyEntry.set_sensitive(enabled)
|
# Keep settings editable even when AI assistant is disabled so users
|
||||||
self.aiOllamaModelEntry.set_sensitive(enabled)
|
# can configure providers/keys before enabling it.
|
||||||
self.aiOllamaEndpointEntry.set_sensitive(enabled)
|
self.aiProviderCombo.set_sensitive(True)
|
||||||
self.aiConfirmationCheckButton.set_sensitive(enabled)
|
self.aiConfirmationCheckButton.set_sensitive(True)
|
||||||
self.aiScreenshotQualityCombo.set_sensitive(enabled)
|
self.aiScreenshotQualityCombo.set_sensitive(True)
|
||||||
try:
|
try:
|
||||||
self.get_widget("aiGetClaudeKeyButton").set_sensitive(enabled)
|
self.get_widget("aiGetClaudeKeyButton").set_sensitive(True)
|
||||||
except:
|
except:
|
||||||
pass # Button might not exist in older UI files
|
pass # Button might not exist in older UI files
|
||||||
|
|
||||||
# Update provider-specific controls if AI is enabled
|
current_provider = self.prefsDict.get("aiProvider", settings.aiProvider)
|
||||||
if enabled:
|
self._updateProviderControls(current_provider)
|
||||||
current_provider = self.prefsDict.get("aiProvider", settings.aiProvider)
|
|
||||||
self._updateProviderControls(current_provider)
|
|
||||||
|
|
||||||
def _initIndentationState(self):
|
def _initIndentationState(self):
|
||||||
"""Initialize Indentation widgets with current settings."""
|
"""Initialize Indentation widgets with current settings."""
|
||||||
|
|||||||
@@ -325,7 +325,6 @@ class AIAssistant(Plugin):
|
|||||||
if not self._prefs_widgets:
|
if not self._prefs_widgets:
|
||||||
return
|
return
|
||||||
|
|
||||||
enabled = self._prefs_widgets["enable_check"].get_active()
|
|
||||||
provider_values = self._prefs_widgets.get("provider_values", [])
|
provider_values = self._prefs_widgets.get("provider_values", [])
|
||||||
provider_index = self._prefs_widgets["provider_combo"].get_active()
|
provider_index = self._prefs_widgets["provider_combo"].get_active()
|
||||||
provider = provider_values[provider_index] if 0 <= provider_index < len(provider_values) else settings.aiProvider
|
provider = provider_values[provider_index] if 0 <= provider_index < len(provider_values) else settings.aiProvider
|
||||||
@@ -333,12 +332,14 @@ class AIAssistant(Plugin):
|
|||||||
is_gemini = provider == settings.AI_PROVIDER_GEMINI
|
is_gemini = provider == settings.AI_PROVIDER_GEMINI
|
||||||
is_ollama = provider == settings.AI_PROVIDER_OLLAMA
|
is_ollama = provider == settings.AI_PROVIDER_OLLAMA
|
||||||
|
|
||||||
self._prefs_widgets["provider_combo"].set_sensitive(enabled)
|
# Keep preferences editable even when the feature is disabled so users
|
||||||
self._prefs_widgets["api_key_entry"].set_sensitive(enabled and is_gemini)
|
# can prepare configuration before turning AI assistant on.
|
||||||
self._prefs_widgets["ollama_model_entry"].set_sensitive(enabled and is_ollama)
|
self._prefs_widgets["provider_combo"].set_sensitive(True)
|
||||||
self._prefs_widgets["ollama_endpoint_entry"].set_sensitive(enabled and is_ollama)
|
self._prefs_widgets["api_key_entry"].set_sensitive(is_gemini)
|
||||||
self._prefs_widgets["confirmation_check"].set_sensitive(enabled)
|
self._prefs_widgets["ollama_model_entry"].set_sensitive(is_ollama)
|
||||||
self._prefs_widgets["quality_combo"].set_sensitive(enabled)
|
self._prefs_widgets["ollama_endpoint_entry"].set_sensitive(is_ollama)
|
||||||
|
self._prefs_widgets["confirmation_check"].set_sensitive(True)
|
||||||
|
self._prefs_widgets["quality_combo"].set_sensitive(True)
|
||||||
|
|
||||||
def refresh_settings(self):
|
def refresh_settings(self):
|
||||||
"""Refresh plugin settings and reinitialize provider. Called when settings change."""
|
"""Refresh plugin settings and reinitialize provider. Called when settings change."""
|
||||||
|
|||||||
@@ -1967,6 +1967,15 @@ class Script(script.Script):
|
|||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Some toolkits emit transient window:deactivate/window:activate pairs
|
||||||
|
# while the same window remains active. Treat those as noise so we do
|
||||||
|
# not clear state and force a full script/settings reactivation.
|
||||||
|
AXObject.clear_cache(event.source)
|
||||||
|
if AXUtilities.is_active(event.source):
|
||||||
|
msg = "DEFAULT: Ignoring event. Source window still active."
|
||||||
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
|
return
|
||||||
|
|
||||||
if self.flatReviewPresenter.is_active():
|
if self.flatReviewPresenter.is_active():
|
||||||
self.flatReviewPresenter.quit()
|
self.flatReviewPresenter.quit()
|
||||||
|
|
||||||
|
|||||||
@@ -572,7 +572,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
|
|||||||
and soundEnabled:
|
and soundEnabled:
|
||||||
roleSoundIcon = sound_theme_manager.getManager().getRoleSoundIcon(role)
|
roleSoundIcon = sound_theme_manager.getManager().getRoleSoundIcon(role)
|
||||||
if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY \
|
if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY \
|
||||||
and soundEnabled and roleSoundIcon:
|
and soundEnabled:
|
||||||
|
# Stateful controls present their role via state sounds; suppress
|
||||||
|
# spoken role names here even if no dedicated role icon exists.
|
||||||
if AXUtilities.is_check_box(obj) \
|
if AXUtilities.is_check_box(obj) \
|
||||||
or AXUtilities.is_check_menu_item(obj) \
|
or AXUtilities.is_check_menu_item(obj) \
|
||||||
or AXUtilities.is_radio_button(obj) \
|
or AXUtilities.is_radio_button(obj) \
|
||||||
|
|||||||
@@ -678,7 +678,9 @@ class SpeechGenerator(generator.Generator):
|
|||||||
and soundEnabled:
|
and soundEnabled:
|
||||||
roleSoundIcon = sound_theme_manager.getManager().getRoleSoundIcon(role)
|
roleSoundIcon = sound_theme_manager.getManager().getRoleSoundIcon(role)
|
||||||
if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY \
|
if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY \
|
||||||
and soundEnabled and roleSoundIcon:
|
and soundEnabled:
|
||||||
|
# Stateful controls present their role via state sounds; suppress
|
||||||
|
# spoken role names here even if no dedicated role icon exists.
|
||||||
if AXUtilities.is_check_box(obj) \
|
if AXUtilities.is_check_box(obj) \
|
||||||
or AXUtilities.is_check_menu_item(obj) \
|
or AXUtilities.is_check_menu_item(obj) \
|
||||||
or AXUtilities.is_radio_button(obj) \
|
or AXUtilities.is_radio_button(obj) \
|
||||||
|
|||||||
Reference in New Issue
Block a user