Merged with trunk revision 600
[ardour.git] / gtk2_ardour / ardour_ui_options.cc
1 /*
2     Copyright (C) 2005 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
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.
13
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <pbd/convert.h>
22
23 #include <gtkmm2ext/utils.h>
24
25 #include <ardour/configuration.h>
26 #include <ardour/session.h>
27 #include <ardour/audioengine.h>
28
29 #include "ardour_ui.h"
30 #include "actions.h"
31 #include "gui_thread.h"
32
33 #include "i18n.h"
34
35 using namespace Gtk;
36 using namespace Gtkmm2ext;
37 using namespace ARDOUR;
38
39 void
40 ARDOUR_UI::setup_config_options ()
41 {
42         std::vector<Glib::ustring> groups;
43         groups.push_back("options");
44         groups.push_back("Editor");
45         
46         struct { 
47             char* name;
48             bool (Configuration::*method)(void) const;
49             char act_type;  //(t)oggle or (r)adio
50         } options[] = {
51                 { "ToggleTimeMaster", &Configuration::get_jack_time_master, 't' },
52                 { "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport, 't' },
53                 { "LatchedRecordEnable", &Configuration::get_latched_record_enable, 't' },
54                 { "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture, 't' },
55                 { "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun, 't' },
56                 { "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end, 't' },
57                 { "UseHardwareMonitoring", &Configuration::get_use_hardware_monitoring, 'r' },
58                 { "UseSoftwareMonitoring", &Configuration::get_use_sw_monitoring, 'r' },
59                 { "UseExternalMonitoring", &Configuration::get_use_external_monitoring, 'r' },
60                 { "MeterFalloffOff", &Configuration::get_meter_falloff_off, 'r' },
61                 { "MeterFalloffSlowest", &Configuration::get_meter_falloff_slowest, 'r' },
62                 { "MeterFalloffSlow", &Configuration::get_meter_falloff_slow, 'r' },
63                 { "MeterFalloffMedium", &Configuration::get_meter_falloff_medium, 'r' },
64                 { "MeterFalloffFast", &Configuration::get_meter_falloff_fast, 'r' },
65                 { "MeterFalloffFaster", &Configuration::get_meter_falloff_faster, 'r' },
66                 { "MeterFalloffFastest", &Configuration::get_meter_falloff_fastest, 'r' },
67                 { "MeterHoldOff", &Configuration::get_meter_hold_off, 'r' },
68                 { "MeterHoldShort", &Configuration::get_meter_hold_short, 'r' },
69                 { "MeterHoldMedium", &Configuration::get_meter_hold_medium, 'r' },
70                 { "MeterHoldLong", &Configuration::get_meter_hold_long, 'r' },
71                 { 0, 0, 0 }
72         };
73         
74         for (uint32_t n = 0; options[n].name; ++n) {
75                 for (std::vector<Glib::ustring>::iterator i = groups.begin(); i != groups.end(); i++) {
76                         Glib::RefPtr<Action> act = ActionManager::get_action (i->c_str(), options[n].name);
77                         if (act) {
78                                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
79                                 if (options[n].act_type == 't' || (options[n].act_type == 'r' && (Config->*(options[n].method))()))
80                                         tact->set_active ((Config->*(options[n].method))());
81                                 continue;
82                         }
83                 }
84         }
85 }
86
87 void
88 ARDOUR_UI::toggle_time_master ()
89 {
90         toggle_config_state ("Transport", "ToggleTimeMaster", &Configuration::set_jack_time_master);
91         if (session) {
92                 session->engine().reset_timebase ();
93         }
94 }
95
96 void
97 ARDOUR_UI::toggle_config_state (const char* group, const char* action, void (Configuration::*set)(bool))
98 {
99         Glib::RefPtr<Action> act = ActionManager::get_action (group, action);
100         if (act) {
101                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
102                 (Config->*set) (tact->get_active());
103         }
104 }
105
106 void
107 ARDOUR_UI::toggle_session_state (const char* group, const char* action, void (Session::*set)(bool), bool (Session::*get)(void) const)
108 {
109         if (session) {
110                 Glib::RefPtr<Action> act = ActionManager::get_action (group, action);
111                 if (act) {
112                         Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
113                         bool x = (session->*get)();
114
115                         if (x != tact->get_active()) {
116                                 (session->*set) (!x);
117                         }
118                 }
119         }
120 }
121
122 void
123 ARDOUR_UI::toggle_session_state (const char* group, const char* action, sigc::slot<void> theSlot)
124 {
125         if (session) {
126                 Glib::RefPtr<Action> act = ActionManager::get_action (group, action);
127                 if (act) {
128                         Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
129                         if (tact->get_active()) {
130                                 theSlot ();
131                         }
132                 }
133         }
134 }
135
136 void
137 ARDOUR_UI::toggle_send_mtc ()
138 {
139         toggle_session_state ("options", "SendMTC", &Session::set_send_mtc, &Session::get_send_mtc);
140 }
141
142 void
143 ARDOUR_UI::toggle_send_mmc ()
144 {
145         toggle_session_state ("options", "SendMMC", &Session::set_send_mmc, &Session::get_send_mmc);
146 }
147
148 void
149 ARDOUR_UI::toggle_use_mmc ()
150 {
151         toggle_session_state ("options", "UseMMC", &Session::set_mmc_control, &Session::get_mmc_control);
152 }
153
154 void
155 ARDOUR_UI::toggle_use_midi_control ()
156 {
157         toggle_session_state ("options", "UseMIDIcontrol", &Session::set_midi_control, &Session::get_midi_control);
158 }
159
160 void
161 ARDOUR_UI::toggle_send_midi_feedback ()
162 {
163         toggle_session_state ("options", "SendMIDIfeedback", &Session::set_midi_feedback, &Session::get_midi_feedback);
164 }
165
166 void
167 ARDOUR_UI::toggle_AutoConnectNewTrackInputsToHardware()
168 {
169         toggle_session_state ("options", "AutoConnectNewTrackInputsToHardware", &Session::set_input_auto_connect, &Session::get_input_auto_connect);
170 }
171 void
172 ARDOUR_UI::toggle_AutoConnectNewTrackOutputsToHardware()
173 {
174         toggle_session_state ("options", "AutoConnectNewTrackOutputsToHardware", bind (mem_fun (session, &Session::set_output_auto_connect), Session::AutoConnectPhysical));
175 }
176 void
177 ARDOUR_UI::toggle_AutoConnectNewTrackOutputsToMaster()
178 {
179         toggle_session_state ("options", "AutoConnectNewTrackOutputsToHardware", bind (mem_fun (session, &Session::set_output_auto_connect), Session::AutoConnectMaster));
180 }
181 void
182 ARDOUR_UI::toggle_ManuallyConnectNewTrackOutputs()
183 {
184         toggle_session_state ("options", "AutoConnectNewTrackOutputsToHardware", bind (mem_fun (session, &Session::set_output_auto_connect), Session::AutoConnectOption (0)));
185 }
186
187 void
188 ARDOUR_UI::toggle_auto_input ()
189 {
190         toggle_session_state ("Transport", "ToggleAutoInput", &Session::set_auto_input, &Session::get_auto_input);
191 }
192
193 void
194 ARDOUR_UI::toggle_auto_play ()
195 {
196         toggle_session_state ("Transport", "ToggleAutoPlay", &Session::set_auto_play, &Session::get_auto_play);
197 }
198
199 void
200 ARDOUR_UI::toggle_auto_return ()
201 {
202         toggle_session_state ("Transport", "ToggleAutoReturn", &Session::set_auto_return, &Session::get_auto_return);
203 }
204
205 void
206 ARDOUR_UI::toggle_click ()
207 {
208         toggle_session_state ("Transport", "ToggleClick", &Session::set_clicking, &Session::get_clicking);
209 }
210
211 void
212 ARDOUR_UI::toggle_session_auto_loop ()
213 {
214         if (session) {
215                 if (session->get_auto_loop()) {
216                         if (session->transport_rolling()) {
217                                 transport_roll();
218                         } else {
219                                 session->request_auto_loop (false);
220                         }
221                 } else {
222                         session->request_auto_loop (true);
223                 }
224         }
225 }
226
227 void
228 ARDOUR_UI::toggle_punch_in ()
229 {
230         toggle_session_state ("Transport", "TogglePunchIn", &Session::set_punch_in, &Session::get_punch_in);
231 }
232
233 void
234 ARDOUR_UI::toggle_punch_out ()
235 {
236         toggle_session_state ("Transport", "TogglePunchOut", &Session::set_punch_out, &Session::get_punch_out);
237 }
238
239 void
240 ARDOUR_UI::toggle_editing_space()
241 {
242         Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalEditor");
243         if (act) {
244                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
245                 if (tact->get_active()) {
246                         maximise_editing_space ();
247                 } else {
248                         restore_editing_space ();
249                 }
250         }
251 }
252
253 void
254 ARDOUR_UI::toggle_UseHardwareMonitoring()
255 {
256         Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseHardwareMonitoring");
257         if (act) {
258                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
259                 if (tact->get_active()) {
260                         Config->set_use_hardware_monitoring (true);
261                         Config->set_use_sw_monitoring (false);
262                         Config->set_use_external_monitoring (false);
263                         if (session) {
264                                 session->reset_input_monitor_state();
265                         }
266                 }
267         }
268 }
269
270 void
271 ARDOUR_UI::toggle_UseSoftwareMonitoring()
272 {
273         Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseSoftwareMonitoring");
274         if (act) {
275                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
276                 if (tact->get_active()) {
277                         Config->set_use_hardware_monitoring (false);
278                         Config->set_use_sw_monitoring (true);
279                         Config->set_use_external_monitoring (false);
280                         if (session) {
281                                 session->reset_input_monitor_state();
282                         }
283                 }
284         }
285 }
286
287 void
288 ARDOUR_UI::toggle_UseExternalMonitoring()
289 {
290         Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseExternalMonitoring");
291         if (act) {
292                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
293                 if (tact->get_active()) {
294                         Config->set_use_hardware_monitoring (false);
295                         Config->set_use_sw_monitoring (false);
296                         Config->set_use_external_monitoring (true);
297                         if (session) {
298                                 session->reset_input_monitor_state();
299                         }
300                 }
301         }
302 }
303
304 void
305 ARDOUR_UI::toggle_StopPluginsWithTransport()
306 {
307         toggle_config_state ("options", "StopPluginsWithTransport", &Configuration::set_plugins_stop_with_transport);
308 }
309
310 void
311 ARDOUR_UI::toggle_LatchedRecordEnable()
312 {
313         toggle_config_state ("options", "LatchedRecordEnable", &Configuration::set_latched_record_enable);
314 }
315
316 void
317 ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording()
318 {
319         toggle_session_state ("options", "DoNotRunPluginsWhileRecording", &Session::set_do_not_record_plugins, &Session::get_do_not_record_plugins);
320 }
321
322 void
323 ARDOUR_UI::toggle_VerifyRemoveLastCapture()
324 {
325         toggle_config_state ("options", "VerifyRemoveLastCapture", &Configuration::set_verify_remove_last_capture);
326 }
327
328 void
329 ARDOUR_UI::toggle_StopRecordingOnXrun()
330 {
331         toggle_config_state ("options", "StopRecordingOnXrun", &Configuration::set_stop_recording_on_xrun);
332 }
333
334 void
335 ARDOUR_UI::toggle_StopTransportAtEndOfSession()
336 {
337         toggle_config_state ("options", "StopTransportAtEndOfSession", &Configuration::set_stop_at_session_end);
338 }
339
340 void
341 ARDOUR_UI::toggle_GainReduceFastTransport()
342 {
343         Glib::RefPtr<Action> act = ActionManager::get_action ("options", "GainReduceFastTransport");
344         if (act) {
345                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
346                 if (tact->get_active()) {
347                         Config->set_quieten_at_speed (0.251189); // -12dB reduction for ffwd or rewind
348                 } else {
349                         Config->set_quieten_at_speed (1.0); /* no change */
350                 }
351         }
352 }
353
354 void
355 ARDOUR_UI::toggle_LatchedSolo()
356 {
357         toggle_session_state ("options", "LatchedSolo", &Session::set_solo_latched, &Session::solo_latched);
358 }
359
360 void
361 ARDOUR_UI::toggle_SoloViaBus()
362 {
363         if (!session) {
364                 return;
365         }
366
367         Glib::RefPtr<Action> act = ActionManager::get_action ("options", "SoloViaBus");
368         if (act) {
369                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
370
371                 if (tact->get_active()) {
372                         session->set_solo_model (Session::SoloBus);
373                 } else {
374                         session->set_solo_model (Session::InverseMute);
375                 }
376         }
377 }
378
379 void
380 ARDOUR_UI::toggle_AutomaticallyCreateCrossfades()
381 {
382 }
383 void
384 ARDOUR_UI::toggle_UnmuteNewFullCrossfades()
385 {
386 }
387
388 void
389 ARDOUR_UI::mtc_port_changed ()
390 {
391         bool have_mtc;
392
393         if (session) {
394                 if (session->mtc_port()) {
395                         have_mtc = true;
396                 } else {
397                         have_mtc = false;
398                 }
399         } else {
400                 have_mtc = false;
401         }
402
403         if (have_mtc) {
404                 const gchar *psync_strings[] = {
405                         N_("Internal"),
406                         N_("MTC"),
407                         N_("JACK"),
408                         0
409                 };
410                 
411                 positional_sync_strings = PBD::internationalize (psync_strings);
412                 
413         } else {
414                 const gchar *psync_strings[] = {
415                         N_("Internal"),
416                         N_("JACK"),
417                         0
418                 };
419                 positional_sync_strings = PBD::internationalize (psync_strings);
420         }
421         
422         set_popdown_strings (sync_option_combo, positional_sync_strings);
423 }
424
425 void
426 ARDOUR_UI::setup_session_options ()
427 {
428         mtc_port_changed ();
429
430         session_control_changed (Session::SlaveType);
431         session_control_changed (Session::SendMTC);
432         session_control_changed (Session::SendMMC);
433         session_control_changed (Session::MMCControl);
434         session_control_changed (Session::MidiFeedback);
435         session_control_changed (Session::MidiControl);
436         session_control_changed (Session::RecordingPlugins);
437         session_control_changed (Session::CrossFadesActive);
438         session_control_changed (Session::SoloLatch);
439         session_control_changed (Session::SoloingModel);
440         session_control_changed (Session::LayeringModel);
441         session_control_changed (Session::CrossfadingModel);
442         session_control_changed (Session::PunchOut);
443         session_control_changed (Session::PunchIn);
444         session_control_changed (Session::AutoPlay);
445         session_control_changed (Session::AutoReturn);
446         session_control_changed (Session::AutoInput);
447         session_control_changed (Session::Clicking);
448         
449         session->ControlChanged.connect (mem_fun (*this, &ARDOUR_UI::queue_session_control_changed));
450 }
451
452 void
453 ARDOUR_UI::map_some_session_state (const char* group, const char* action, bool (Session::*get)() const)
454 {
455         if (!session) {
456                 return;
457         }
458
459         Glib::RefPtr<Action> act = ActionManager::get_action (group, action);
460         if (act) {
461                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
462                 bool x = (session->*get)();
463                 if (tact->get_active() != x) {
464                         tact->set_active (x);
465                 }
466         }
467 }
468
469 void
470 ARDOUR_UI::queue_session_control_changed (Session::ControlType t)
471 {
472         ENSURE_GUI_THREAD (bind (mem_fun (*this, &ARDOUR_UI::session_control_changed), t));
473 }
474
475 void
476 ARDOUR_UI::session_control_changed (Session::ControlType t)
477 {
478         switch (t) {
479         case Session::SlaveType:
480                 switch (session->slave_source()) {
481                 case Session::None:
482                         sync_option_combo.set_active_text (_("Internal"));
483                         break;
484                 case Session::MTC:
485                         sync_option_combo.set_active_text (_("MTC"));
486                         break;
487                 case Session::JACK:
488                         sync_option_combo.set_active_text (_("JACK"));
489                         break;
490                 }
491                 
492                 break;
493
494         case Session::SendMTC:
495                 map_some_session_state ("options", "SendMTC", &Session::get_send_mtc);
496                 break;
497
498         case Session::SendMMC:
499                 map_some_session_state ("options", "SendMMC", &Session::get_send_mmc);
500                 break;
501
502         case Session::MMCControl:       
503                 map_some_session_state ("options", "UseMMC", &Session::get_mmc_control);
504                 break;
505
506         case Session::MidiFeedback:       
507                 map_some_session_state ("options", "SendMIDIfeedback", &Session::get_midi_feedback);
508                 break;
509
510         case Session::MidiControl:       
511                 map_some_session_state ("options", "UseMIDIcontrol", &Session::get_midi_control);
512                 break;
513
514         case Session::RecordingPlugins:
515                 map_some_session_state ("options", "DoNotRunPluginsWhileRecording", &Session::get_do_not_record_plugins);
516                 break;
517
518         case Session::CrossFadesActive:
519                 map_some_session_state ("options", "CrossfadesActive", &Session::get_crossfades_active);
520                 break;
521
522         case Session::SoloLatch:
523                 break;
524
525         case Session::SoloingModel:
526                 switch (session->solo_model()) {
527                 case Session::InverseMute:
528                         break;
529                 case Session::SoloBus:
530                         break;
531                 }
532                 break;
533
534         case Session::LayeringModel:
535                 break;
536
537         case Session::CrossfadingModel:
538                 break;
539
540                 
541         case Session::AutoPlay:
542                 map_some_session_state ("Transport", "ToggleAutoPlay", &Session::get_auto_play);
543                 break;
544
545         case Session::AutoLoop:
546                 break;
547
548         case Session::AutoReturn:
549                 map_some_session_state ("Transport", "ToggleAutoReturn", &Session::get_auto_return);
550                 break;
551
552         case Session::AutoInput:
553                 map_some_session_state ("Transport", "ToggleAutoInput", &Session::get_auto_input);
554                 break;
555
556         case Session::PunchOut:
557                 map_some_session_state ("Transport", "TogglePunchOut", &Session::get_punch_out);
558                 break;
559
560         case Session::PunchIn:
561                 map_some_session_state ("Transport", "TogglePunchIn", &Session::get_punch_in);
562                 break;
563
564         case Session::Clicking:
565                 map_some_session_state ("Transport", "ToggleClick", &Session::get_clicking);
566                 break;
567
568         default:
569                 // somebody else handles this 
570                 break;
571
572         }
573 }