Cthulhu is no longer a fork. Now it is a screen reader written in Golang.
This commit is contained in:
1 parent
a998fe67de
commit
069fc674dc
708 files changed
+112482
-532
No files matched your search
@@ -0,0 +1,576 @@
|
||||
// Cthulhu screen reader.
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/datetime"
|
||||
"git.stormux.org/storm/cthulhu/internal/input"
|
||||
)
|
||||
|
||||
// Application profiles store only values that differ from the global profile.
|
||||
// The writable schema is made of nested value structs and pointer fields, so
|
||||
// clearing equal leaves preserves its existing patch semantics.
|
||||
func applicationProfileDifference(global, application Settings) writableProfile {
|
||||
base := profileFromSettings(global)
|
||||
result := profileFromSettings(application)
|
||||
clearEqualProfileFields(reflect.ValueOf(&result).Elem(), reflect.ValueOf(base))
|
||||
return result
|
||||
}
|
||||
|
||||
func clearEqualProfileFields(result, base reflect.Value) {
|
||||
for index := 0; index < result.NumField(); index++ {
|
||||
field, baseline := result.Field(index), base.Field(index)
|
||||
if field.Kind() == reflect.Struct {
|
||||
clearEqualProfileFields(field, baseline)
|
||||
} else if reflect.DeepEqual(field.Interface(), baseline.Interface()) {
|
||||
field.SetZero()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RebaseApplicationSettings keeps session-only application choices when the
|
||||
// global profile changes, while newly inherited values follow the new global.
|
||||
func RebaseApplicationSettings(oldGlobal, newGlobal, application Settings) Settings {
|
||||
patch := applicationProfileDifference(oldGlobal, application)
|
||||
rebased := newGlobal
|
||||
applyProfile(&rebased, patch)
|
||||
rebased.ActiveProfile = application.ActiveProfile
|
||||
return rebased
|
||||
}
|
||||
|
||||
func profileFromSettings(settings Settings) writableProfile {
|
||||
return writableProfile{
|
||||
OCR: writableOCR{Language: stringPointer(settings.OCR.Language), Layout: intPointer(settings.OCR.Layout), Scale: intPointer(settings.OCR.Scale), Grayscale: boolPointer(settings.OCR.Grayscale), Invert: boolPointer(settings.OCR.Invert), BlackWhite: boolPointer(settings.OCR.BlackWhite), Threshold: intPointer(settings.OCR.Threshold), AutoRefresh: boolPointer(settings.OCR.AutoRefresh), RefreshInterval: intPointer(settings.OCR.RefreshInterval), ConfirmClick: boolPointer(settings.OCR.ConfirmClick), CopyFirstResult: boolPointer(settings.OCR.CopyFirstResult), AutoReadAll: boolPointer(settings.OCR.AutoReadAll)},
|
||||
ProgressBar: writableProgressBar{
|
||||
OutputMode: stringPointer(settings.ProgressBar.OutputMode),
|
||||
ReportBackground: boolPointer(settings.ProgressBar.ReportBackground),
|
||||
BeepPercentageInterval: intPointer(settings.ProgressBar.BeepPercentageInterval),
|
||||
SpeechPercentageInterval: intPointer(settings.ProgressBar.SpeechPercentageInterval),
|
||||
},
|
||||
Presentation: writablePresentation{
|
||||
Pronunciations: pronunciationSlicePointer(settings.Pronunciations),
|
||||
TextAttributes: writableTextAttributes{Choices: textAttributeSlicePointer(settings.TextAttributes.Choices), Indicator: intPointer(settings.TextAttributes.Indicator)},
|
||||
TimeFormat: stringPointer(settings.TimeFormat), DateFormat: stringPointer(settings.DateFormat),
|
||||
SpeakDescription: boolPointer(settings.SpeakDescription),
|
||||
SpeechVerbosityLevel: intPointer(settings.SpeechVerbosityLevel),
|
||||
SayAllStyle: stringPointer(settings.SayAllStyle),
|
||||
Reading: writableReading{
|
||||
AutomaticallyReadClipboardChanges: boolPointer(settings.Reading.AutomaticallyReadClipboardChanges),
|
||||
AutomaticallyReadTitleChanges: boolPointer(settings.Reading.AutomaticallyReadTitleChanges),
|
||||
EnablePauseBreaks: boolPointer(settings.Reading.EnablePauseBreaks),
|
||||
SpeakNumbersAsDigits: boolPointer(settings.Reading.SpeakNumbersAsDigits),
|
||||
SpeakMultiCaseStringsAsWords: boolPointer(settings.Reading.SpeakMultiCaseStringsAsWords),
|
||||
EnableIndentation: boolPointer(settings.Reading.EnableIndentation),
|
||||
IndentationPresentationMode: stringPointer(settings.Reading.IndentationPresentationMode),
|
||||
OnlySpeakDisplayedText: boolPointer(settings.Reading.OnlySpeakDisplayedText),
|
||||
SpeakBlankLines: boolPointer(settings.Reading.SpeakBlankLines),
|
||||
EnableMnemonicSpeaking: boolPointer(settings.Reading.EnableMnemonicSpeaking),
|
||||
EnablePositionSpeaking: boolPointer(settings.Reading.EnablePositionSpeaking),
|
||||
EnableTutorialMessages: boolPointer(settings.Reading.EnableTutorialMessages),
|
||||
MessagesAreDetailed: boolPointer(settings.Reading.MessagesAreDetailed),
|
||||
UseColorNames: boolPointer(settings.Reading.UseColorNames),
|
||||
PresentTooltips: boolPointer(settings.Reading.PresentTooltips),
|
||||
EnableMouseReview: boolPointer(settings.Reading.EnableMouseReview),
|
||||
SpeakMisspelledIndicator: boolPointer(settings.Reading.SpeakMisspelledIndicator),
|
||||
SpeakContextBlockquote: boolPointer(settings.Reading.SpeakContextBlockquote),
|
||||
SpeakContextList: boolPointer(settings.Reading.SpeakContextList),
|
||||
SpeakContextTable: boolPointer(settings.Reading.SpeakContextTable),
|
||||
SpeakContextPanel: boolPointer(settings.Reading.SpeakContextPanel),
|
||||
SpeakContextLandmark: boolPointer(settings.Reading.SpeakContextLandmark),
|
||||
SpeakContextNonLandmarkForm: boolPointer(settings.Reading.SpeakContextNonLandmarkForm),
|
||||
SayAllContextBlockquote: boolPointer(settings.Reading.SayAllContextBlockquote),
|
||||
SayAllContextList: boolPointer(settings.Reading.SayAllContextList),
|
||||
SayAllContextTable: boolPointer(settings.Reading.SayAllContextTable),
|
||||
SayAllContextPanel: boolPointer(settings.Reading.SayAllContextPanel),
|
||||
SayAllContextLandmark: boolPointer(settings.Reading.SayAllContextLandmark),
|
||||
SayAllContextNonLandmarkForm: boolPointer(settings.Reading.SayAllContextNonLandmarkForm),
|
||||
ReadFullRowInGUITable: boolPointer(settings.Reading.ReadFullRowInGUITable),
|
||||
ReadFullRowInDocumentTable: boolPointer(settings.Reading.ReadFullRowInDocumentTable),
|
||||
ReadFullRowInSpreadSheet: boolPointer(settings.Reading.ReadFullRowInSpreadSheet),
|
||||
},
|
||||
},
|
||||
Speech: writableSpeech{
|
||||
HardwareDevice: stringPointer(settings.HardwareSpeechDevice),
|
||||
HardwareBaudRate: intPointer(settings.HardwareSpeechBaudRate),
|
||||
Enabled: boolPointer(settings.EnableSpeech), ServerFactory: stringPointer(settings.SpeechServerFactory),
|
||||
HistoryLimit: intPointer(settings.SpeechHistoryLimit),
|
||||
Punctuation: intPointer(settings.VerbalizePunctuationStyle), Capitalization: stringPointer(settings.CapitalizationStyle),
|
||||
DefaultVoice: voicePointer(settings.DefaultVoice),
|
||||
UppercaseVoice: voicePointer(settings.UppercaseVoice),
|
||||
HyperlinkVoice: voicePointer(settings.HyperlinkVoice),
|
||||
SystemVoice: voicePointer(settings.SystemVoice),
|
||||
OutputModule: stringPointer(settings.SpeechOutputModule),
|
||||
},
|
||||
Braille: writableBraille{Enabled: boolPointer(settings.EnableBraille),
|
||||
Contracted: boolPointer(settings.EnableContractedBraille),
|
||||
ContractionTable: stringPointer(settings.BrailleContractionTable),
|
||||
AbbreviateRoles: boolPointer(settings.Braille.AbbreviateRoles),
|
||||
DisableEOL: boolPointer(settings.Braille.DisableEOL), WordWrap: boolPointer(settings.Braille.WordWrap),
|
||||
Verbosity: intPointer(settings.Braille.Verbosity), SelectionIndicator: intPointer(settings.Braille.SelectionIndicator),
|
||||
LinkIndicator: intPointer(settings.Braille.LinkIndicator), FlashMessages: boolPointer(settings.Braille.FlashMessages),
|
||||
FlashTime: intPointer(settings.Braille.FlashTime), FlashPersistent: boolPointer(settings.Braille.FlashPersistent),
|
||||
FlashDetailed: boolPointer(settings.Braille.FlashDetailed)},
|
||||
Sound: writableSound{
|
||||
Enabled: boolPointer(settings.EnableSound), Volume: floatPointer(settings.SoundVolume),
|
||||
Sink: stringPointer(settings.SoundSink), Theme: stringPointer(settings.SoundTheme),
|
||||
PlayForRole: boolPointer(settings.PlaySoundForRole), PlayForState: boolPointer(settings.PlaySoundForState),
|
||||
PlayForPosition: boolPointer(settings.PlaySoundForPositionInSet),
|
||||
Spatialize: boolPointer(settings.SpatializeObjectSounds),
|
||||
RolePresentationStrategy: stringPointer(settings.RoleSoundPresentation),
|
||||
},
|
||||
Keyboard: writableKeyboard{
|
||||
Bindings: bindingSlicePointer(settings.KeyBindings),
|
||||
Layout: intPointer(settings.KeyboardLayout),
|
||||
ScreenReaderKeys: stringSlicePointer(settings.CthulhuModifierKeys),
|
||||
},
|
||||
KeyEcho: writableKeyEcho{
|
||||
UseCustomEchoVoice: boolPointer(settings.UseCustomEchoVoice),
|
||||
UseCustomEchoSpeechServer: boolPointer(settings.UseCustomEchoSpeechServer),
|
||||
UseCustomEchoForKey: boolPointer(settings.UseCustomEchoForKey),
|
||||
UseCustomEchoForCharacter: boolPointer(settings.UseCustomEchoForCharacter),
|
||||
UseCustomEchoForWord: boolPointer(settings.UseCustomEchoForWord),
|
||||
UseCustomEchoForSentence: boolPointer(settings.UseCustomEchoForSentence),
|
||||
EchoVoice: voicePointer(settings.EchoVoice), EchoSpeechServer: stringPointer(settings.EchoSpeechServer),
|
||||
|
||||
Enabled: boolPointer(settings.EnableKeyEcho), ByCharacter: boolPointer(settings.EnableEchoByCharacter),
|
||||
ByWord: boolPointer(settings.EnableEchoByWord), BySentence: boolPointer(settings.EnableEchoBySentence),
|
||||
Alphabetic: boolPointer(settings.EnableAlphabeticKeys), Numeric: boolPointer(settings.EnableNumericKeys),
|
||||
Punctuation: boolPointer(settings.EnablePunctuationKeys), Space: boolPointer(settings.EnableSpace),
|
||||
Modifiers: boolPointer(settings.EnableModifierKeys), FunctionKeys: boolPointer(settings.EnableFunctionKeys),
|
||||
ActionKeys: boolPointer(settings.EnableActionKeys), NavigationKeys: boolPointer(settings.EnableNavigationKeys),
|
||||
Diacritical: boolPointer(settings.EnableDiacriticalKeys),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func applyProfile(settings *Settings, profile writableProfile) {
|
||||
apply_profile_ocr(&settings.OCR, profile.OCR)
|
||||
// Keep the established patch order; absent fields leave prior values intact.
|
||||
apply_profile_formats(settings, profile)
|
||||
apply_profile_echo_voice(settings, profile)
|
||||
apply_profile_reading(settings, profile)
|
||||
apply_profile_output(settings, profile)
|
||||
apply_profile_speech(settings, profile)
|
||||
apply_profile_sound(settings, profile)
|
||||
if value := profile.ProgressBar.OutputMode; value != nil {
|
||||
settings.ProgressBar.OutputMode = *value
|
||||
}
|
||||
if value := profile.ProgressBar.ReportBackground; value != nil {
|
||||
settings.ProgressBar.ReportBackground = *value
|
||||
}
|
||||
if value := profile.ProgressBar.BeepPercentageInterval; value != nil {
|
||||
settings.ProgressBar.BeepPercentageInterval = *value
|
||||
}
|
||||
if value := profile.ProgressBar.SpeechPercentageInterval; value != nil {
|
||||
settings.ProgressBar.SpeechPercentageInterval = *value
|
||||
}
|
||||
apply_profile_keyboard(settings, profile)
|
||||
apply_profile_echo_keys(settings, profile)
|
||||
}
|
||||
|
||||
func apply_profile_ocr(settings *OCRSettings, patch writableOCR) {
|
||||
if patch.Language != nil {
|
||||
settings.Language = *patch.Language
|
||||
}
|
||||
if patch.Layout != nil {
|
||||
settings.Layout = *patch.Layout
|
||||
}
|
||||
if patch.Scale != nil {
|
||||
settings.Scale = *patch.Scale
|
||||
}
|
||||
if patch.Grayscale != nil {
|
||||
settings.Grayscale = *patch.Grayscale
|
||||
}
|
||||
if patch.Invert != nil {
|
||||
settings.Invert = *patch.Invert
|
||||
}
|
||||
if patch.BlackWhite != nil {
|
||||
settings.BlackWhite = *patch.BlackWhite
|
||||
}
|
||||
if patch.Threshold != nil {
|
||||
settings.Threshold = *patch.Threshold
|
||||
}
|
||||
if patch.AutoRefresh != nil {
|
||||
settings.AutoRefresh = *patch.AutoRefresh
|
||||
}
|
||||
if patch.RefreshInterval != nil {
|
||||
settings.RefreshInterval = *patch.RefreshInterval
|
||||
}
|
||||
if patch.ConfirmClick != nil {
|
||||
settings.ConfirmClick = *patch.ConfirmClick
|
||||
}
|
||||
if patch.CopyFirstResult != nil {
|
||||
settings.CopyFirstResult = *patch.CopyFirstResult
|
||||
}
|
||||
if patch.AutoReadAll != nil {
|
||||
settings.AutoReadAll = *patch.AutoReadAll
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_formats(settings *Settings, profile writableProfile) {
|
||||
if v := profile.Presentation.TimeFormat; v != nil {
|
||||
settings.TimeFormat = *v
|
||||
}
|
||||
if v := profile.Presentation.DateFormat; v != nil {
|
||||
settings.DateFormat = datetime.NormalizeDate(*v)
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_echo_voice(settings *Settings, profile writableProfile) {
|
||||
if v := profile.KeyEcho.UseCustomEchoVoice; v != nil {
|
||||
settings.UseCustomEchoVoice = *v
|
||||
}
|
||||
if v := profile.KeyEcho.UseCustomEchoSpeechServer; v != nil {
|
||||
settings.UseCustomEchoSpeechServer = *v
|
||||
}
|
||||
if v := profile.KeyEcho.UseCustomEchoForKey; v != nil {
|
||||
settings.UseCustomEchoForKey = *v
|
||||
}
|
||||
if v := profile.KeyEcho.UseCustomEchoForCharacter; v != nil {
|
||||
settings.UseCustomEchoForCharacter = *v
|
||||
}
|
||||
if v := profile.KeyEcho.UseCustomEchoForWord; v != nil {
|
||||
settings.UseCustomEchoForWord = *v
|
||||
}
|
||||
if v := profile.KeyEcho.UseCustomEchoForSentence; v != nil {
|
||||
settings.UseCustomEchoForSentence = *v
|
||||
}
|
||||
if v := profile.KeyEcho.EchoVoice; v != nil {
|
||||
settings.EchoVoice = cloneVoice(*v)
|
||||
}
|
||||
if v := profile.KeyEcho.EchoSpeechServer; v != nil {
|
||||
settings.EchoSpeechServer = *v
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_reading(settings *Settings, profile writableProfile) {
|
||||
if value := profile.Presentation.Pronunciations; value != nil {
|
||||
settings.Pronunciations = append([]PronunciationEntry(nil), (*value)...)
|
||||
}
|
||||
if value := profile.Presentation.TextAttributes.Choices; value != nil {
|
||||
settings.TextAttributes.Choices = append([]TextAttributeChoice(nil), (*value)...)
|
||||
}
|
||||
if value := profile.Presentation.TextAttributes.Indicator; value != nil {
|
||||
settings.TextAttributes.Indicator = *value
|
||||
}
|
||||
if value := profile.Presentation.SpeakDescription; value != nil {
|
||||
settings.SpeakDescription = *value
|
||||
}
|
||||
if value := profile.Presentation.SpeechVerbosityLevel; value != nil {
|
||||
settings.SpeechVerbosityLevel = *value
|
||||
}
|
||||
if value := profile.Presentation.SayAllStyle; value != nil {
|
||||
settings.SayAllStyle = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.AutomaticallyReadClipboardChanges; value != nil {
|
||||
settings.Reading.AutomaticallyReadClipboardChanges = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.AutomaticallyReadTitleChanges; value != nil {
|
||||
settings.Reading.AutomaticallyReadTitleChanges = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.OnlySpeakDisplayedText; value != nil {
|
||||
settings.Reading.OnlySpeakDisplayedText = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.EnablePauseBreaks; value != nil {
|
||||
settings.Reading.EnablePauseBreaks = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakNumbersAsDigits; value != nil {
|
||||
settings.Reading.SpeakNumbersAsDigits = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakMultiCaseStringsAsWords; value != nil {
|
||||
settings.Reading.SpeakMultiCaseStringsAsWords = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.EnableIndentation; value != nil {
|
||||
settings.Reading.EnableIndentation = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.IndentationPresentationMode; value != nil {
|
||||
settings.Reading.IndentationPresentationMode = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakBlankLines; value != nil {
|
||||
settings.Reading.SpeakBlankLines = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.EnableMnemonicSpeaking; value != nil {
|
||||
settings.Reading.EnableMnemonicSpeaking = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.EnablePositionSpeaking; value != nil {
|
||||
settings.Reading.EnablePositionSpeaking = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.EnableTutorialMessages; value != nil {
|
||||
settings.Reading.EnableTutorialMessages = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.MessagesAreDetailed; value != nil {
|
||||
settings.Reading.MessagesAreDetailed = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.UseColorNames; value != nil {
|
||||
settings.Reading.UseColorNames = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.PresentTooltips; value != nil {
|
||||
settings.Reading.PresentTooltips = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.EnableMouseReview; value != nil {
|
||||
settings.Reading.EnableMouseReview = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakMisspelledIndicator; value != nil {
|
||||
settings.Reading.SpeakMisspelledIndicator = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakContextBlockquote; value != nil {
|
||||
settings.Reading.SpeakContextBlockquote = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakContextList; value != nil {
|
||||
settings.Reading.SpeakContextList = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakContextTable; value != nil {
|
||||
settings.Reading.SpeakContextTable = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakContextPanel; value != nil {
|
||||
settings.Reading.SpeakContextPanel = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakContextLandmark; value != nil {
|
||||
settings.Reading.SpeakContextLandmark = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SpeakContextNonLandmarkForm; value != nil {
|
||||
settings.Reading.SpeakContextNonLandmarkForm = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SayAllContextBlockquote; value != nil {
|
||||
settings.Reading.SayAllContextBlockquote = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SayAllContextList; value != nil {
|
||||
settings.Reading.SayAllContextList = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SayAllContextTable; value != nil {
|
||||
settings.Reading.SayAllContextTable = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SayAllContextPanel; value != nil {
|
||||
settings.Reading.SayAllContextPanel = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SayAllContextLandmark; value != nil {
|
||||
settings.Reading.SayAllContextLandmark = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.SayAllContextNonLandmarkForm; value != nil {
|
||||
settings.Reading.SayAllContextNonLandmarkForm = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.ReadFullRowInGUITable; value != nil {
|
||||
settings.Reading.ReadFullRowInGUITable = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.ReadFullRowInDocumentTable; value != nil {
|
||||
settings.Reading.ReadFullRowInDocumentTable = *value
|
||||
}
|
||||
if value := profile.Presentation.Reading.ReadFullRowInSpreadSheet; value != nil {
|
||||
settings.Reading.ReadFullRowInSpreadSheet = *value
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_output(settings *Settings, profile writableProfile) {
|
||||
if value := profile.Speech.Enabled; value != nil {
|
||||
settings.EnableSpeech = *value
|
||||
}
|
||||
if value := profile.Speech.HistoryLimit; value != nil {
|
||||
settings.SpeechHistoryLimit = *value
|
||||
}
|
||||
if value := profile.Braille.Enabled; value != nil {
|
||||
settings.EnableBraille = *value
|
||||
}
|
||||
if value := profile.Braille.Contracted; value != nil {
|
||||
settings.EnableContractedBraille = *value
|
||||
}
|
||||
if value := profile.Braille.ContractionTable; value != nil {
|
||||
settings.BrailleContractionTable = *value
|
||||
}
|
||||
if value := profile.Braille.AbbreviateRoles; value != nil {
|
||||
settings.Braille.AbbreviateRoles = *value
|
||||
}
|
||||
if value := profile.Braille.DisableEOL; value != nil {
|
||||
settings.Braille.DisableEOL = *value
|
||||
}
|
||||
if value := profile.Braille.WordWrap; value != nil {
|
||||
settings.Braille.WordWrap = *value
|
||||
}
|
||||
if value := profile.Braille.Verbosity; value != nil {
|
||||
settings.Braille.Verbosity = *value
|
||||
}
|
||||
if value := profile.Braille.SelectionIndicator; value != nil {
|
||||
settings.Braille.SelectionIndicator = *value
|
||||
}
|
||||
if value := profile.Braille.LinkIndicator; value != nil {
|
||||
settings.Braille.LinkIndicator = *value
|
||||
}
|
||||
if value := profile.Braille.FlashMessages; value != nil {
|
||||
settings.Braille.FlashMessages = *value
|
||||
}
|
||||
if value := profile.Braille.FlashTime; value != nil {
|
||||
settings.Braille.FlashTime = *value
|
||||
}
|
||||
if value := profile.Braille.FlashPersistent; value != nil {
|
||||
settings.Braille.FlashPersistent = *value
|
||||
}
|
||||
if value := profile.Braille.FlashDetailed; value != nil {
|
||||
settings.Braille.FlashDetailed = *value
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_speech(settings *Settings, profile writableProfile) {
|
||||
if value := profile.Speech.HardwareDevice; value != nil {
|
||||
settings.HardwareSpeechDevice = *value
|
||||
}
|
||||
if value := profile.Speech.HardwareBaudRate; value != nil {
|
||||
settings.HardwareSpeechBaudRate = *value
|
||||
}
|
||||
if value := profile.Speech.ServerFactory; value != nil {
|
||||
settings.SpeechServerFactory = *value
|
||||
}
|
||||
if value := profile.Speech.Punctuation; value != nil {
|
||||
settings.VerbalizePunctuationStyle = *value
|
||||
}
|
||||
if value := profile.Speech.Capitalization; value != nil {
|
||||
settings.CapitalizationStyle = *value
|
||||
}
|
||||
if value := profile.Speech.OutputModule; value != nil {
|
||||
settings.SpeechOutputModule = *value
|
||||
}
|
||||
if value := profile.Speech.DefaultVoice; value != nil {
|
||||
settings.DefaultVoice = cloneVoice(*value)
|
||||
}
|
||||
if value := profile.Speech.UppercaseVoice; value != nil {
|
||||
settings.UppercaseVoice = cloneVoice(*value)
|
||||
}
|
||||
if value := profile.Speech.HyperlinkVoice; value != nil {
|
||||
settings.HyperlinkVoice = cloneVoice(*value)
|
||||
}
|
||||
if value := profile.Speech.SystemVoice; value != nil {
|
||||
settings.SystemVoice = cloneVoice(*value)
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_sound(settings *Settings, profile writableProfile) {
|
||||
if value := profile.Sound.Enabled; value != nil {
|
||||
settings.EnableSound = *value
|
||||
}
|
||||
if value := profile.Sound.Volume; value != nil {
|
||||
settings.SoundVolume = *value
|
||||
}
|
||||
if value := profile.Sound.Sink; value != nil {
|
||||
settings.SoundSink = *value
|
||||
}
|
||||
if value := profile.Sound.Theme; value != nil {
|
||||
settings.SoundTheme = *value
|
||||
}
|
||||
if value := profile.Sound.PlayForRole; value != nil {
|
||||
settings.PlaySoundForRole = *value
|
||||
}
|
||||
if value := profile.Sound.PlayForState; value != nil {
|
||||
settings.PlaySoundForState = *value
|
||||
}
|
||||
if value := profile.Sound.PlayForPosition; value != nil {
|
||||
settings.PlaySoundForPositionInSet = *value
|
||||
}
|
||||
if value := profile.Sound.Spatialize; value != nil {
|
||||
settings.SpatializeObjectSounds = *value
|
||||
}
|
||||
if value := profile.Sound.RolePresentationStrategy; value != nil {
|
||||
settings.RoleSoundPresentation = *value
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_keyboard(settings *Settings, profile writableProfile) {
|
||||
if value := profile.Keyboard.Bindings; value != nil {
|
||||
settings.KeyBindings = input.CloneBindingOverrides(*value)
|
||||
}
|
||||
if value := profile.Keyboard.Layout; value != nil {
|
||||
settings.KeyboardLayout = *value
|
||||
}
|
||||
if value := profile.Keyboard.ScreenReaderKeys; value != nil {
|
||||
settings.CthulhuModifierKeys = append([]string(nil), (*value)...)
|
||||
}
|
||||
}
|
||||
|
||||
func apply_profile_echo_keys(settings *Settings, profile writableProfile) {
|
||||
if value := profile.KeyEcho.Enabled; value != nil {
|
||||
settings.EnableKeyEcho = *value
|
||||
}
|
||||
if value := profile.KeyEcho.ByCharacter; value != nil {
|
||||
settings.EnableEchoByCharacter = *value
|
||||
}
|
||||
if value := profile.KeyEcho.ByWord; value != nil {
|
||||
settings.EnableEchoByWord = *value
|
||||
}
|
||||
if value := profile.KeyEcho.BySentence; value != nil {
|
||||
settings.EnableEchoBySentence = *value
|
||||
}
|
||||
if value := profile.KeyEcho.Alphabetic; value != nil {
|
||||
settings.EnableAlphabeticKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.Numeric; value != nil {
|
||||
settings.EnableNumericKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.Punctuation; value != nil {
|
||||
settings.EnablePunctuationKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.Space; value != nil {
|
||||
settings.EnableSpace = *value
|
||||
}
|
||||
if value := profile.KeyEcho.Modifiers; value != nil {
|
||||
settings.EnableModifierKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.FunctionKeys; value != nil {
|
||||
settings.EnableFunctionKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.ActionKeys; value != nil {
|
||||
settings.EnableActionKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.NavigationKeys; value != nil {
|
||||
settings.EnableNavigationKeys = *value
|
||||
}
|
||||
if value := profile.KeyEcho.Diacritical; value != nil {
|
||||
settings.EnableDiacriticalKeys = *value
|
||||
}
|
||||
}
|
||||
|
||||
func boolPointer(value bool) *bool { return &value }
|
||||
|
||||
func intPointer(value int) *int { return &value }
|
||||
|
||||
func floatPointer(value float64) *float64 { return &value }
|
||||
|
||||
func stringPointer(value string) *string { return &value }
|
||||
|
||||
func stringSlicePointer(value []string) *[]string {
|
||||
copy := append([]string(nil), value...)
|
||||
return ©
|
||||
}
|
||||
|
||||
func pronunciationSlicePointer(value []PronunciationEntry) *[]PronunciationEntry {
|
||||
copy := append([]PronunciationEntry{}, value...)
|
||||
return ©
|
||||
}
|
||||
|
||||
func textAttributeSlicePointer(value []TextAttributeChoice) *[]TextAttributeChoice {
|
||||
copy := append([]TextAttributeChoice{}, value...)
|
||||
return ©
|
||||
}
|
||||
|
||||
func voicePointer(value Voice) *Voice { copy := cloneVoice(value); return © }
|
||||
|
||||
func bindingSlicePointer(value []input.BindingOverride) *[]input.BindingOverride {
|
||||
copy := input.CloneBindingOverrides(value)
|
||||
if copy == nil {
|
||||
copy = []input.BindingOverride{}
|
||||
}
|
||||
return ©
|
||||
}
|
||||
Reference in new issue
Block a user