fix: make pre/post fader metering switch label/tooltip translatable
[jack_mixer.git] / jack_mixer / preferences.py
blob920fbf66e814c506ec3c660d5e32cf4e23aa24f2
1 # This file is part of jack_mixer
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
4 # Copyright (C) 2009 Frederic Peters <fpeters@0d.be>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; version 2 of the License
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 from os.path import expanduser, isdir
21 from gi.repository import Gtk
22 from gi.repository import Gdk
23 from gi.repository import GObject
26 class PreferencesDialog(Gtk.Dialog):
27 def __init__(self, parent):
28 self.app = parent
29 GObject.GObject.__init__(self)
30 self.set_title(_("Preferences"))
31 self.create_ui()
32 self.connect("response", self.on_response_cb)
33 self.connect("delete-event", self.on_response_cb)
35 def create_frame(self, label, child):
36 frame = Gtk.Frame()
37 frame.set_label("")
38 frame.set_border_width(3)
39 frame.set_shadow_type(Gtk.ShadowType.NONE)
40 frame.get_label_widget().set_markup("<b>%s</b>" % label)
42 child.set_margin_top(10)
43 child.set_margin_bottom(10)
44 frame.add(child)
46 return frame
48 def create_ui(self):
49 vbox = self.get_content_area()
51 path_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
52 path_vbox.set_tooltip_text(
53 _("Set the path where mixer project files are saved and loaded from by default")
55 self.path_entry = Gtk.Entry()
56 self.path_entry.connect("changed", self.on_path_entry_changed)
57 path_vbox.pack_start(self.path_entry, False, False, 3)
58 self.project_path_chooser = Gtk.FileChooserButton(
59 title=_("Default Project Path"), action=Gtk.FileChooserAction.SELECT_FOLDER
61 project_path = self.app.gui_factory.default_project_path
62 path_vbox.pack_start(self.project_path_chooser, False, False, 3)
64 if project_path:
65 self.path_entry.set_text(project_path)
67 if isdir(expanduser(project_path)):
68 self.project_path_chooser.set_current_folder(expanduser(project_path))
70 self.project_path_chooser.connect("file-set", self.on_project_path_selected)
71 vbox.pack_start(self.create_frame(_("Default Project Path"), path_vbox), True, True, 0)
73 interface_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
75 self.language_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
76 self.language_box.set_tooltip_text(_("Set the interface language and localisation"))
77 self.language_combo = self.create_language_combo()
78 interface_vbox.pack_start(self.language_box, True, True, 3)
80 self.language_box.pack_start(Gtk.Label(_("Language:")), False, True, 5)
81 self.language_box.pack_start(self.language_combo, True, True, 0)
83 self.confirm_quit_checkbutton = Gtk.CheckButton(_("Confirm quit"))
84 self.confirm_quit_checkbutton.set_tooltip_text(
85 _("Always ask for confirmation before quitting the application")
87 self.confirm_quit_checkbutton.set_active(self.app.gui_factory.get_confirm_quit())
88 self.confirm_quit_checkbutton.connect("toggled", self.on_confirm_quit_toggled)
89 interface_vbox.pack_start(self.confirm_quit_checkbutton, True, True, 3)
91 self.custom_widgets_checkbutton = Gtk.CheckButton(_("Use custom widgets"))
92 self.custom_widgets_checkbutton.set_tooltip_text(
93 _("Use widgets with custom design for the channel sliders")
95 self.custom_widgets_checkbutton.set_active(self.app.gui_factory.get_use_custom_widgets())
96 self.custom_widgets_checkbutton.connect("toggled", self.on_custom_widget_toggled)
97 interface_vbox.pack_start(self.custom_widgets_checkbutton, True, True, 3)
99 color_tooltip = _("Draw the volume meters with the selected solid color")
100 self.vumeter_color_checkbutton = Gtk.CheckButton(_("Use custom vumeter color"))
101 self.vumeter_color_checkbutton.set_tooltip_text(color_tooltip)
102 self.vumeter_color_checkbutton.set_active(
103 self.app.gui_factory.get_vumeter_color_scheme() == "solid"
105 self.vumeter_color_checkbutton.connect("toggled", self.on_vumeter_color_change)
106 interface_vbox.pack_start(self.vumeter_color_checkbutton, True, True, 3)
108 self.custom_color_box = hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
109 self.custom_color_box.set_tooltip_text(color_tooltip)
110 interface_vbox.pack_start(hbox, True, True, 3)
112 hbox.set_sensitive(self.vumeter_color_checkbutton.get_active())
113 hbox.pack_start(Gtk.Label(_("Custom color:")), False, True, 5)
114 self.vumeter_color_picker = Gtk.ColorButton()
115 self.vumeter_color_picker.set_color(
116 Gdk.color_parse(self.app.gui_factory.get_vumeter_color())
118 self.vumeter_color_picker.connect("color-set", self.on_vumeter_color_change)
119 hbox.pack_start(self.vumeter_color_picker, True, True, 0)
121 reset_peak_meter_tooltip = _("Reset the peak meters after the specified time")
122 self.auto_reset_peak_meters_checkbutton = Gtk.CheckButton(_("Auto reset peak meter"))
123 self.auto_reset_peak_meters_checkbutton.set_tooltip_text(reset_peak_meter_tooltip)
124 self.auto_reset_peak_meters_checkbutton.set_active(
125 self.app.gui_factory.get_auto_reset_peak_meters()
127 self.auto_reset_peak_meters_checkbutton.connect(
128 "toggled", self.on_auto_reset_peak_meters_toggled
130 interface_vbox.pack_start(self.auto_reset_peak_meters_checkbutton, True, True, 3)
132 self.auto_reset_peak_meters_time_seconds_box = hbox = Gtk.Box(
133 orientation=Gtk.Orientation.HORIZONTAL
135 self.auto_reset_peak_meters_time_seconds_box.set_tooltip_text(reset_peak_meter_tooltip)
136 interface_vbox.pack_start(hbox, True, True, 3)
138 hbox.set_sensitive(self.auto_reset_peak_meters_checkbutton.get_active())
139 hbox.pack_start(Gtk.Label(_("Time (s):")), False, True, 5)
140 self.auto_reset_peak_meters_time_seconds_spinbutton = (
141 spinbutton
142 ) = self.create_auto_reset_peak_meters_time_seconds_spinbutton()
143 hbox.pack_start(spinbutton, True, True, 0)
145 self.meter_refresh_period_milliseconds_box = hbox = Gtk.Box(
146 orientation=Gtk.Orientation.HORIZONTAL
148 self.meter_refresh_period_milliseconds_box.set_tooltip_text(
149 _("Update the volume level meters with the specified interval in milliseconds")
151 interface_vbox.pack_start(hbox, True, True, 3)
152 hbox.pack_start(Gtk.Label(_("Meter Refresh Period (ms):")), False, True, 5)
153 self.meter_refresh_period_milliseconds_spinbutton = (
154 spinbutton
155 ) = self.create_meter_refresh_period_milliseconds_spinbutton()
156 hbox.pack_start(spinbutton, True, True, 0)
158 vbox.pack_start(self.create_frame(_("Interface"), interface_vbox), True, True, 0)
160 table = Gtk.Table(2, 2, False)
161 table.set_row_spacings(5)
162 table.set_col_spacings(5)
164 meter_scale_tooltip = _("Set the scale for all volume meters")
165 meter_scale_label = Gtk.Label(label=_("Meter scale:"))
166 meter_scale_label.set_tooltip_text(meter_scale_tooltip)
167 table.attach(meter_scale_label, 0, 1, 0, 1)
168 self.meter_scale_combo = self.create_meter_store_and_combo()
169 self.meter_scale_combo.set_tooltip_text(meter_scale_tooltip)
170 table.attach(self.meter_scale_combo, 1, 2, 0, 1)
172 slider_scale_tooltip = _("Set the scale for all volume sliders")
173 slider_scale_label = Gtk.Label(label=_("Slider scale:"))
174 slider_scale_label.set_tooltip_text(slider_scale_tooltip)
175 table.attach(slider_scale_label, 0, 1, 1, 2)
176 self.slider_scale_combo = self.create_slider_store_and_combo()
177 self.slider_scale_combo.set_tooltip_text(slider_scale_tooltip)
178 table.attach(self.slider_scale_combo, 1, 2, 1, 2)
180 vbox.pack_start(self.create_frame(_("Scales"), table), True, True, 0)
182 table = Gtk.Table(1, 2, False)
183 table.set_row_spacings(5)
184 table.set_col_spacings(5)
186 midi_behavior_tooltip = _(
187 "Set how channel volume and balance are controlled via MIDI:\n\n"
188 "- Jump To Value: channel volume or balance is set immediately to received controller value\n"
189 "- Pick Up: control changes are ignored until a controller value near the current value is received\n"
191 midi_behavior_label = Gtk.Label(label=_("Control Behavior:"))
192 midi_behavior_label.set_tooltip_text(midi_behavior_tooltip)
193 table.attach(midi_behavior_label, 0, 1, 0, 1)
194 self.midi_behavior_combo = self.create_midi_behavior_combo()
195 self.midi_behavior_combo.set_tooltip_text(midi_behavior_tooltip)
196 table.attach(self.midi_behavior_combo, 1, 2, 0, 1)
198 vbox.pack_start(self.create_frame(_("MIDI"), table), True, True, 0)
199 self.vbox.show_all()
201 self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
203 def create_language_combo(self):
204 combo = Gtk.ComboBoxText()
205 for code, name in self.app.gui_factory.languages:
206 combo.append(code or "", name)
207 combo.set_active_id(self.app.gui_factory.get_language() or "")
208 combo.connect("changed", self.on_language_combo_changed)
209 return combo
211 def create_meter_store_and_combo(self):
212 store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_PYOBJECT)
213 for scale in self.app.meter_scales:
214 row = scale.scale_id, scale
215 current_iter = store.append(row)
216 if scale is self.app.gui_factory.get_default_meter_scale():
217 active_iter = current_iter
218 self.meter_store = store
220 meter_scale_combo = Gtk.ComboBox.new_with_model(store)
221 cell = Gtk.CellRendererText()
222 meter_scale_combo.pack_start(cell, True)
223 meter_scale_combo.add_attribute(cell, "text", 0)
224 meter_scale_combo.set_active_iter(active_iter)
225 meter_scale_combo.connect("changed", self.on_meter_scale_combo_changed)
227 return meter_scale_combo
229 def create_slider_store_and_combo(self):
230 store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_PYOBJECT)
231 for scale in self.app.slider_scales:
232 row = scale.scale_id, scale
233 current_iter = store.append(row)
234 if scale is self.app.gui_factory.get_default_slider_scale():
235 active_iter = current_iter
236 self.slider_store = store
238 slider_scale_combo = Gtk.ComboBox.new_with_model(store)
239 cell = Gtk.CellRendererText()
240 slider_scale_combo.pack_start(cell, True)
241 slider_scale_combo.add_attribute(cell, "text", 0)
242 slider_scale_combo.set_active_iter(active_iter)
243 slider_scale_combo.connect("changed", self.on_slider_scale_combo_changed)
245 return slider_scale_combo
247 def create_midi_behavior_combo(self):
248 combo = Gtk.ComboBoxText()
249 for i, mode in enumerate(self.app.gui_factory.midi_behavior_modes):
250 combo.append(str(i), mode)
251 combo.set_active(self.app.gui_factory.get_midi_behavior_mode())
252 combo.connect("changed", self.on_midi_behavior_combo_changed)
253 return combo
255 def create_auto_reset_peak_meters_time_seconds_spinbutton(self):
256 adjustment = Gtk.Adjustment(
257 value=float(self.app.gui_factory.get_auto_reset_peak_meters_time_seconds()),
258 lower=0.1,
259 upper=10.0,
260 step_increment=0.1,
261 page_increment=0.5,
262 page_size=0.0,
264 spinbutton = Gtk.SpinButton(adjustment=adjustment, climb_rate=1.0, digits=1)
265 spinbutton.connect("value-changed", self.on_peak_reset_spinbutton_changed)
266 return spinbutton
268 def create_meter_refresh_period_milliseconds_spinbutton(self):
269 adjustment = Gtk.Adjustment(
270 value=int(self.app.gui_factory.get_meter_refresh_period_milliseconds()),
271 lower=1,
272 upper=1000,
273 step_increment=1,
274 page_increment=10,
276 spinbutton = Gtk.SpinButton(adjustment=adjustment)
277 spinbutton.connect("value-changed", self.on_meter_refresh_spinbutton_changed)
278 return spinbutton
280 def on_response_cb(self, dlg, response_id, *args):
281 self.app.preferences_dialog = None
282 self.destroy()
284 def on_path_entry_changed(self, *args):
285 path = self.path_entry.get_text().strip()
287 if path:
288 fullpath = expanduser(path)
290 if isdir(fullpath):
291 self.project_path_chooser.set_current_folder(fullpath)
292 self.app.gui_factory.set_default_project_path(path)
294 def on_project_path_selected(self, path_chooser):
295 path = path_chooser.get_filename()
296 self.path_entry.set_text(path)
297 self.app.gui_factory.set_default_project_path(path)
299 def on_language_combo_changed(self, *args):
300 code = self.language_combo.get_active_id()
301 if code != self.app.gui_factory.get_language():
302 self.app.gui_factory.set_language(code)
303 dlg = Gtk.MessageDialog(
304 parent=self,
305 modal=True,
306 destroy_with_parent=True,
307 message_type=Gtk.MessageType.WARNING,
308 buttons=Gtk.ButtonsType.OK,
309 text=_("You need to restart the application for this setting to take effect."),
311 dlg.run()
312 dlg.destroy()
314 def on_meter_scale_combo_changed(self, *args):
315 active_iter = self.meter_scale_combo.get_active_iter()
316 scale = self.meter_store.get(active_iter, 1)[0]
317 self.app.gui_factory.set_default_meter_scale(scale)
319 def on_slider_scale_combo_changed(self, *args):
320 active_iter = self.slider_scale_combo.get_active_iter()
321 scale = self.slider_store.get(active_iter, 1)[0]
322 self.app.gui_factory.set_default_slider_scale(scale)
324 def on_midi_behavior_combo_changed(self, *args):
325 active = self.midi_behavior_combo.get_active()
326 self.app.gui_factory.set_midi_behavior_mode(active)
328 def on_vumeter_color_change(self, *args):
329 color_scheme = "default"
330 if self.vumeter_color_checkbutton.get_active():
331 color_scheme = "solid"
332 self.app.gui_factory.set_vumeter_color_scheme(color_scheme)
334 color = self.vumeter_color_picker.get_color().to_string()
335 self.app.gui_factory.set_vumeter_color(color)
337 self.custom_color_box.set_sensitive(self.vumeter_color_checkbutton.get_active())
339 def on_confirm_quit_toggled(self, *args):
340 self.app.gui_factory.set_confirm_quit(self.confirm_quit_checkbutton.get_active())
342 def on_custom_widget_toggled(self, *args):
343 self.app.gui_factory.set_use_custom_widgets(self.custom_widgets_checkbutton.get_active())
345 def on_auto_reset_peak_meters_toggled(self, *args):
346 self.app.gui_factory.set_auto_reset_peak_meters(
347 self.auto_reset_peak_meters_checkbutton.get_active()
350 self.auto_reset_peak_meters_time_seconds_box.set_sensitive(
351 self.auto_reset_peak_meters_checkbutton.get_active()
354 def on_peak_reset_spinbutton_changed(self, *args):
355 self.app.gui_factory.set_auto_reset_peak_meters_time_seconds(
356 self.auto_reset_peak_meters_time_seconds_spinbutton.get_value()
359 def on_meter_refresh_spinbutton_changed(self, *args):
360 self.app.gui_factory.set_meter_refresh_period_milliseconds(
361 self.meter_refresh_period_milliseconds_spinbutton.get_value_as_int()