Coverage for src/robotide/ui/preferences_dialogs.py: 48%
190 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
1# Copyright 2008-2015 Nokia Networks
2# Copyright 2016- Robot Framework Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
16import builtins 1ab
17import textwrap 1ab
19import wx 1ab
21from ..context import IS_LINUX 1ab
22from ..widgets import HelpLabel, Label, TextField 1ab
24_ = wx.GetTranslation # To keep linter/code analyser happy 1ab
25builtins.__dict__['_'] = wx.GetTranslation 1ab
28class PreferencesPanel(wx.Panel): 1ab
29 """Base class for all preference panels used by PreferencesDialog"""
31 def __init__(self, parent=None, name_tr=None, *args, **kwargs): 1ab
32 self.tree_item = None 1c
33 self.name_tr = name_tr 1c
34 from ..preferences.settings import RideSettings 1c
35 wx.Panel.__init__(self, parent, *args, **kwargs) 1c
36 self._gsettings = RideSettings() 1c
37 self.settings = self._gsettings['General'] 1c
38 self.background_color = self.settings['background'] 1c
39 self.foreground_color = self.settings['foreground'] 1c
40 self.secondary_background_color = self.settings['secondary background'] 1c
41 self.secondary_foreground_color = self.settings['secondary foreground'] 1c
42 self.SetBackgroundColour(self.background_color) 1c
43 self.SetForegroundColour(self.foreground_color) 1c
45 def GetTitle(self): 1ab
46 return getattr(self, "title", self.location[-1])
48 def Separator(self, parent, title): 1ab
49 """Creates a simple horizontal separator with title"""
50 container = wx.Panel(parent, wx.ID_ANY)
51 label = wx.StaticText(container, wx.ID_ANY, label=title)
52 label.SetBackgroundColour(self.background_color)
53 label.SetForegroundColour(self.foreground_color)
54 sep = wx.StaticLine(container, wx.ID_ANY)
55 sep.SetBackgroundColour(self.secondary_background_color)
56 sep.SetForegroundColour(self.secondary_foreground_color)
57 sizer = wx.BoxSizer(wx.VERTICAL)
58 sizer.Add(label, 0, wx.EXPAND|wx.TOP, 8)
59 sizer.Add(sep, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 2)
60 container.SetSizerAndFit(sizer)
61 return container
64class PreferencesComboBox(wx.ComboBox): 1ab
65 """A combobox tied to a specific setting. Saves value to disk after edit."""
66 def __init__(self, parent, elid, settings, key, choices): 1ab
67 self.settings = settings 1c
68 self.key = key 1c
69 from ..preferences.settings import RideSettings 1c
70 super(PreferencesComboBox, self).__init__(parent, elid, self._get_value(), 1c
71 size=self._get_size(choices),
72 choices=choices, style=wx.CB_READONLY)
73 self._gsettings = RideSettings() 1c
74 self.gsettings = self._gsettings['General'] 1c
75 background_color = self.gsettings['secondary background'] 1c
76 foreground_color = self.gsettings['secondary foreground'] 1c
77 self.SetBackgroundColour(background_color) 1c
78 self.SetForegroundColour(foreground_color) 1c
79 self.Bind(wx.EVT_COMBOBOX, self.on_select) 1c
81 def _get_value(self): 1ab
82 return self.settings[self.key]
84 @staticmethod 1ab
85 def _get_size(choices=None): 1ab
86 """ In Linux with GTK3 wxPython 4, there was not enough spacing.
87 The value 72 is there for 2 digits numeric lists, for
88 IntegerPreferenceComboBox.
89 This issue only occurs in Linux, for Mac and Windows using default size.
90 """
91 if IS_LINUX and isinstance(choices, list): 91 ↛ 92line 91 didn't jump to line 92 because the condition on line 91 was never true1c
92 return wx.Size(max(max(len(str(s)) for s in choices) * 9, 144), 30)
93 return wx.DefaultSize 1c
95 def on_select(self, event): 1ab
96 self._set_value(str(event.GetEventObject().GetValue()))
97 self.settings.save()
99 def _set_value(self, value): 1ab
100 self.settings[self.key] = value
103class IntegerPreferenceComboBox(PreferencesComboBox): 1ab
104 """A combobox tied to a setting that has integer values."""
106 def _get_value(self): 1ab
107 return str(self.settings[self.key]) 1c
109 def _set_value(self, value): 1ab
110 self.settings[self.key] = int(value)
113class PreferencesSpinControl(wx.SpinCtrl): 1ab
114 """A spin control tied to a specific setting. Saves value to disk after edit."""
116 def __init__(self, parent, elid, settings, key, choices): 1ab
117 self.settings = settings
118 self.key = key
119 from ..preferences.settings import RideSettings
120 super(PreferencesSpinControl, self).__init__(parent, elid,
121 size=self._get_size(choices[-1]))
123 self._gsettings = RideSettings()
124 self.psettings = self._gsettings['General']
125 background_color = self.psettings['background']
126 foreground_color = self.psettings['foreground']
127 self.SetBackgroundColour(background_color)
128 self.SetForegroundColour(foreground_color)
129 self.SetRange(*choices)
130 self.SetValue(self._get_value())
131 self.Bind(wx.EVT_SPINCTRL, self.on_change)
132 self.Bind(wx.EVT_TEXT, self.on_change)
134 def _get_value(self): 1ab
135 return self.settings[self.key]
137 @staticmethod 1ab
138 def _get_size(max_value): 1ab
139 """ In Linux with GTK3 wxPython 4, there was not enough spacing.
140 The value 72 is there for 2 digits numeric lists, for
141 IntegerPreferenceComboBox.
142 This issue only occurs in Linux, for Mac and Windows using default size.
143 """
144 if IS_LINUX and max_value:
145 return wx.Size(max(len(str(max_value)) * 9, 144), 20)
146 return wx.DefaultSize
148 def on_change(self, event): 1ab
149 self._set_value(event.GetEventObject().GetValue())
150 self.settings.save()
152 def _set_value(self, value): 1ab
153 self.settings[self.key] = value
156class PreferencesColorPicker(wx.ColourPickerCtrl): 1ab
157 """A colored button that opens a color picker dialog"""
158 def __init__(self, parent, elid, settings, key): 1ab
159 self.settings = settings
160 self.key = key
161 # print(f"DEBUG: Preferences ColourPicker value type {type(settings[key])}")
162 value = wx.Colour(settings[key])
163 from ..preferences.settings import RideSettings
164 super(PreferencesColorPicker, self).__init__(parent, elid, colour=value)
165 self._gsettings = RideSettings()
166 self.psettings = self._gsettings['General']
167 background_color = self.psettings['background']
168 foreground_color = self.psettings['foreground']
169 self.SetBackgroundColour(background_color)
170 self.SetForegroundColour(foreground_color)
171 self.Bind(wx.EVT_COLOURPICKER_CHANGED, self.on_pick_color)
173 def on_pick_color(self, event): 1ab
174 """Set the color for the given key to the color of the widget"""
175 color = event.GetColour()
176 rgb = color.GetAsString(flags=wx.C2S_HTML_SYNTAX)
177 self.settings[self.key] = rgb
178 self.settings.save()
180 def SetColour(self, colour): 1ab
181 super(PreferencesColorPicker, self).SetColour(colour)
182 self.settings[self.key] = colour
183 self.settings.save()
186class _ChoiceEditor(object): 1ab
187 _editor_class = None 1ab
189 def __init__(self, settings, setting_name, label, choices, elhelp=''): 1ab
190 self._settings = settings 1c
191 self._setting_name = setting_name 1c
192 self._label = label 1c
193 self._choices = choices 1c
194 self._help = elhelp 1c
195 from ..preferences.settings import RideSettings 1c
196 self._gsettings = RideSettings() 1c
197 self.csettings = self._gsettings['General'] 1c
198 self.background_color = self.csettings['background'] 1c
199 self.foreground_color = self.csettings['foreground'] 1c
201 def chooser(self, parent): 1ab
202 element = self._editor_class(parent, wx.NewId(), self._settings, 1c
203 key=self._setting_name, choices=self._choices)
204 element.SetBackgroundColour(self.background_color) 1c
205 element.SetForegroundColour(self.foreground_color) 1c
206 return element 1c
208 def label(self, parent): 1ab
209 llabel = wx.StaticText(parent, wx.NewId(), self._label) 1c
210 llabel.SetBackgroundColour(self.background_color) 1c
211 llabel.SetForegroundColour(self.foreground_color) 1c
212 return llabel 1c
214 def help(self, parent): 1ab
215 return HelpLabel(parent, '\n'.join(textwrap.wrap(self._help, 60)))
218class StringChoiceEditor(_ChoiceEditor): 1ab
219 _editor_class = PreferencesComboBox 1ab
221 def SetSelection(self, combo, idx): 1ab
222 self._editor_class.SetSelection(combo, idx)
225class IntegerChoiceEditor(_ChoiceEditor): 1ab
226 _editor_class = IntegerPreferenceComboBox 1ab
229class SpinChoiceEditor(_ChoiceEditor): 1ab
230 _editor_class = PreferencesSpinControl 1ab
233def boolean_editor(parent, settings, name, label, elhelp=''): 1ab
234 editor = _create_checkbox_editor(parent, settings, name, elhelp)
235 from ..preferences.settings import RideSettings
236 _gsettings = RideSettings()
237 bsettings = _gsettings['General']
238 background_color = bsettings['background']
239 foreground_color = bsettings['foreground']
240 editor.SetBackgroundColour(background_color)
241 editor.SetForegroundColour(foreground_color)
242 blabel = Label(parent, label=label)
243 blabel.SetBackgroundColour(background_color)
244 blabel.SetForegroundColour(foreground_color)
245 return blabel, editor
248def _create_checkbox_editor(parent, settings, name, elhelp): 1ab
249 initial_value = settings.get(name, "")
250 editor = wx.CheckBox(parent)
251 editor.SetValue(initial_value)
252 editor.Bind(wx.EVT_CHECKBOX, lambda evt: settings.set(name, editor.GetValue()))
253 editor.SetToolTip(elhelp)
254 return editor
257def comma_separated_value_editor(parent, settings, name, label, thelp=''): 1ab
258 initial_value = ', '.join(settings.get(name, ""))
259 editor = TextField(parent, initial_value)
260 from ..preferences.settings import RideSettings
261 _gsettings = RideSettings()
262 esettings = _gsettings['General']
263 background_color = esettings['background']
264 foreground_color = esettings['foreground']
265 editor.SetBackgroundColour(background_color)
266 editor.SetForegroundColour(foreground_color)
267 editor.SetToolTip(thelp)
269 def set_value(evt):
270 new_value = [token.strip() for token in editor.GetValue().split(',')
271 if token.strip()]
272 settings.set(name, new_value)
273 evt.Skip()
274 editor.Bind(wx.EVT_KILL_FOCUS, lambda evt: set_value(evt))
275 elabel = Label(parent, label=label)
276 elabel.SetBackgroundColour(background_color)
277 elabel.SetForegroundColour(foreground_color)
278 return elabel, editor