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
):
29 GObject
.GObject
.__init
__(self
)
30 self
.set_title(_("Preferences"))
32 self
.connect("response", self
.on_response_cb
)
33 self
.connect("delete-event", self
.on_response_cb
)
35 def create_frame(self
, label
, child
):
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)
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)
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
= (
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
= (
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)
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
)
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
)
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()),
264 spinbutton
= Gtk
.SpinButton(adjustment
=adjustment
, climb_rate
=1.0, digits
=1)
265 spinbutton
.connect("value-changed", self
.on_peak_reset_spinbutton_changed
)
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()),
276 spinbutton
= Gtk
.SpinButton(adjustment
=adjustment
)
277 spinbutton
.connect("value-changed", self
.on_meter_refresh_spinbutton_changed
)
280 def on_response_cb(self
, dlg
, response_id
, *args
):
281 self
.app
.preferences_dialog
= None
284 def on_path_entry_changed(self
, *args
):
285 path
= self
.path_entry
.get_text().strip()
288 fullpath
= expanduser(path
)
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(
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."),
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()