fix: make pre/post fader metering switch label/tooltip translatable
[jack_mixer.git] / jack_mixer / gui.py
blobde921dbdf11027b2e27a3527c288e9a4fd4a1412
1 # This file is part of jack_mixer
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 import configparser
19 import logging
20 import os
22 import gi # noqa: F401
23 from gi.repository import GObject
25 try:
26 import xdg
27 from xdg import BaseDirectory
28 except ImportError:
29 xdg = None
31 from .serialization import SerializedObject
34 log = logging.getLogger(__name__)
37 def lookup_scale(scales, scale_id):
38 for scale in scales:
39 if scale_id == scale.scale_id:
40 return scale
41 return None
44 class Factory(GObject.GObject, SerializedObject):
45 def __init__(self, topwindow, meter_scales, slider_scales):
46 self.languages = [
47 (None, _("Use system setting")),
48 ("de", "Deutsch"),
49 ("en", "English"),
50 ("es", "Español"),
51 ("fr", "Français"),
53 self.midi_behavior_modes = ["Jump To Value", "Pick Up"]
54 GObject.GObject.__init__(self)
55 self.topwindow = topwindow
56 self.meter_scales = meter_scales
57 self.slider_scales = slider_scales
58 self.set_default_preferences()
59 if xdg:
60 self.config = configparser.ConfigParser()
61 self.path = os.path.join(
62 BaseDirectory.save_config_path("jack_mixer"), "preferences.ini"
64 if os.path.isfile(self.path):
65 self.read_preferences()
66 else:
67 self.write_preferences()
68 else:
69 log.warning(
70 _("Cannot load PyXDG. ")
71 + _("Your preferences will not be preserved across jack_mixer invocations.")
74 def set_default_preferences(self):
75 self.confirm_quit = False
76 self.default_meter_scale = self.meter_scales[0]
77 self.default_project_path = None
78 self.default_slider_scale = self.slider_scales[0]
79 self.language = None
80 self.midi_behavior_mode = 0
81 self.use_custom_widgets = False
82 self.vumeter_color = "#ccb300"
83 self.vumeter_color_scheme = "default"
84 self.auto_reset_peak_meters = False
85 self.auto_reset_peak_meters_time_seconds = 2.0
86 self.meter_refresh_period_milliseconds = 33
88 def read_preferences(self):
89 self.config.read(self.path)
90 self.confirm_quit = self.config.getboolean(
91 "Preferences", "confirm_quit", fallback=self.confirm_quit
94 scale_id = self.config["Preferences"]["default_meter_scale"]
95 self.default_meter_scale = lookup_scale(self.meter_scales, scale_id)
96 if not self.default_meter_scale:
97 self.default_meter_scale = self.meter_scales[0]
99 scale_id = self.config["Preferences"]["default_slider_scale"]
100 self.default_slider_scale = lookup_scale(self.slider_scales, scale_id)
101 if not self.default_slider_scale:
102 self.default_slider_scale = self.slider_scales[0]
104 self.default_project_path = self.config["Preferences"].get("default_project_path")
105 self.language = self.config["Preferences"].get("language")
107 try:
108 self.midi_behavior_mode = self.config.getint(
109 "Preferences", "midi_behavior_mode", fallback=self.midi_behavior_mode
111 except (TypeError, ValueError):
112 # use default value
113 pass
115 self.use_custom_widgets = self.config.getboolean(
116 "Preferences", "use_custom_widgets", fallback=self.use_custom_widgets
118 self.vumeter_color = self.config.get(
119 "Preferences", "vumeter_color", fallback=self.vumeter_color
121 self.vumeter_color_scheme = self.config.get(
122 "Preferences", "vumeter_color_scheme", fallback=self.vumeter_color_scheme
124 self.auto_reset_peak_meters = self.config.getboolean(
125 "Preferences", "auto_reset_peak_meters", fallback=self.auto_reset_peak_meters
127 self.auto_reset_peak_meters_time_seconds = self.config.getfloat(
128 "Preferences", "auto_reset_peak_meters_time_seconds",
129 fallback=self.auto_reset_peak_meters_time_seconds
131 self.meter_refresh_period_milliseconds = self.config.getint(
132 "Preferences", "meter_refresh_period_milliseconds",
133 fallback=self.meter_refresh_period_milliseconds
136 def write_preferences(self):
137 self.config["Preferences"] = {}
138 self.config["Preferences"]["confirm_quit"] = str(self.confirm_quit)
139 self.config["Preferences"]["default_meter_scale"] = self.default_meter_scale.scale_id
140 self.config["Preferences"]["default_project_path"] = self.default_project_path or ""
141 self.config["Preferences"]["default_slider_scale"] = self.default_slider_scale.scale_id
142 self.config["Preferences"]["language"] = self.language or ""
143 self.config["Preferences"]["midi_behavior_mode"] = str(self.midi_behavior_mode)
144 self.config["Preferences"]["use_custom_widgets"] = str(self.use_custom_widgets)
145 self.config["Preferences"]["vumeter_color"] = self.vumeter_color
146 self.config["Preferences"]["vumeter_color_scheme"] = self.vumeter_color_scheme
147 self.config["Preferences"]["auto_reset_peak_meters"] = str(self.auto_reset_peak_meters)
148 self.config["Preferences"]["auto_reset_peak_meters_time_seconds"] = \
149 str(self.auto_reset_peak_meters_time_seconds)
150 self.config["Preferences"]["meter_refresh_period_milliseconds"] = \
151 str(self.meter_refresh_period_milliseconds)
153 with open(self.path, "w") as configfile:
154 self.config.write(configfile)
155 configfile.close()
157 def _update_setting(self, name, value):
158 if value != getattr(self, name):
159 setattr(self, name, value)
160 if xdg:
161 self.write_preferences()
162 signal = "{}-changed".format(name.replace("_", "-"))
163 self.emit(signal, value)
165 def set_confirm_quit(self, confirm_quit):
166 self._update_setting("confirm_quit", confirm_quit)
168 def set_default_meter_scale(self, scale):
169 if scale:
170 self._update_setting("default_meter_scale", scale)
171 else:
172 log.warning(
173 _("Ignoring default_meter_scale setting, because '%s' scale is not known."), scale
176 def set_default_project_path(self, path):
177 self._update_setting("default_project_path", path)
179 def set_default_slider_scale(self, scale):
180 if scale:
181 self._update_setting("default_slider_scale", scale)
182 else:
183 log.warning(
184 _("Ignoring default_slider_scale setting, because '%s' scale is not known."), scale
187 def set_language(self, lang):
188 self._update_setting("language", lang)
190 def set_midi_behavior_mode(self, mode):
191 self._update_setting("midi_behavior_mode", int(mode))
193 def set_use_custom_widgets(self, use_custom):
194 self._update_setting("use_custom_widgets", use_custom)
196 def set_vumeter_color(self, color):
197 self._update_setting("vumeter_color", color)
199 def set_vumeter_color_scheme(self, color_scheme):
200 self._update_setting("vumeter_color_scheme", color_scheme)
202 def set_auto_reset_peak_meters(self, auto_reset):
203 self._update_setting("auto_reset_peak_meters", auto_reset)
205 def set_auto_reset_peak_meters_time_seconds(self, time):
206 self._update_setting("auto_reset_peak_meters_time_seconds", time)
208 def set_meter_refresh_period_milliseconds(self, period):
209 self._update_setting("meter_refresh_period_milliseconds", period)
211 def get_confirm_quit(self):
212 return self.confirm_quit
214 def get_default_meter_scale(self):
215 return self.default_meter_scale
217 def get_default_project_path(self):
218 if self.default_project_path:
219 return os.path.expanduser(self.default_project_path)
220 elif xdg:
221 return BaseDirectory.save_data_path("jack_mixer")
223 def get_default_slider_scale(self):
224 return self.default_slider_scale
226 def get_language(self):
227 return self.language
229 def get_midi_behavior_mode(self):
230 return self.midi_behavior_mode
232 def get_use_custom_widgets(self):
233 return self.use_custom_widgets
235 def get_vumeter_color(self):
236 return self.vumeter_color
238 def get_vumeter_color_scheme(self):
239 return self.vumeter_color_scheme
241 def get_auto_reset_peak_meters(self):
242 return self.auto_reset_peak_meters
244 def get_auto_reset_peak_meters_time_seconds(self):
245 return self.auto_reset_peak_meters_time_seconds
247 def get_meter_refresh_period_milliseconds(self):
248 return self.meter_refresh_period_milliseconds
250 def emit_midi_behavior_mode(self):
251 self.emit("midi-behavior-mode-changed", self.midi_behavior_mode)
253 @classmethod
254 def serialization_name(cls):
255 return "gui_factory"
257 def serialize(self, object_backend):
258 object_backend.add_property("confirm-quit", str(self.get_confirm_quit()))
259 object_backend.add_property("default_meter_scale", self.get_default_meter_scale().scale_id)
260 # serialize the value, even if it's empty, not the default fallback directories
261 object_backend.add_property("default_project_path", self.default_project_path or "")
262 object_backend.add_property(
263 "default_slider_scale", self.get_default_slider_scale().scale_id
265 object_backend.add_property("midi_behavior_mode", str(self.get_midi_behavior_mode()))
266 object_backend.add_property("use_custom_widgets", str(self.get_use_custom_widgets()))
267 object_backend.add_property("vumeter_color", self.get_vumeter_color())
268 object_backend.add_property("vumeter_color_scheme", self.get_vumeter_color_scheme())
269 object_backend.add_property(
270 "auto_reset_peak_meters", str(self.get_auto_reset_peak_meters())
272 object_backend.add_property(
273 "auto_reset_peak_meters_time_seconds", str(
274 self.get_auto_reset_peak_meters_time_seconds()
277 object_backend.add_property(
278 "meter_refresh_period_milliseconds", str(
279 self.get_meter_refresh_period_milliseconds()
283 def unserialize_property(self, name, value):
284 if name == "confirm_quit":
285 self.set_confirm_quit(value == "True")
286 return True
287 elif name == "default_meter_scale":
288 self.set_default_meter_scale(lookup_scale(self.meter_scales, value))
289 return True
290 elif name == "default_project_path":
291 self.set_default_project_path(value or None)
292 return True
293 elif name == "default_slider_scale":
294 self.set_default_slider_scale(lookup_scale(self.slider_scales, value))
295 return True
296 elif name == "midi_behavior_mode":
297 self.set_midi_behavior_mode(int(value))
298 return True
299 elif name == "use_custom_widgets":
300 self.set_use_custom_widgets(value == "True")
301 return True
302 elif name == "vumeter_color":
303 self.set_vumeter_color(value)
304 return True
305 elif name == "vumeter_color_scheme":
306 self.set_vumeter_color_scheme(value)
307 return True
308 elif name == "auto_reset_peak_meters":
309 self.set_auto_reset_peak_meters(value)
310 return True
311 elif name == "auto_reset_peak_meters_time_seconds":
312 self.set_auto_reset_peak_meters_time_seconds(float(value))
313 return True
314 elif name == "meter_refresh_period_milliseconds":
315 self.set_meter_refresh_period_milliseconds(int(value))
316 return False
319 GObject.signal_new(
320 "confirm-quit-changed",
321 Factory,
322 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
323 None,
324 [bool],
326 GObject.signal_new(
327 "default-meter-scale-changed",
328 Factory,
329 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
330 None,
331 [GObject.TYPE_PYOBJECT],
333 GObject.signal_new(
334 "default-project-path-changed",
335 Factory,
336 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
337 None,
338 [str],
340 GObject.signal_new(
341 "default-slider-scale-changed",
342 Factory,
343 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
344 None,
345 [GObject.TYPE_PYOBJECT],
347 GObject.signal_new(
348 "language-changed",
349 Factory,
350 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
351 None,
352 [str],
354 GObject.signal_new(
355 "midi-behavior-mode-changed",
356 Factory,
357 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
358 None,
359 [int],
361 GObject.signal_new(
362 "use-custom-widgets-changed",
363 Factory,
364 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
365 None,
366 [bool],
368 GObject.signal_new(
369 "vumeter-color-changed",
370 Factory,
371 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
372 None,
373 [str],
375 GObject.signal_new(
376 "vumeter-color-scheme-changed",
377 Factory,
378 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
379 None,
380 [str],
382 GObject.signal_new(
383 "auto-reset-peak-meters-changed",
384 Factory,
385 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
386 None,
387 [bool],
389 GObject.signal_new(
390 "auto-reset-peak-meters-time-seconds-changed",
391 Factory,
392 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
393 None,
394 [float],
396 GObject.signal_new(
397 "meter-refresh-period-milliseconds-changed",
398 Factory,
399 GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
400 None,
401 [int],