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