lots of deep but hard to spot changes to transport control, primarily relating to...
[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 */
19
20 #include <pbd/convert.h>
21 #include <pbd/stacktrace.h>
22
23 #include <gtkmm2ext/utils.h>
24
25 #include <ardour/configuration.h>
26 #include <ardour/session.h>
27 #include <ardour/osc.h>
28 #include <ardour/audioengine.h>
29
30 #include "ardour_ui.h"
31 #include "actions.h"
32 #include "gui_thread.h"
33 #include "public_editor.h"
34
35 #include "i18n.h"
36
37 using namespace Gtk;
38 using namespace Gtkmm2ext;
39 using namespace ARDOUR;
40 using namespace PBD;
41 using namespace sigc;
42
43 void
44 ARDOUR_UI::toggle_time_master ()
45 {
46         ActionManager::toggle_config_state ("Transport", "ToggleTimeMaster", &Configuration::set_jack_time_master, &Configuration::get_jack_time_master);
47 }
48
49 void
50 ARDOUR_UI::toggle_send_mtc ()
51 {
52         ActionManager::toggle_config_state ("options", "SendMTC", &Configuration::set_send_mtc, &Configuration::get_send_mtc);
53 }
54
55 void
56 ARDOUR_UI::toggle_send_mmc ()
57 {
58         ActionManager::toggle_config_state ("options", "SendMMC", &Configuration::set_send_mmc, &Configuration::get_send_mmc);
59 }
60
61 void
62 ARDOUR_UI::toggle_use_mmc ()
63 {
64         ActionManager::toggle_config_state ("options", "UseMMC", &Configuration::set_mmc_control, &Configuration::get_mmc_control);
65 }
66
67 void
68 ARDOUR_UI::toggle_use_osc ()
69 {
70         ActionManager::toggle_config_state ("options", "UseOSC", &Configuration::set_use_osc, &Configuration::get_use_osc);
71 }
72
73 void
74 ARDOUR_UI::toggle_seamless_loop ()
75 {
76         ActionManager::toggle_config_state ("options", "toggle-seamless-loop", &Configuration::set_seamless_loop, &Configuration::get_seamless_loop);
77 }
78
79 void
80 ARDOUR_UI::toggle_send_midi_feedback ()
81 {
82         ActionManager::toggle_config_state ("options", "SendMIDIfeedback", &Configuration::set_midi_feedback, &Configuration::get_midi_feedback);
83 }
84
85 void
86 ARDOUR_UI::toggle_denormal_protection ()
87 {
88         ActionManager::toggle_config_state ("options", "DenormalProtection", &Configuration::set_denormal_protection, &Configuration::get_denormal_protection);
89 }
90
91 void
92 ARDOUR_UI::toggle_only_copy_imported_files ()
93 {
94         ActionManager::toggle_config_state ("options", "OnlyCopyImportedFiles", &Configuration::set_only_copy_imported_files, &Configuration::get_only_copy_imported_files);
95 }
96
97 void
98 ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
99 {
100         const char *action = 0;
101
102         switch (hf) {
103         case BWF:
104                 action = X_("FileHeaderFormatBWF");
105                 break;
106         case WAVE:
107                 action = X_("FileHeaderFormatWAVE");
108                 break;
109         case WAVE64:
110                 action = X_("FileHeaderFormatWAVE64");
111                 break;
112         case iXML:
113                 action = X_("FileHeaderFormatiXML");
114                 break;
115         case RF64:
116                 action = X_("FileHeaderFormatRF64");
117                 break;
118         case CAF:
119                 action = X_("FileHeaderFormatCAF");
120                 break;
121         case AIFF:
122                 action = X_("FileHeaderFormatAIFF");
123                 break;
124         default:
125                 fatal << string_compose (_("programming error: %1"), "illegal file header format in ::set_native_file_header_format") << endmsg;
126                 /*NOTREACHED*/  
127         }
128
129         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
130
131         if (act) {
132                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
133                 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
134                         Config->set_native_file_header_format (hf);
135                 }
136         }
137 }
138
139 void
140 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
141 {
142         const char* action = 0;
143
144         switch (sf) {
145         case FormatFloat:
146                 action = X_("FileDataFormatFloat");
147                 break;
148         case FormatInt24:
149                 action = X_("FileDataFormat24bit");
150                 break;
151         case FormatInt16:
152                 action = X_("FileDataFormat16bit");
153                 break;
154         default:
155                 fatal << string_compose (_("programming error: %1"), "illegal file data format in ::set_native_file_data_format") << endmsg;
156                 /*NOTREACHED*/
157         }
158
159         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
160
161         if (act) {
162                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
163                 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
164                         Config->set_native_file_data_format (sf);
165                 }
166         }
167 }
168
169 void
170 ARDOUR_UI::set_input_auto_connect (AutoConnectOption option)
171 {
172         const char* action;
173         
174         switch (option) {
175         case AutoConnectPhysical:
176                 action = X_("InputAutoConnectPhysical");
177                 break;
178         default:
179                 action = X_("InputAutoConnectManual");
180         }
181
182         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
183
184         if (act) {
185                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
186
187                 if (ract && ract->get_active() && Config->get_input_auto_connect() != option) {
188                         Config->set_input_auto_connect (option);
189                 }
190         }
191 }
192
193 void
194 ARDOUR_UI::set_output_auto_connect (AutoConnectOption option)
195 {
196         const char* action;
197         
198         switch (option) {
199         case AutoConnectPhysical:
200                 action = X_("OutputAutoConnectPhysical");
201                 break;
202         case AutoConnectMaster:
203                 action = X_("OutputAutoConnectMaster");
204                 break;
205         default:
206                 action = X_("OutputAutoConnectManual");
207         }
208
209         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
210
211         if (act) {
212                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
213
214                 if (ract && ract->get_active() && Config->get_output_auto_connect() != option) {
215                         Config->set_output_auto_connect (option);
216                 }
217         }
218 }
219
220 void
221 ARDOUR_UI::set_solo_model (SoloModel model)
222 {
223         const char* action = 0;
224
225         switch (model) {
226         case SoloBus:
227                 action = X_("SoloViaBus");
228                 break;
229                 
230         case InverseMute:
231                 action = X_("SoloInPlace");
232                 break;
233         default:
234                 fatal << string_compose (_("programming error: unknown solo model in ARDOUR_UI::set_solo_model: %1"), model) << endmsg;
235                 /*NOTREACHED*/
236         }
237
238         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
239
240         if (act) {
241                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
242
243                 if (ract && ract->get_active() && Config->get_solo_model() != model) {
244                         Config->set_solo_model (model);
245                 }
246         }
247
248 }
249
250 void
251 ARDOUR_UI::set_remote_model (RemoteModel model)
252 {
253         const char* action = 0;
254
255         switch (model) {
256         case UserOrdered:
257                 action = X_("RemoteUserDefined");
258                 break;
259         case MixerOrdered:
260                 action = X_("RemoteMixerDefined");
261                 break;
262         case EditorOrdered:
263                 action = X_("RemoteEditorDefined");
264                 break;
265
266         default:
267                 fatal << string_compose (_("programming error: unknown remote model in ARDOUR_UI::set_remote_model: %1"), model) << endmsg;
268                 /*NOTREACHED*/
269         }
270
271         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
272
273         if (act) {
274                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
275
276                 if (ract && ract->get_active() && Config->get_remote_model() != model) {
277                         Config->set_remote_model (model);
278                 }
279         }
280
281 }
282
283 void
284 ARDOUR_UI::set_monitor_model (MonitorModel model)
285 {
286         const char* action = 0;
287
288         switch (model) {
289         case HardwareMonitoring:
290                 action = X_("UseHardwareMonitoring");
291                 break;
292                 
293         case SoftwareMonitoring:
294                 action = X_("UseSoftwareMonitoring");
295                 break;
296         case ExternalMonitoring:
297                 action = X_("UseExternalMonitoring");
298                 break;
299
300         default:
301                 fatal << string_compose (_("programming error: unknown monitor model in ARDOUR_UI::set_monitor_model: %1"), model) << endmsg;
302                 /*NOTREACHED*/
303         }
304
305         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
306
307         if (act) {
308                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
309
310                 if (ract && ract->get_active() && Config->get_monitoring_model() != model) {
311                         Config->set_monitoring_model (model);
312                 }
313         }
314
315 }
316
317 void
318 ARDOUR_UI::set_denormal_model (DenormalModel model)
319 {
320         const char* action = 0;
321
322         switch (model) {
323         case DenormalNone:
324                 action = X_("DenormalNone");
325                 break;
326
327         case DenormalFTZ:
328                 action = X_("DenormalFTZ");
329                 break;
330                 
331         case DenormalDAZ:
332                 action = X_("DenormalDAZ");
333                 break;
334
335         case DenormalFTZDAZ:
336                 action = X_("DenormalFTZDAZ");
337                 break;
338
339         default:
340                 fatal << string_compose (_("programming error: unknown denormal model in ARDOUR_UI::set_denormal_model: %1"), model) << endmsg;
341                 /*NOTREACHED*/
342         }
343
344         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
345
346         if (act) {
347                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
348
349                 if (ract && ract->get_active() && Config->get_denormal_model() != model) {
350                         Config->set_denormal_model (model);
351                 }
352         }
353
354 }
355
356 void
357 ARDOUR_UI::toggle_auto_input ()
358 {
359         ActionManager::toggle_config_state ("Transport", "ToggleAutoInput", &Configuration::set_auto_input, &Configuration::get_auto_input);
360 }
361
362 void
363 ARDOUR_UI::toggle_auto_play ()
364 {
365         ActionManager::toggle_config_state ("Transport", "ToggleAutoPlay", &Configuration::set_auto_play, &Configuration::get_auto_play);
366 }
367
368 void
369 ARDOUR_UI::toggle_auto_return ()
370 {
371         ActionManager::toggle_config_state ("Transport", "ToggleAutoReturn", &Configuration::set_auto_return, &Configuration::get_auto_return);
372 }
373
374 void
375 ARDOUR_UI::toggle_click ()
376 {
377         ActionManager::toggle_config_state ("Transport", "ToggleClick", &Configuration::set_clicking, &Configuration::get_clicking);
378 }
379
380 void
381 ARDOUR_UI::unset_dual_punch ()
382 {
383         Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch");
384         
385         if (action) {
386                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(action);
387                 if (tact) {
388                         ignore_dual_punch = true;
389                         tact->set_active (false);
390                         ignore_dual_punch = false;
391                 }
392         }
393 }
394
395 void
396 ARDOUR_UI::toggle_punch ()
397 {
398         if (ignore_dual_punch) {
399                 return;
400         }
401
402         Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch");
403
404         if (action) {
405
406                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(action);
407
408                 if (!tact) {
409                         return;
410                 }
411
412                 /* drive the other two actions from this one */
413
414                 Glib::RefPtr<Action> in_action = ActionManager::get_action ("Transport", "TogglePunchIn");
415                 Glib::RefPtr<Action> out_action = ActionManager::get_action ("Transport", "TogglePunchOut");
416
417                 if (in_action && out_action) {
418                         Glib::RefPtr<ToggleAction> tiact = Glib::RefPtr<ToggleAction>::cast_dynamic(in_action);
419                         Glib::RefPtr<ToggleAction> toact = Glib::RefPtr<ToggleAction>::cast_dynamic(out_action);
420                         tiact->set_active (tact->get_active());
421                         toact->set_active (tact->get_active());
422                 }
423         }
424 }
425
426 void
427 ARDOUR_UI::toggle_punch_in ()
428 {
429         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Transport"), X_("TogglePunchIn"));
430         if (!act) {
431                 return;
432         }
433
434         Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
435         if (!tact) {
436                 return;
437         }
438
439         if (tact->get_active() != Config->get_punch_in()) {
440                 Config->set_punch_in (tact->get_active ());
441         }
442
443         if (tact->get_active()) {
444                 /* if punch-in is turned on, make sure the loop/punch ruler is visible, and stop it being hidden,
445                    to avoid confusing the user */
446                 show_loop_punch_ruler_and_disallow_hide ();
447         }
448
449         reenable_hide_loop_punch_ruler_if_appropriate ();
450 }
451
452 void
453 ARDOUR_UI::toggle_punch_out ()
454 {
455         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Transport"), X_("TogglePunchOut"));
456         if (!act) {
457                 return;
458         }
459
460         Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
461         if (!tact) {
462                 return;
463         }
464
465         if (tact->get_active() != Config->get_punch_out()) {
466                 Config->set_punch_out (tact->get_active ());
467         }
468
469         if (tact->get_active()) {
470                 /* if punch-out is turned on, make sure the loop/punch ruler is visible, and stop it being hidden,
471                    to avoid confusing the user */
472                 show_loop_punch_ruler_and_disallow_hide ();
473         }
474         reenable_hide_loop_punch_ruler_if_appropriate ();
475 }
476
477 void
478 ARDOUR_UI::show_loop_punch_ruler_and_disallow_hide ()
479 {
480         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Rulers"), "toggle-loop-punch-ruler");
481         if (!act) {
482                 return;
483         }
484
485         act->set_sensitive (false);
486         
487         Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
488         if (!tact) {
489                 return;
490         }
491         
492         if (!tact->get_active()) {
493                 tact->set_active ();
494         }
495 }
496
497 /* This is a bit of a silly name for a method */
498 void
499 ARDOUR_UI::reenable_hide_loop_punch_ruler_if_appropriate ()
500 {
501         if (!Config->get_punch_in() && !Config->get_punch_out()) {
502                 /* if punch in/out are now both off, reallow hiding of the loop/punch ruler */
503                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Rulers"), "toggle-loop-punch-ruler");
504                 if (act) {
505                         act->set_sensitive (true);
506                 }
507         }
508 }
509
510 void
511 ARDOUR_UI::toggle_video_sync()
512 {
513         Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", "ToggleVideoSync");
514         if (act) {
515                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
516                 Config->set_use_video_sync (tact->get_active());
517         }
518 }
519
520 void
521 ARDOUR_UI::toggle_editing_space()
522 {
523         Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalEditor");
524         if (act) {
525                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
526                 if (tact->get_active()) {
527                         maximise_editing_space ();
528                 } else {
529                         restore_editing_space ();
530                 }
531         }
532 }
533
534 void
535 ARDOUR_UI::toggle_new_plugins_active ()
536 {
537         ActionManager::toggle_config_state ("options", "NewPluginsActive", &Configuration::set_new_plugins_active, &Configuration::get_new_plugins_active);
538 }
539
540 void
541 ARDOUR_UI::toggle_StopPluginsWithTransport()
542 {
543         ActionManager::toggle_config_state ("options", "StopPluginsWithTransport", &Configuration::set_plugins_stop_with_transport, &Configuration::get_plugins_stop_with_transport);
544 }
545
546 void
547 ARDOUR_UI::toggle_LatchedRecordEnable()
548 {
549         ActionManager::toggle_config_state ("options", "LatchedRecordEnable", &Configuration::set_latched_record_enable, &Configuration::get_latched_record_enable);
550 }
551
552 void
553 ARDOUR_UI::toggle_RegionEquivalentsOverlap()
554 {
555         ActionManager::toggle_config_state ("options", "RegionEquivalentsOverlap", &Configuration::set_use_overlap_equivalency, &Configuration::get_use_overlap_equivalency);
556 }
557
558 void
559 ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording()
560 {
561         ActionManager::toggle_config_state ("options", "DoNotRunPluginsWhileRecording", &Configuration::set_do_not_record_plugins, &Configuration::get_do_not_record_plugins);
562 }
563
564 void
565 ARDOUR_UI::toggle_VerifyRemoveLastCapture()
566 {
567         ActionManager::toggle_config_state ("options", "VerifyRemoveLastCapture", &Configuration::set_verify_remove_last_capture, &Configuration::get_verify_remove_last_capture);
568 }
569
570 void
571 ARDOUR_UI::toggle_PeriodicSafetyBackups()
572 {
573         ActionManager::toggle_config_state ("options", "PeriodicSafetyBackups", &Configuration::set_periodic_safety_backups, &Configuration::get_periodic_safety_backups);
574 }
575
576 void
577 ARDOUR_UI::toggle_StopRecordingOnXrun()
578 {
579         ActionManager::toggle_config_state ("options", "StopRecordingOnXrun", &Configuration::set_stop_recording_on_xrun, &Configuration::get_stop_recording_on_xrun);
580 }
581
582 void
583 ARDOUR_UI::toggle_CreateXrunMarker()
584 {
585         ActionManager::toggle_config_state ("options", "CreateXrunMarker", &Configuration::set_create_xrun_marker, &Configuration::get_create_xrun_marker);
586 }
587
588 void
589 ARDOUR_UI::toggle_sync_order_keys ()
590 {
591         ActionManager::toggle_config_state ("options", "SyncEditorAndMixerTrackOrder", &Configuration::set_sync_all_route_ordering, &Configuration::get_sync_all_route_ordering);
592 }
593
594 void
595 ARDOUR_UI::toggle_StopTransportAtEndOfSession()
596 {
597         ActionManager::toggle_config_state ("options", "StopTransportAtEndOfSession", &Configuration::set_stop_at_session_end, &Configuration::get_stop_at_session_end);
598 }
599
600 void
601 ARDOUR_UI::toggle_GainReduceFastTransport()
602 {
603         ActionManager::toggle_config_state ("options", "GainReduceFastTransport", &Configuration::set_quieten_at_speed, &Configuration::get_quieten_at_speed);
604 }
605
606 void
607 ARDOUR_UI::toggle_LatchedSolo()
608 {
609         ActionManager::toggle_config_state ("options", "LatchedSolo", &Configuration::set_solo_latched, &Configuration::get_solo_latched);
610 }
611
612 void
613 ARDOUR_UI::toggle_ShowSoloMutes()
614 {
615         ActionManager::toggle_config_state ("options", "ShowSoloMutes", &Configuration::set_show_solo_mutes, &Configuration::get_show_solo_mutes);
616 }
617
618 void
619 ARDOUR_UI::toggle_SoloMuteOverride()
620 {
621         ActionManager::toggle_config_state ("options", "SoloMuteOverride", &Configuration::set_solo_mute_override, &Configuration::get_solo_mute_override);
622 }
623
624 void
625 ARDOUR_UI::toggle_PrimaryClockDeltaEditCursor()
626 {
627         ActionManager::toggle_config_state ("options", "PrimaryClockDeltaEditCursor", &Configuration::set_primary_clock_delta_edit_cursor, &Configuration::get_primary_clock_delta_edit_cursor);
628 }
629
630 void
631 ARDOUR_UI::toggle_SecondaryClockDeltaEditCursor()
632 {
633         ActionManager::toggle_config_state ("options", "SecondaryClockDeltaEditCursor", &Configuration::set_secondary_clock_delta_edit_cursor, &Configuration::get_secondary_clock_delta_edit_cursor);
634 }
635
636 void
637 ARDOUR_UI::toggle_ShowTrackMeters()
638 {
639         ActionManager::toggle_config_state ("options", "ShowTrackMeters", &Configuration::set_show_track_meters, &Configuration::get_show_track_meters);
640 }
641
642 void
643 ARDOUR_UI::toggle_TapeMachineMode ()
644 {
645         ActionManager::toggle_config_state ("options", "ToggleTapeMachineMode", &Configuration::set_tape_machine_mode, &Configuration::get_tape_machine_mode);
646 }
647
648 void
649 ARDOUR_UI::toggle_use_narrow_ms()
650 {
651         ActionManager::toggle_config_state ("options", "DefaultNarrowMS", &Configuration::set_default_narrow_ms, &Configuration::get_default_narrow_ms);
652 }
653
654 void
655 ARDOUR_UI::toggle_NameNewMarkers()
656 {
657         ActionManager::toggle_config_state ("options", "NameNewMarkers", &Configuration::set_name_new_markers, &Configuration::get_name_new_markers);
658 }
659
660 void
661 ARDOUR_UI::toggle_rubberbanding_snaps_to_grid ()
662 {
663         ActionManager::toggle_config_state ("options", "RubberbandingSnapsToGrid", &Configuration::set_rubberbanding_snaps_to_grid, &Configuration::get_rubberbanding_snaps_to_grid);
664 }
665
666 void
667 ARDOUR_UI::toggle_auto_analyse_audio ()
668 {
669         ActionManager::toggle_config_state ("options", "AutoAnalyseAudio", &Configuration::set_auto_analyse_audio, &Configuration::get_auto_analyse_audio);
670 }
671
672 void
673 ARDOUR_UI::mtc_port_changed ()
674 {
675         bool have_mtc;
676
677         if (session) {
678                 if (session->mtc_port()) {
679                         have_mtc = true;
680                 } else {
681                         have_mtc = false;
682                 }
683         } else {
684                 have_mtc = false;
685         }
686
687         positional_sync_strings.clear ();
688         positional_sync_strings.push_back (slave_source_to_string (None));
689         if (have_mtc) {
690                 positional_sync_strings.push_back (slave_source_to_string (MTC));
691         }
692         positional_sync_strings.push_back (slave_source_to_string (JACK));
693
694         set_popdown_strings (sync_option_combo, positional_sync_strings);
695 }
696
697 void
698 ARDOUR_UI::setup_session_options ()
699 {
700         mtc_port_changed ();
701
702         Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
703 }
704
705
706 void
707 ARDOUR_UI::map_solo_model ()
708 {
709         const char* on;
710
711         if (Config->get_solo_model() == InverseMute) {
712                 on = X_("SoloInPlace");
713         } else {
714                 on = X_("SoloViaBus");
715         }
716
717         Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
718         if (act) {
719                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
720
721                 if (tact && !tact->get_active()) {
722                         tact->set_active (true);
723                 }
724         }
725 }
726
727 void
728 ARDOUR_UI::map_monitor_model ()
729 {
730         const char* on = 0;
731
732         switch (Config->get_monitoring_model()) {
733         case HardwareMonitoring:
734                 on = X_("UseHardwareMonitoring");
735                 break;
736         case SoftwareMonitoring:
737                 on = X_("UseSoftwareMonitoring");
738                 break;
739         case ExternalMonitoring:
740                 on = X_("UseExternalMonitoring");
741                 break;
742         }
743
744         Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
745         if (act) {
746                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
747
748                 if (tact && !tact->get_active()) {
749                         tact->set_active (true);
750                 }
751         }
752 }
753
754 void
755 ARDOUR_UI::map_denormal_protection ()
756 {
757         Glib::RefPtr<Action> act = ActionManager::get_action ("options", X_("DenormalProtection"));
758         if (act) {
759                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
760
761                 if (tact && !tact->get_active()) {
762                         tact->set_active (Config->get_denormal_protection());
763                 }
764         }
765 }
766
767 void
768 ARDOUR_UI::map_denormal_model ()
769 {
770         const char* on = 0;
771
772         switch (Config->get_denormal_model()) {
773         case DenormalNone:
774                 on = X_("DenormalNone");
775                 break;
776         case DenormalFTZ:
777                 on = X_("DenormalFTZ");
778                 break;
779         case DenormalDAZ:
780                 on = X_("DenormalDAZ");
781                 break;
782         case DenormalFTZDAZ:
783                 on = X_("DenormalFTZDAZ");
784                 break;
785         }
786
787         Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
788         if (act) {
789                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
790
791                 if (tact && !tact->get_active()) {
792                         tact->set_active (true);
793                 }
794         }
795 }
796
797 void
798 ARDOUR_UI::map_remote_model ()
799 {
800         const char* on = 0;
801
802         switch (Config->get_remote_model()) {
803         case UserOrdered:
804                 on = X_("RemoteUserDefined");
805                 break;
806         case MixerOrdered:
807                 on = X_("RemoteMixerDefined");
808                 break;
809         case EditorOrdered:
810                 on = X_("RemoteEditorDefined");
811                 break;
812         }
813
814         Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
815         if (act) {
816                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
817
818                 if (tact && !tact->get_active()) {
819                         tact->set_active (true);
820                 }
821         }
822 }
823
824 void
825 ARDOUR_UI::map_file_header_format ()
826 {
827         const char* action = 0;
828
829         switch (Config->get_native_file_header_format()) {
830         case BWF:
831                 action = X_("FileHeaderFormatBWF");
832                 break;
833
834         case WAVE:
835                 action = X_("FileHeaderFormatWAVE");
836                 break;
837
838         case WAVE64:
839                 action = X_("FileHeaderFormatWAVE64");
840                 break;
841
842         case iXML:
843                 action = X_("FileHeaderFormatiXML");
844                 break;
845
846         case RF64:
847                 action = X_("FileHeaderFormatRF64");
848                 break;
849
850         case CAF:
851                 action = X_("FileHeaderFormatCAF");
852                 break;
853
854         default:
855                 fatal << string_compose (_("programming error: unknown file header format passed to ARDOUR_UI::map_file_data_format: %1"), 
856                                          Config->get_native_file_header_format()) << endmsg;
857                 /*NOTREACHED*/
858         }
859
860
861         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
862
863         if (act) {
864                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
865
866                 if (tact && !tact->get_active()) {
867                         tact->set_active (true);
868                 }
869         }
870 }
871
872 void
873 ARDOUR_UI::map_file_data_format ()
874 {
875         const char* action = 0;
876
877         switch (Config->get_native_file_data_format()) {
878         case FormatFloat:
879                 action = X_("FileDataFormatFloat");
880                 break;
881
882         case FormatInt24:
883                 action = X_("FileDataFormat24bit");
884                 break;
885
886         case FormatInt16:
887                 action = X_("FileDataFormat16bit");
888                 break;
889
890         default:
891                 fatal << string_compose (_("programming error: unknown file data format passed to ARDOUR_UI::map_file_data_format: %1"), 
892                                          Config->get_native_file_data_format()) << endmsg;
893                 /*NOTREACHED*/
894         }
895
896
897         Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
898
899         if (act) {
900                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
901
902                 if (tact && !tact->get_active()) {
903                         tact->set_active (true);
904                 }
905         }
906 }
907
908 void
909 ARDOUR_UI::map_input_auto_connect ()
910 {
911         const char* on;
912
913         if (Config->get_input_auto_connect() == (AutoConnectOption) 0) {
914                 on = "InputAutoConnectManual";
915         } else {
916                 on = "InputAutoConnectPhysical";
917         }
918
919         Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
920         if (act) {
921                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
922
923                 if (tact && !tact->get_active()) {
924                         tact->set_active (true);
925                 }
926         }
927 }
928
929 void
930 ARDOUR_UI::map_output_auto_connect ()
931 {
932         const char* on;
933
934         if (Config->get_output_auto_connect() == (AutoConnectOption) 0) {
935                 on = "OutputAutoConnectManual";
936         } else if (Config->get_output_auto_connect() == AutoConnectPhysical) {
937                 on = "OutputAutoConnectPhysical";
938         } else {
939                 on = "OutputAutoConnectMaster";
940         }
941
942         Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
943         if (act) {
944                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
945                 
946                 if (tact && !tact->get_active()) {
947                         tact->set_active (true);
948                 }
949         }
950 }
951
952 void
953 ARDOUR_UI::map_only_copy_imported_files ()
954 {
955         Glib::RefPtr<Action> act = ActionManager::get_action ("options", X_("OnlyCopyImportedFiles"));
956         if (act) {
957                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
958
959                 if (tact && !tact->get_active()) {
960                         tact->set_active (Config->get_only_copy_imported_files());
961                 }
962         }
963
964 }
965
966 void
967 ARDOUR_UI::map_meter_falloff ()
968 {
969         const char* action = X_("MeterFalloffMedium");
970
971         float val = Config->get_meter_falloff ();
972         MeterFalloff code = meter_falloff_from_float(val);
973
974         switch (code) {
975         case MeterFalloffOff:
976                 action = X_("MeterFalloffOff");
977                 break;
978         case MeterFalloffSlowest:
979                 action = X_("MeterFalloffSlowest");
980                 break;
981         case MeterFalloffSlow:
982                 action = X_("MeterFalloffSlow");
983                 break;
984         case MeterFalloffMedium:
985                 action = X_("MeterFalloffMedium");
986                 break;
987         case MeterFalloffFast:
988                 action = X_("MeterFalloffFast");
989                 break;
990         case MeterFalloffFaster:
991                 action = X_("MeterFalloffFaster");
992                 break;
993         case MeterFalloffFastest:
994                 action = X_("MeterFalloffFastest");
995                 break;
996         }
997
998         Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), action);
999
1000         if (act) {
1001                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
1002                 if (ract && !ract->get_active()) {
1003                         ract->set_active (true);
1004                 }
1005         }
1006 }
1007
1008 void
1009 ARDOUR_UI::map_meter_hold ()
1010 {
1011         const char* action = X_("MeterHoldMedium");
1012
1013         /* XXX hack alert. Fix this. Please */
1014
1015         float val = Config->get_meter_hold ();
1016         MeterHold code = (MeterHold) (int) (floor (val));
1017
1018         switch (code) {
1019         case MeterHoldOff:
1020                 action = X_("MeterHoldOff");
1021                 break;
1022         case MeterHoldShort:
1023                 action = X_("MeterHoldShort");
1024                 break;
1025         case MeterHoldMedium:
1026                 action = X_("MeterHoldMedium");
1027                 break;
1028         case MeterHoldLong:
1029                 action = X_("MeterHoldLong");
1030                 break;
1031         }
1032
1033         Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), action);
1034
1035         if (act) {
1036                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
1037                 if (ract && !ract->get_active()) {
1038                         ract->set_active (true);
1039                 }
1040         }
1041 }
1042
1043 void 
1044 ARDOUR_UI::set_meter_hold (MeterHold val)
1045 {
1046         const char* action = 0;
1047         float fval;
1048
1049         fval = meter_hold_to_float (val);
1050
1051         switch (val) {
1052         case MeterHoldOff:
1053                 action = X_("MeterHoldOff");
1054                 break;
1055         case MeterHoldShort:
1056                 action = X_("MeterHoldShort");
1057                 break;
1058         case MeterHoldMedium:
1059                 action = X_("MeterHoldMedium");
1060                 break;
1061         case MeterHoldLong:
1062                 action = X_("MeterHoldLong");
1063                 break;
1064         }
1065
1066         Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), action);
1067         
1068         if (act) {
1069                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
1070                 if (ract && ract->get_active() && Config->get_meter_hold() != fval) {
1071                         Config->set_meter_hold (fval);
1072                 }
1073         }
1074 }
1075
1076 void
1077 ARDOUR_UI::set_meter_falloff (MeterFalloff val)
1078 {
1079         const char* action = 0;
1080         float fval;
1081
1082         fval = meter_falloff_to_float (val);
1083
1084         switch (val) {
1085         case MeterFalloffOff:
1086                 action = X_("MeterFalloffOff");
1087                 break;
1088         case MeterFalloffSlowest:
1089                 action = X_("MeterFalloffSlowest");
1090                 break;
1091         case MeterFalloffSlow:
1092                 action = X_("MeterFalloffSlow");
1093                 break;
1094         case MeterFalloffMedium:
1095                 action = X_("MeterFalloffMedium");
1096                 break;
1097         case MeterFalloffFast:
1098                 action = X_("MeterFalloffFast");
1099                 break;
1100         case MeterFalloffFaster:
1101                 action = X_("MeterFalloffFaster");
1102                 break;
1103         case MeterFalloffFastest:
1104                 action = X_("MeterFalloffFastest");
1105                 break;
1106         }
1107
1108         Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), action);
1109
1110         if (act) {
1111                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
1112                 if (ract && ract->get_active() && Config->get_meter_falloff () != fval) {
1113                         Config->set_meter_falloff (fval);
1114                 }
1115         }
1116 }
1117
1118 void
1119 ARDOUR_UI::parameter_changed (const char* parameter_name)
1120 {
1121         ENSURE_GUI_THREAD (bind (mem_fun (*this, &ARDOUR_UI::parameter_changed), parameter_name));
1122
1123 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
1124         
1125         if (PARAM_IS ("slave-source")) {
1126
1127                 sync_option_combo.set_active_text (slave_source_to_string (Config->get_slave_source()));
1128                 
1129                 switch (Config->get_slave_source()) {
1130                 case None:
1131                         ActionManager::get_action ("Transport", "ToggleAutoPlay")->set_sensitive (true);
1132                         ActionManager::get_action ("Transport", "ToggleAutoReturn")->set_sensitive (true);
1133                         break;
1134
1135                 default:
1136                         /* XXX need to make auto-play is off as well as insensitive */
1137                         ActionManager::get_action ("Transport", "ToggleAutoPlay")->set_sensitive (false);
1138                         ActionManager::get_action ("Transport", "ToggleAutoReturn")->set_sensitive (false);
1139                         break;
1140                 }
1141
1142         } else if (PARAM_IS ("send-mtc")) {
1143
1144                 ActionManager::map_some_state ("options", "SendMTC", &Configuration::get_send_mtc);
1145
1146         } else if (PARAM_IS ("send-mmc")) {
1147
1148
1149                 ActionManager::map_some_state ("options", "SendMMC", &Configuration::get_send_mmc);
1150
1151         } else if (PARAM_IS ("use-osc")) {
1152
1153 #ifdef HAVE_LIBLO
1154                 if (Config->get_use_osc()) {
1155                         osc->start ();
1156                 } else {
1157                         osc->stop ();
1158                 }
1159 #endif
1160
1161                 ActionManager::map_some_state ("options", "UseOSC", &Configuration::get_use_osc);
1162                 
1163         } else if (PARAM_IS ("seamless-loop")) {
1164                 ActionManager::map_some_state ("options", "toggle-seamless-loop", &Configuration::get_seamless_loop);
1165
1166         } else if (PARAM_IS ("mmc-control")) {
1167                 ActionManager::map_some_state ("options", "UseMMC", &Configuration::get_mmc_control);
1168
1169         } else if (PARAM_IS ("midi-feedback")) {
1170                 ActionManager::map_some_state ("options", "SendMIDIfeedback", &Configuration::get_midi_feedback);
1171         } else if (PARAM_IS ("do-not-record-plugins")) {
1172                 ActionManager::map_some_state ("options", "DoNotRunPluginsWhileRecording", &Configuration::get_do_not_record_plugins);
1173         } else if (PARAM_IS ("latched-record-enable")) {
1174                 ActionManager::map_some_state ("options", "LatchedRecordEnable", &Configuration::get_latched_record_enable);
1175         } else if (PARAM_IS ("solo-latched")) {
1176                 ActionManager::map_some_state ("options", "LatchedSolo", &Configuration::get_solo_latched);
1177         } else if (PARAM_IS ("show-solo-mutes")) {
1178                 ActionManager::map_some_state ("options", "ShowSoloMutes", &Configuration::get_show_solo_mutes);
1179         } else if (PARAM_IS ("solo-mute-override")) {
1180                 ActionManager::map_some_state ("options", "SoloMuteOverride", &Configuration::get_solo_mute_override);
1181         } else if (PARAM_IS ("solo-model")) {
1182                 map_solo_model ();
1183         } else if (PARAM_IS ("auto-play")) {
1184                 ActionManager::map_some_state ("Transport", "ToggleAutoPlay", &Configuration::get_auto_play);
1185         } else if (PARAM_IS ("auto-return")) {
1186                 ActionManager::map_some_state ("Transport", "ToggleAutoReturn", &Configuration::get_auto_return);
1187         } else if (PARAM_IS ("auto-input")) {
1188                 ActionManager::map_some_state ("Transport", "ToggleAutoInput", &Configuration::get_auto_input);
1189         } else if (PARAM_IS ("tape-machine-mode")) {
1190                 ActionManager::map_some_state ("options", "ToggleTapeMachineMode", &Configuration::get_tape_machine_mode);
1191         } else if (PARAM_IS ("punch-out")) {
1192                 ActionManager::map_some_state ("Transport", "TogglePunchOut", &Configuration::get_punch_out);
1193                 if (!Config->get_punch_out()) {
1194                         unset_dual_punch ();
1195                 }
1196         } else if (PARAM_IS ("punch-in")) {
1197                 ActionManager::map_some_state ("Transport", "TogglePunchIn", &Configuration::get_punch_in);
1198                 if (!Config->get_punch_in()) {
1199                         unset_dual_punch ();
1200                 }
1201         } else if (PARAM_IS ("clicking")) {
1202                 ActionManager::map_some_state ("Transport", "ToggleClick", &Configuration::get_clicking);
1203         } else if (PARAM_IS ("jack-time-master")) {
1204                 ActionManager::map_some_state ("Transport",  "ToggleTimeMaster", &Configuration::get_jack_time_master);
1205         } else if (PARAM_IS ("plugins-stop-with-transport")) {
1206                 ActionManager::map_some_state ("options",  "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport);
1207         } else if (PARAM_IS ("new-plugins-active")) {
1208                 ActionManager::map_some_state ("options",  "NewPluginsActive", &Configuration::get_new_plugins_active);
1209         } else if (PARAM_IS ("latched-record-enable")) {
1210                 ActionManager::map_some_state ("options", "LatchedRecordEnable", &Configuration::get_latched_record_enable);
1211         } else if (PARAM_IS ("verify-remove-last-capture")) {
1212                 ActionManager::map_some_state ("options",  "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture);
1213         } else if (PARAM_IS ("periodic-safety-backups")) {
1214                 ActionManager::map_some_state ("options",  "PeriodicSafetyBackups", &Configuration::get_periodic_safety_backups);
1215         } else if (PARAM_IS ("stop-recording-on-xrun")) {
1216                 ActionManager::map_some_state ("options",  "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun);
1217         } else if (PARAM_IS ("create-xrun-marker")) {
1218                 ActionManager::map_some_state ("options",  "CreateXrunMarker", &Configuration::get_create_xrun_marker);
1219         } else if (PARAM_IS ("sync-all-route-ordering")) {
1220                 ActionManager::map_some_state ("options",  "SyncEditorAndMixerTrackOrder", &Configuration::get_sync_all_route_ordering);
1221         } else if (PARAM_IS ("stop-at-session-end")) {
1222                 ActionManager::map_some_state ("options",  "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end);
1223         } else if (PARAM_IS ("monitoring-model")) {
1224                 map_monitor_model ();
1225         } else if (PARAM_IS ("denormal-model")) {
1226                 map_denormal_model ();
1227         } else if (PARAM_IS ("denormal-protection")) {
1228                 map_denormal_protection ();
1229         } else if (PARAM_IS ("remote-model")) {
1230                 map_remote_model ();
1231         } else if (PARAM_IS ("use-video-sync")) {
1232                 ActionManager::map_some_state ("Transport",  "ToggleVideoSync", &Configuration::get_use_video_sync);
1233         } else if (PARAM_IS ("quieten-at-speed")) {
1234                 ActionManager::map_some_state ("options",  "GainReduceFastTransport", &Configuration::get_quieten_at_speed);
1235         } else if (PARAM_IS ("shuttle-behaviour")) {
1236
1237                 switch (Config->get_shuttle_behaviour ()) {
1238                 case Sprung:
1239                         shuttle_style_button.set_active_text (_("sprung"));
1240                         shuttle_fract = 0.0;
1241                         shuttle_box.queue_draw ();
1242                         if (session) {
1243                                 if (session->transport_rolling()) {
1244                                         shuttle_fract = SHUTTLE_FRACT_SPEED1;
1245                                         session->request_transport_speed (1.0);
1246                                 }
1247                         }
1248                         break;
1249                 case Wheel:
1250                         shuttle_style_button.set_active_text (_("wheel"));
1251                         break;
1252                 }
1253
1254         } else if (PARAM_IS ("shuttle-units")) {
1255                 
1256                 switch (Config->get_shuttle_units()) {
1257                 case Percentage:
1258                         shuttle_units_button.set_label("% ");
1259                         break;
1260                 case Semitones:
1261                         shuttle_units_button.set_label(_("ST"));
1262                         break;
1263                 }
1264         } else if (PARAM_IS ("input-auto-connect")) {
1265                 map_input_auto_connect ();
1266         } else if (PARAM_IS ("output-auto-connect")) {
1267                 map_output_auto_connect ();
1268         } else if (PARAM_IS ("native-file-header-format")) {
1269                 map_file_header_format ();
1270         } else if (PARAM_IS ("native-file-data-format")) {
1271                 map_file_data_format ();
1272         } else if (PARAM_IS ("meter-hold")) {
1273                 map_meter_hold ();
1274         } else if (PARAM_IS ("meter-falloff")) {
1275                 map_meter_falloff ();
1276         } else if (PARAM_IS ("video-pullup") || PARAM_IS ("smpte-format")) {
1277                 if (session) {
1278                         primary_clock.set (session->audible_frame(), true);
1279                         secondary_clock.set (session->audible_frame(), true);
1280                 } else {
1281                         primary_clock.set (0, true);
1282                         secondary_clock.set (0, true);
1283                 }
1284         } else if (PARAM_IS ("use-overlap-equivalency")) {
1285                 ActionManager::map_some_state ("options", "RegionEquivalentsOverlap", &Configuration::get_use_overlap_equivalency);
1286         } else if (PARAM_IS ("primary-clock-delta-edit-cursor")) {
1287                 ActionManager::map_some_state ("options",  "PrimaryClockDeltaEditCursor", &Configuration::get_primary_clock_delta_edit_cursor);
1288         } else if (PARAM_IS ("secondary-clock-delta-edit-cursor")) {
1289                 ActionManager::map_some_state ("options",  "SecondaryClockDeltaEditCursor", &Configuration::get_secondary_clock_delta_edit_cursor);
1290         } else if (PARAM_IS ("only-copy-imported-files")) {
1291                 map_only_copy_imported_files ();
1292         } else if (PARAM_IS ("show-track-meters")) {
1293                 ActionManager::map_some_state ("options",  "ShowTrackMeters", &Configuration::get_show_track_meters);
1294                 editor->toggle_meter_updating();
1295         } else if (PARAM_IS ("default-narrow_ms")) {
1296                 ActionManager::map_some_state ("options",  "DefaultNarrowMS", &Configuration::get_default_narrow_ms);
1297         } else if (PARAM_IS ("rubberbanding-snaps-to-grid")) {
1298                 ActionManager::map_some_state ("options", "RubberbandingSnapsToGrid", &Configuration::get_rubberbanding_snaps_to_grid);
1299         }
1300
1301                            
1302
1303 #undef PARAM_IS
1304 }