Use std::string instead of PBD::sys::path in pbd/search_path.h, pbd/file_utils.h...
[ardour.git] / gtk2_ardour / session_option_editor.cc
1 /*
2     Copyright (C) 2000-2010 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 "ardour/session.h"
21
22 #include "gui_thread.h"
23 #include "session_option_editor.h"
24 #include "search_path_option.h"
25 #include "i18n.h"
26
27 using namespace std;
28 using namespace ARDOUR;
29
30 SessionOptionEditor::SessionOptionEditor (Session* s)
31         : OptionEditor (&(s->config), _("Session Properties"))
32         , _session_config (&(s->config))
33 {
34         set_session (s);
35
36         set_name ("SessionProperties");
37
38         /* TIMECODE*/
39
40         _sync_source = new ComboOption<SyncSource> (
41                 "sync-source",
42                 _("External timecode source"),
43                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_sync_source),
44                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_sync_source)
45                 );
46
47         populate_sync_options ();
48         parameter_changed (string ("external-sync"));
49
50         add_option (_("Timecode"), _sync_source);
51
52         add_option (_("Timecode"), new OptionEditorHeading (_("Timecode Settings")));
53
54         ComboOption<TimecodeFormat>* smf = new ComboOption<TimecodeFormat> (
55                 "timecode-format",
56                 _("Timecode frames-per-second"),
57                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_format),
58                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_format)
59                 );
60
61         smf->add (timecode_23976, _("23.976"));
62         smf->add (timecode_24, _("24"));
63         smf->add (timecode_24976, _("24.976"));
64         smf->add (timecode_25, _("25"));
65         smf->add (timecode_2997, _("29.97"));
66         smf->add (timecode_2997drop, _("29.97 drop"));
67         smf->add (timecode_30, _("30"));
68         smf->add (timecode_30drop, _("30 drop"));
69         smf->add (timecode_5994, _("59.94"));
70         smf->add (timecode_60, _("60"));
71
72         add_option (_("Timecode"), smf);
73
74         ComboOption<uint32_t>* spf = new ComboOption<uint32_t> (
75                 "subframes-per-frame",
76                 _("Subframes per frame"),
77                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_subframes_per_frame),
78                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_subframes_per_frame)
79                 );
80
81         spf->add (80, _("80"));
82         spf->add (100, _("100"));
83
84         add_option (_("Timecode"), spf);
85
86         add_option (_("Timecode"), new BoolOption (
87                             "timecode-source-is-synced",
88                             _("Timecode source shares sample clock with audio interface"),
89                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_source_is_synced),
90                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_source_is_synced)
91                             ));
92
93         ComboOption<float>* vpu = new ComboOption<float> (
94                 "video-pullup",
95                 _("Pull-up / pull-down"),
96                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_video_pullup),
97                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_video_pullup)
98                 );
99
100         vpu->add (4.1667 + 0.1, _("4.1667 + 0.1%"));
101         vpu->add (4.1667, _("4.1667"));
102         vpu->add (4.1667 - 0.1, _("4.1667 - 0.1%"));
103         vpu->add (0.1, _("0.1"));
104         vpu->add (0, _("none"));
105         vpu->add (-0.1, _("-0.1"));
106         vpu->add (-4.1667 + 0.1, _("-4.1667 + 0.1%"));
107         vpu->add (-4.1667, _("-4.1667"));
108         vpu->add (-4.1667 - 0.1, _("-4.1667 - 0.1%"));
109
110         add_option (_("Timecode"), vpu);
111
112         ClockOption* co = new ClockOption (
113                 "timecode-offset",
114                 _("Timecode offset"),
115                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_offset),
116                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_offset)
117                 );
118
119         co->set_session (_session);
120
121         add_option (_("Timecode"), co);
122
123         add_option (_("Timecode"), new BoolOption (
124                             "timecode-offset-negative",
125                             _("Timecode Offset Negative"),
126                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_offset_negative),
127                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_offset_negative)
128                             ));
129
130         add_option (_("Timecode"), new OptionEditorHeading (_("JACK Transport/Time Settings")));
131
132         add_option (_("Timecode"), new BoolOption (
133                             "jack-time-master",
134                             string_compose (_("%1 is JACK Time Master (provides Bar|Beat|Tick and other information to JACK)"), PROGRAM_NAME),
135                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_jack_time_master),
136                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_jack_time_master)
137                             ));
138
139         /* FADES */
140
141         ComboOption<CrossfadeModel>* cfm = new ComboOption<CrossfadeModel> (
142                 "xfade-model",
143                 _("Crossfades are created"),
144                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfade_model),
145                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfade_model)
146                 );
147
148         cfm->add (FullCrossfade, _("to span entire overlap"));
149         cfm->add (ShortCrossfade, _("short"));
150
151         add_option (_("Fades"), cfm);
152
153         ComboOption<CrossfadeChoice>* cfc = new ComboOption<CrossfadeChoice> (
154                 "xfade-choice",
155                 _("Crossfade type"),
156                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfade_choice),
157                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfade_choice)
158                 );
159
160         cfc->add (ConstantPowerMinus3dB, _("constant power (-3dB)"));
161         cfc->add (ConstantPowerMinus6dB, _("constant power (-6dB)"));
162         cfc->add (RegionFades, _("use existing region fade shape"));
163
164         add_option (_("Fades"), cfc);
165
166         add_option (_("Fades"), new SpinOption<float> (
167                 _("short-xfade-seconds"),
168                 _("Short crossfade length"),
169                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_short_xfade_seconds),
170                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_short_xfade_seconds),
171                 0, 1000, 1, 10,
172                 _("ms"), 0.001
173                             ));
174
175         add_option (_("Fades"), new SpinOption<float> (
176                 _("destructive-xfade-seconds"),
177                 _("Destructive crossfade length"),
178                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_destructive_xfade_msecs),
179                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_destructive_xfade_msecs),
180                 0, 1000, 1, 10,
181                 _("ms")
182                             ));
183
184         add_option (_("Fades"), new BoolOption (
185                             "auto-xfade",
186                             _("Create crossfades automatically"),
187                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_auto_xfade),
188                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_auto_xfade)
189                             ));
190
191         add_option (_("Fades"), new BoolOption (
192                             "use-region-fades",
193                             _("Region fades active"),
194                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_region_fades),
195                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_region_fades)
196                             ));
197
198         add_option (_("Fades"), new BoolOption (
199                             "show-region-fades",
200                             _("Region fades visible"),
201                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_region_fades),
202                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_region_fades)
203                             ));
204
205         /* Media */
206
207         add_option (_("Media"), new OptionEditorHeading (_("Audio file format")));
208
209         ComboOption<SampleFormat>* sf = new ComboOption<SampleFormat> (
210                 "native-file-data-format",
211                 _("Sample format"),
212                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_data_format),
213                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_data_format)
214                 );
215
216         sf->add (FormatFloat, _("32-bit floating point"));
217         sf->add (FormatInt24, _("24-bit integer"));
218         sf->add (FormatInt16, _("16-bit integer"));
219
220         add_option (_("Media"), sf);
221
222         ComboOption<HeaderFormat>* hf = new ComboOption<HeaderFormat> (
223                 "native-file-header-format",
224                 _("File type"),
225                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_header_format),
226                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_header_format)
227                 );
228
229         hf->add (BWF, _("Broadcast WAVE"));
230         hf->add (WAVE, _("WAVE"));
231         hf->add (WAVE64, _("WAVE-64"));
232         hf->add (CAF, _("CAF"));
233
234         add_option (_("Media"), hf);
235
236         add_option (_("Media"), new OptionEditorHeading (_("File locations")));
237
238         SearchPathOption* spo = new SearchPathOption ("audio-search-path", _("Search for audio files in:"),
239                                                       sigc::mem_fun (*_session_config, &SessionConfiguration::get_audio_search_path),
240                                                       sigc::mem_fun (*_session_config, &SessionConfiguration::set_audio_search_path));
241         add_option (_("Media"), spo);
242
243         spo = new SearchPathOption ("midi-search-path", _("Search for MIDI files in:"),
244                                     sigc::mem_fun (*_session_config, &SessionConfiguration::get_midi_search_path),
245                                     sigc::mem_fun (*_session_config, &SessionConfiguration::set_midi_search_path));
246
247         add_option (_("Media"), spo);
248
249         /* Monitoring */
250
251         add_option (_("Monitoring"), new BoolOption (
252                             "auto-input",
253                             _("Monitoring automatically follows transport state (\"auto-input\")"),
254                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_auto_input),
255                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_auto_input)
256                             ));
257
258         add_option (_("Monitoring"), new BoolOption (
259                             "have-monitor-section",
260                             _("Use monitor section in this session"),
261                             sigc::mem_fun (*this, &SessionOptionEditor::get_use_monitor_section),
262                             sigc::mem_fun (*this, &SessionOptionEditor::set_use_monitor_section)
263                             ));
264
265         /* Misc */
266
267         add_option (_("Misc"), new OptionEditorHeading (_("MIDI Options")));
268
269         add_option (_("Misc"), new BoolOption (
270                             "midi-copy-is-fork",
271                             _("MIDI region copies are independent"),
272                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_midi_copy_is_fork),
273                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_midi_copy_is_fork)
274                             ));
275
276         ComboOption<InsertMergePolicy>* li = new ComboOption<InsertMergePolicy> (
277                 "insert-merge-policy",
278                 _("Policy for handling overlapping notes\n on the same MIDI channel"),
279                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_insert_merge_policy),
280                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_insert_merge_policy)
281                 );
282
283         li->add (InsertMergeReject, _("never allow them"));
284         li->add (InsertMergeRelax, _("don't do anything in particular"));
285         li->add (InsertMergeReplace, _("replace any overlapped existing note"));
286         li->add (InsertMergeTruncateExisting, _("shorten the overlapped existing note"));
287         li->add (InsertMergeTruncateAddition, _("shorten the overlapping new note"));
288         li->add (InsertMergeExtend, _("replace both overlapping notes with a single note"));
289
290         add_option (_("Misc"), li);
291
292         add_option (_("Misc"), new OptionEditorHeading (_("Glue to bars and beats")));
293
294         add_option (_("Misc"), new BoolOption (
295                             "glue-new-markers-to-bars-and-beats",
296                             _("Glue new markers to bars and beats"),
297                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_glue_new_markers_to_bars_and_beats),
298                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_glue_new_markers_to_bars_and_beats)
299                             ));
300
301         add_option (_("Misc"), new BoolOption (
302                             "glue-new-regions-to-bars-and-beats",
303                             _("Glue new regions to bars and beats"),
304                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_glue_new_regions_to_bars_and_beats),
305                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_glue_new_regions_to_bars_and_beats)
306                             ));
307 }
308
309 void
310 SessionOptionEditor::populate_sync_options ()
311 {
312         vector<SyncSource> sync_opts = _session->get_available_sync_options ();
313
314         _sync_source->clear ();
315
316         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
317                 _sync_source->add (*i, sync_source_to_string (*i));
318         }
319 }
320
321 void
322 SessionOptionEditor::parameter_changed (std::string const & p)
323 {
324         OptionEditor::parameter_changed (p);
325
326         if (p == "external-sync") {
327                 _sync_source->set_sensitive (!_session->config.get_external_sync ());
328         }
329 }
330
331 /* the presence of absence of a monitor section is not really a regular session
332  * property so we provide these two functions to act as setter/getter slots
333  */
334
335 bool
336 SessionOptionEditor::set_use_monitor_section (bool yn)
337 {
338         bool had_monitor_section = _session->monitor_out();
339
340         if (yn) {
341                 _session->add_monitor_section ();
342         } else {
343                 _session->remove_monitor_section ();
344         }
345
346         return had_monitor_section != yn;
347 }
348
349 bool
350 SessionOptionEditor::get_use_monitor_section ()
351 {
352         return _session->monitor_out() != 0;
353 }