Sounds split off into own tab in settings.

This commit is contained in:
Storm Dragon
2026-04-05 21:32:06 -04:00
parent 5779444d4b
commit 296c47be36
5 changed files with 503 additions and 56 deletions
+316 -52
View File
@@ -124,6 +124,12 @@
<property name="step_increment">1</property> <property name="step_increment">1</property>
<property name="page_increment">10</property> <property name="page_increment">10</property>
</object> </object>
<object class="GtkAdjustment" id="progressBarBeepIntervalAdjustment">
<property name="upper">9999</property>
<property name="value">0</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="rateAdjustment"> <object class="GtkAdjustment" id="rateAdjustment">
<property name="upper">100</property> <property name="upper">100</property>
<property name="value">50</property> <property name="value">50</property>
@@ -136,6 +142,12 @@
<property name="step_increment">0.10000000149</property> <property name="step_increment">0.10000000149</property>
<property name="page_increment">1</property> <property name="page_increment">1</property>
</object> </object>
<object class="GtkAdjustment" id="soundVolumeAdjustment">
<property name="upper">1</property>
<property name="value">0.5</property>
<property name="step_increment">0.05000000075</property>
<property name="page_increment">0.10000000149</property>
</object>
<object class="GtkAdjustment" id="echoPitchAdjustment"> <object class="GtkAdjustment" id="echoPitchAdjustment">
<property name="upper">10</property> <property name="upper">10</property>
<property name="value">5</property> <property name="value">5</property>
@@ -777,25 +789,6 @@
<property name="top_attach">3</property> <property name="top_attach">3</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="beepProgressBarUpdatesCheckButton">
<property name="label" translatable="yes" comments="Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases.">Bee_p updates</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
</object> </object>
</child> </child>
</object> </object>
@@ -1036,23 +1029,96 @@
<property name="height">2</property> <property name="height">2</property>
</packing> </packing>
</child> </child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="generalTabLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
</object>
<packing>
<property name="position">0</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="soundsGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">10</property>
<property name="column_spacing">10</property>
<child> <child>
<object class="GtkFrame" id="soundThemeFrame"> <object class="GtkFrame" id="soundOutputFrame">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label_xalign">0</property> <property name="label_xalign">0</property>
<property name="shadow_type">none</property> <property name="shadow_type">none</property>
<child> <child>
<object class="GtkAlignment" id="soundThemeAlignment"> <object class="GtkAlignment" id="soundOutputAlignment">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="left_padding">12</property> <property name="left_padding">12</property>
<child> <child>
<object class="GtkBox" id="soundThemeVBox"> <object class="GtkGrid" id="soundOutputGrid">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="orientation">vertical</property> <property name="row_spacing">10</property>
<property name="spacing">6</property> <property name="column_spacing">20</property>
<child>
<object class="GtkCheckButton" id="enableSoundCheckButton">
<property name="label" translatable="yes">Enable _sounds</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="soundVolumeLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Sound _volume:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">soundVolumeScale</property>
<accessibility>
<relation type="label-for" target="soundVolumeScale"/>
</accessibility>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkScale" id="soundVolumeScale">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">soundVolumeAdjustment</property>
<property name="digits">2</property>
<property name="round_digits">2</property>
<property name="value_pos">right</property>
<signal name="value-changed" handler="soundVolumeValueChanged" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child> <child>
<object class="GtkBox" id="soundSinkHBox"> <object class="GtkBox" id="soundSinkHBox">
<property name="visible">True</property> <property name="visible">True</property>
@@ -1093,11 +1159,48 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="left_attach">0</property>
<property name="fill">True</property> <property name="top_attach">2</property>
<property name="position">0</property> <property name="width">2</property>
</packing> </packing>
</child> </child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="soundOutputTitleLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Output</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="soundPresentationFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="soundPresentationAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkGrid" id="soundPresentationGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">10</property>
<property name="column_spacing">20</property>
<child> <child>
<object class="GtkBox" id="soundThemeHBox"> <object class="GtkBox" id="soundThemeHBox">
<property name="visible">True</property> <property name="visible">True</property>
@@ -1138,9 +1241,9 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="left_attach">0</property>
<property name="fill">True</property> <property name="top_attach">0</property>
<property name="position">1</property> <property name="width">2</property>
</packing> </packing>
</child> </child>
<child> <child>
@@ -1183,9 +1286,77 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="left_attach">0</property>
<property name="fill">True</property> <property name="top_attach">1</property>
<property name="position">2</property> <property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="playSoundForRoleCheckButton">
<property name="label" translatable="yes">Play sound for _role</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="playSoundForStateCheckButton">
<property name="label" translatable="yes">Play sound for _state</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="playSoundForPositionInSetCheckButton">
<property name="label" translatable="yes">Play sound for p_osition in set</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="playSoundForValueCheckButton">
<property name="label" translatable="yes">Play sound for _value</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">2</property>
</packing> </packing>
</child> </child>
</object> </object>
@@ -1193,10 +1364,10 @@
</object> </object>
</child> </child>
<child type="label"> <child type="label">
<object class="GtkLabel" id="soundThemeTitleLabel"> <object class="GtkLabel" id="soundPresentationTitleLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes" comments="Translators: This is the title of a section in the preferences dialog containing sound options.">Sound</property> <property name="label" translatable="yes">Presentation</property>
<attributes> <attributes>
<attribute name="weight" value="bold"/> <attribute name="weight" value="bold"/>
</attributes> </attributes>
@@ -1205,18 +1376,111 @@
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">4</property> <property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="soundAlertsFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="soundAlertsAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkGrid" id="soundAlertsGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">10</property>
<property name="column_spacing">20</property>
<child>
<object class="GtkCheckButton" id="beepProgressBarUpdatesCheckButton">
<property name="label" translatable="yes" comments="Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases.">Bee_p progress bar updates</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="checkButtonToggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="progressBarBeepIntervalLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Beep _frequency (secs):</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">progressBarBeepIntervalSpinButton</property>
<accessibility>
<relation type="label-for" target="progressBarBeepIntervalSpinButton"/>
</accessibility>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="progressBarBeepIntervalSpinButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="text" translatable="yes">0</property>
<property name="adjustment">progressBarBeepIntervalAdjustment</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
<property name="value">0</property>
<signal name="value-changed" handler="progressBarBeepIntervalValueChanged" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="soundAlertsTitleLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Alerts</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing>
<property name="position">1</property>
</packing>
</child> </child>
<child type="tab"> <child type="tab">
<object class="GtkLabel" id="generalTabLabel"> <object class="GtkLabel" id="soundsTabLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">General</property> <property name="label" translatable="yes">Sounds</property>
</object> </object>
<packing> <packing>
<property name="position">1</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -1614,7 +1878,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -1624,7 +1888,7 @@
<property name="label" translatable="yes">Voice</property> <property name="label" translatable="yes">Voice</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -2312,7 +2576,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -2322,7 +2586,7 @@
<property name="label" translatable="yes">Speech</property> <property name="label" translatable="yes">Speech</property>
</object> </object>
<packing> <packing>
<property name="position">2</property> <property name="position">3</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -2911,7 +3175,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">3</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -2921,7 +3185,7 @@
<property name="label" translatable="yes">Braille</property> <property name="label" translatable="yes">Braille</property>
</object> </object>
<packing> <packing>
<property name="position">3</property> <property name="position">4</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -3436,7 +3700,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">4</property> <property name="position">5</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -3446,7 +3710,7 @@
<property name="label" translatable="yes">Echo</property> <property name="label" translatable="yes">Echo</property>
</object> </object>
<packing> <packing>
<property name="position">4</property> <property name="position">5</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -3528,7 +3792,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">5</property> <property name="position">6</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -3538,7 +3802,7 @@
<property name="label" translatable="yes">Key Bindings</property> <property name="label" translatable="yes">Key Bindings</property>
</object> </object>
<packing> <packing>
<property name="position">5</property> <property name="position">6</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -3638,7 +3902,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">6</property> <property name="position">7</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -3648,7 +3912,7 @@
<property name="label" translatable="yes">Pronunciation</property> <property name="label" translatable="yes">Pronunciation</property>
</object> </object>
<packing> <packing>
<property name="position">6</property> <property name="position">7</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
@@ -3983,7 +4247,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="position">7</property> <property name="position">8</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
@@ -3993,7 +4257,7 @@
<property name="label" translatable="yes">Text Attributes</property> <property name="label" translatable="yes">Text Attributes</property>
</object> </object>
<packing> <packing>
<property name="position">7</property> <property name="position">8</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
+38
View File
@@ -198,6 +198,8 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
self.soundThemeCombo = None self.soundThemeCombo = None
self.soundSinkCombo = None self.soundSinkCombo = None
self.roleSoundPresentationCombo = None self.roleSoundPresentationCombo = None
self.soundVolumeScale = None
self.progressBarBeepIntervalSpinButton = None
self._isInitialSetup = False self._isInitialSetup = False
self._updatingSpeechFamilies = False self._updatingSpeechFamilies = False
self.selectedFamilyChoices = {} self.selectedFamilyChoices = {}
@@ -3111,9 +3113,35 @@ print(json.dumps(result))
self.soundSinkCombo = self.get_widget("soundSinkCombo") self.soundSinkCombo = self.get_widget("soundSinkCombo")
self.soundThemeCombo = self.get_widget("soundThemeCombo") self.soundThemeCombo = self.get_widget("soundThemeCombo")
self.roleSoundPresentationCombo = self.get_widget("roleSoundPresentationCombo") self.roleSoundPresentationCombo = self.get_widget("roleSoundPresentationCombo")
self.soundVolumeScale = self.get_widget("soundVolumeScale")
self.progressBarBeepIntervalSpinButton = self.get_widget("progressBarBeepIntervalSpinButton")
self.soundSinkCombo.set_can_focus(False) self.soundSinkCombo.set_can_focus(False)
self.soundThemeCombo.set_can_focus(False) self.soundThemeCombo.set_can_focus(False)
self.roleSoundPresentationCombo.set_can_focus(False) self.roleSoundPresentationCombo.set_can_focus(False)
self.get_widget("enableSoundCheckButton").set_active(
prefs.get("enableSound", settings.enableSound)
)
self.soundVolumeScale.set_value(
float(prefs.get("soundVolume", settings.soundVolume))
)
self.get_widget("playSoundForRoleCheckButton").set_active(
prefs.get("playSoundForRole", settings.playSoundForRole)
)
self.get_widget("playSoundForStateCheckButton").set_active(
prefs.get("playSoundForState", settings.playSoundForState)
)
self.get_widget("playSoundForPositionInSetCheckButton").set_active(
prefs.get("playSoundForPositionInSet", settings.playSoundForPositionInSet)
)
self.get_widget("playSoundForValueCheckButton").set_active(
prefs.get("playSoundForValue", settings.playSoundForValue)
)
self.get_widget("beepProgressBarUpdatesCheckButton").set_active(
prefs.get("beepProgressBarUpdates", settings.beepProgressBarUpdates)
)
self.progressBarBeepIntervalSpinButton.set_value(
int(prefs.get("progressBarBeepInterval", settings.progressBarBeepInterval))
)
self._soundSinkChoices = [ self._soundSinkChoices = [
(settings.SOUND_SINK_AUTO, guilabels.SOUND_BACKEND_AUTO), (settings.SOUND_SINK_AUTO, guilabels.SOUND_BACKEND_AUTO),
@@ -3199,6 +3227,14 @@ print(json.dumps(result))
value = self._roleSoundPresentationChoices[activeIndex][0] value = self._roleSoundPresentationChoices[activeIndex][0]
self.prefsDict["roleSoundPresentation"] = value self.prefsDict["roleSoundPresentation"] = value
def soundVolumeValueChanged(self, widget):
"""Signal handler for the sound volume scale."""
self.prefsDict["soundVolume"] = widget.get_value()
def progressBarBeepIntervalValueChanged(self, widget):
"""Signal handler for the progress bar beep interval spin button."""
self.prefsDict["progressBarBeepInterval"] = widget.get_value_as_int()
def _updateCthulhuModifier(self): def _updateCthulhuModifier(self):
combobox = self.get_widget("cthulhuModifierComboBox") combobox = self.get_widget("cthulhuModifierComboBox")
@@ -4974,6 +5010,7 @@ print(json.dumps(result))
self._apply_plugin_changes() self._apply_plugin_changes()
self.writeUserPreferences() self.writeUserPreferences()
cthulhu.loadUserSettings(self.script) cthulhu.loadUserSettings(self.script)
self._initSoundThemeState()
self._refresh_dynamic_plugin_tabs() self._refresh_dynamic_plugin_tabs()
braille.checkBrailleSetting() braille.checkBrailleSetting()
self._initSpeechState() self._initSpeechState()
@@ -5236,6 +5273,7 @@ print(json.dumps(result))
cthulhu.loadUserSettings(skipReloadMessage=True) cthulhu.loadUserSettings(skipReloadMessage=True)
self._initGUIState() self._initGUIState()
self._initSoundThemeState()
braille.checkBrailleSetting() braille.checkBrailleSetting()
-4
View File
@@ -1503,13 +1503,11 @@ class Script(default.Script):
self.presentMessage("Activating...") self.presentMessage("Activating...")
result = self._performClickableAction(obj) result = self._performClickableAction(obj)
if result: if result:
self._presentDelayedMessage("Element activated", 50)
return True return True
from cthulhu import ax_event_synthesizer from cthulhu import ax_event_synthesizer
result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj) result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj)
if result: if result:
self._presentDelayedMessage("Element activated", 50)
self._restoreFocusAfterClick(original_focus) self._restoreFocusAfterClick(original_focus)
return True return True
@@ -1520,13 +1518,11 @@ class Script(default.Script):
self.presentMessage("Activating...") self.presentMessage("Activating...")
result = self._performClickableAction(obj) result = self._performClickableAction(obj)
if result: if result:
self._presentDelayedMessage("Element activated", 50)
return True return True
from cthulhu import ax_event_synthesizer from cthulhu import ax_event_synthesizer
result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj) result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj)
if result: if result:
self._presentDelayedMessage("Element activated", 50)
self._restoreFocusAfterClick(original_focus) self._restoreFocusAfterClick(original_focus)
return True return True
+148
View File
@@ -1,12 +1,15 @@
import sys import sys
import tempfile import tempfile
import unittest import unittest
import xml.etree.ElementTree as ET
from pathlib import Path from pathlib import Path
from unittest import mock from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cthulhu import cthulhu
from cthulhu import settings from cthulhu import settings
from cthulhu import cthulhu_gui_prefs
from cthulhu import settings_manager from cthulhu import settings_manager
@@ -23,5 +26,150 @@ class SoundSettingsPersistenceTests(unittest.TestCase):
self.assertIn("progressBarBeepInterval = 0", settingsText) self.assertIn("progressBarBeepInterval = 0", settingsText)
class SoundPreferencesBuilderTests(unittest.TestCase):
def test_ui_definition_exposes_sounds_tab_controls(self):
uiPath = Path(__file__).resolve().parents[1] / "src" / "cthulhu" / "cthulhu-setup.ui"
root = ET.fromstring(uiPath.read_text(encoding="utf-8"))
objectIds = {
element.attrib["id"]
for element in root.iter()
if element.tag == "object" and "id" in element.attrib
}
self.assertIn("soundsGrid", objectIds)
self.assertIn("soundsTabLabel", objectIds)
self.assertIn("enableSoundCheckButton", objectIds)
self.assertIn("soundVolumeScale", objectIds)
self.assertIn("progressBarBeepIntervalSpinButton", objectIds)
def test_notebook_tab_positions_keep_sounds_page_and_label_aligned(self):
uiPath = Path(__file__).resolve().parents[1] / "src" / "cthulhu" / "cthulhu-setup.ui"
root = ET.fromstring(uiPath.read_text(encoding="utf-8"))
notebook = next(
element for element in root.iter()
if element.tag == "object" and element.attrib.get("id") == "notebook"
)
positions = {}
for child in notebook.findall("child"):
obj = child.find("object")
if obj is None or "id" not in obj.attrib:
continue
position = None
packing = child.find("packing")
if packing is not None:
for prop in packing.findall("property"):
if prop.attrib.get("name") == "position":
position = int(prop.text)
break
positions[obj.attrib["id"]] = position
self.assertEqual(positions["generalGrid"], 0)
self.assertEqual(positions["generalTabLabel"], 0)
self.assertEqual(positions["soundsGrid"], 1)
self.assertEqual(positions["soundsTabLabel"], 1)
self.assertEqual(positions["voiceGrid"], 2)
self.assertEqual(positions["voiceLabel"], 2)
self.assertEqual(positions["textAttributesGrid"], 8)
self.assertEqual(positions["textAttributesTabLabel"], 8)
class SoundPreferencesControllerTests(unittest.TestCase):
def test_init_sound_state_loads_sound_volume_and_beep_interval(self):
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI)
gui.prefsDict = {
"enableSound": False,
"soundSink": settings.SOUND_SINK_PULSE,
"soundTheme": "default",
"roleSoundPresentation": settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY,
"soundVolume": 0.65,
"progressBarBeepInterval": 0,
"beepProgressBarUpdates": True,
"playSoundForRole": True,
"playSoundForState": True,
"playSoundForPositionInSet": False,
"playSoundForValue": False,
}
widgets = {
"soundSinkCombo": mock.Mock(),
"soundThemeCombo": mock.Mock(),
"roleSoundPresentationCombo": mock.Mock(),
"soundVolumeScale": mock.Mock(),
"progressBarBeepIntervalSpinButton": mock.Mock(),
"enableSoundCheckButton": mock.Mock(),
"playSoundForRoleCheckButton": mock.Mock(),
"playSoundForStateCheckButton": mock.Mock(),
"playSoundForPositionInSetCheckButton": mock.Mock(),
"playSoundForValueCheckButton": mock.Mock(),
"beepProgressBarUpdatesCheckButton": mock.Mock(),
}
gui.get_widget = widgets.__getitem__
fakeThemeManager = mock.Mock()
fakeThemeManager.getAvailableThemes.return_value = ["default"]
fakeSettingsManager = mock.Mock()
fakeSettingsManager.getSetting.return_value = settings.SOUND_SINK_AUTO
fakeApp = mock.Mock(settingsManager=fakeSettingsManager)
with (
mock.patch.object(cthulhu_gui_prefs.cthulhu, "cthulhuApp", fakeApp),
mock.patch.object(
cthulhu_gui_prefs.sound_theme_manager,
"getManager",
return_value=fakeThemeManager,
),
):
gui._initSoundThemeState()
widgets["enableSoundCheckButton"].set_active.assert_called_once_with(False)
widgets["soundVolumeScale"].set_value.assert_called_once_with(0.65)
widgets["playSoundForRoleCheckButton"].set_active.assert_called_once_with(True)
widgets["playSoundForStateCheckButton"].set_active.assert_called_once_with(True)
widgets["playSoundForPositionInSetCheckButton"].set_active.assert_called_once_with(False)
widgets["playSoundForValueCheckButton"].set_active.assert_called_once_with(False)
widgets["beepProgressBarUpdatesCheckButton"].set_active.assert_called_once_with(True)
widgets["progressBarBeepIntervalSpinButton"].set_value.assert_called_once_with(0)
def test_sound_value_handlers_store_current_values(self):
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI)
gui.prefsDict = {}
volumeWidget = mock.Mock()
volumeWidget.get_value.return_value = 0.7
beepWidget = mock.Mock()
beepWidget.get_value_as_int.return_value = 0
gui.soundVolumeValueChanged(volumeWidget)
gui.progressBarBeepIntervalValueChanged(beepWidget)
self.assertEqual(gui.prefsDict["soundVolume"], 0.7)
self.assertEqual(gui.prefsDict["progressBarBeepInterval"], 0)
def test_load_profile_reinitializes_sound_state(self):
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI)
gui.saveBasicSettings = mock.Mock()
gui._initGUIState = mock.Mock()
gui._initSoundThemeState = mock.Mock()
gui._initSpeechState = mock.Mock()
gui._initEchoSpeechState = mock.Mock()
gui._populateKeyBindings = mock.Mock()
gui._CthulhuSetupGUI__initProfileCombo = mock.Mock()
gui.prefsDict = {}
fakeSettingsManager = mock.Mock()
fakeSettingsManager.getGeneralSettings.return_value = {"soundVolume": 0.5}
fakeApp = mock.Mock(settingsManager=fakeSettingsManager)
with (
mock.patch.object(cthulhu_gui_prefs.cthulhu, "cthulhuApp", fakeApp),
mock.patch.object(cthulhu_gui_prefs.cthulhu, "loadUserSettings"),
mock.patch.object(cthulhu_gui_prefs.braille, "checkBrailleSetting"),
):
gui.loadProfile(["Default", "default"])
gui._initSoundThemeState.assert_called_once_with()
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
+1
View File
@@ -58,6 +58,7 @@ class WebClickableActivationTests(unittest.TestCase):
doAction.assert_called_once_with(caretObject, "click-ancestor") doAction.assert_called_once_with(caretObject, "click-ancestor")
clickObject.assert_not_called() clickObject.assert_not_called()
testScript._presentDelayedMessage.assert_not_called()
class WebHiddenPopupTests(unittest.TestCase): class WebHiddenPopupTests(unittest.TestCase):