session prefs editor gets renamed as session properties
[ardour.git] / gtk2_ardour / session_option_editor.cc
1 #include "ardour/session.h"
2 #include "ardour/io.h"
3 #include "ardour/auditioner.h"
4 #include "ardour/audioengine.h"
5 #include "ardour/port.h"
6
7 #include "gui_thread.h"
8 #include "session_option_editor.h"
9 #include "port_matrix.h"
10 #include "i18n.h"
11
12 using namespace std;
13 using namespace ARDOUR;
14
15 class OptionsPortMatrix : public PortMatrix
16 {
17 public:
18         OptionsPortMatrix (Gtk::Window* parent, ARDOUR::Session* session)
19                 : PortMatrix (parent, session, DataType::AUDIO)
20         {
21                 _port_group.reset (new PortGroup (""));
22                 _ports[OURS].add_group (_port_group);
23
24                 setup_all_ports ();
25                 init ();
26         }
27
28         void setup_ports (int dim)
29         {
30                 if (dim == OURS) {
31                         _port_group->clear ();
32                         _port_group->add_bundle (_session->click_io()->bundle());
33                         _port_group->add_bundle (_session->the_auditioner()->output()->bundle());
34                 } else {
35                         _ports[OTHER].gather (_session, true, false);
36                 }
37         }
38
39         void set_state (ARDOUR::BundleChannel c[2], bool s)
40         {
41                 Bundle::PortList const & our_ports = c[OURS].bundle->channel_ports (c[OURS].channel);
42                 Bundle::PortList const & other_ports = c[OTHER].bundle->channel_ports (c[OTHER].channel);
43
44                 if (c[OURS].bundle == _session->click_io()->bundle()) {
45
46                         for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
47                                 for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
48
49                                         Port* f = _session->engine().get_port_by_name (*i);
50                                         assert (f);
51
52                                         if (s) {
53                                                 _session->click_io()->connect (f, *j, 0);
54                                         } else {
55                                                 _session->click_io()->disconnect (f, *j, 0);
56                                         }
57                                 }
58                         }
59                 }
60         }
61
62         PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const
63         {
64                 Bundle::PortList const & our_ports = c[OURS].bundle->channel_ports (c[OURS].channel);
65                 Bundle::PortList const & other_ports = c[OTHER].bundle->channel_ports (c[OTHER].channel);
66
67                 if (c[OURS].bundle == _session->click_io()->bundle()) {
68
69                         for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
70                                 for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
71                                         Port* f = _session->engine().get_port_by_name (*i);
72                                         assert (f);
73
74                                         if (f->connected_to (*j)) {
75                                                 return PortMatrixNode::ASSOCIATED;
76                                         } else {
77                                                 return PortMatrixNode::NOT_ASSOCIATED;
78                                         }
79                                 }
80                         }
81
82                 } else {
83
84                         /* XXX */
85
86                 }
87
88                 return PortMatrixNode::NOT_ASSOCIATED;
89         }
90
91         bool list_is_global (int dim) const {
92                 return (dim == OTHER);
93         }
94
95         bool can_remove_channels (boost::shared_ptr<Bundle>) const {
96                 return false;
97         }
98
99         void remove_channel (ARDOUR::BundleChannel) {}
100
101         std::string disassociation_verb () const {
102                 return _("Disassociate");
103         }
104
105 private:
106         /* see PortMatrix: signal flow from 0 to 1 (out to in) */
107         enum {
108                 OURS = 0,
109                 OTHER = 1,
110         };
111
112         boost::shared_ptr<PortGroup> _port_group;
113
114 };
115
116
117 class ConnectionOptions : public OptionEditorBox
118 {
119 public:
120         ConnectionOptions (Gtk::Window* parent, ARDOUR::Session* s)
121                 : _port_matrix (parent, s)
122         {
123                 _box->pack_start (_port_matrix);
124         }
125
126         void parameter_changed (string const &)
127         {
128
129         }
130
131         void set_state_from_config ()
132         {
133
134         }
135
136 private:
137         OptionsPortMatrix _port_matrix;
138 };
139
140 SessionOptionEditor::SessionOptionEditor (Session* s)
141         : OptionEditor (&(s->config), _("Session Properties"))
142         , _session_config (&(s->config))
143 {
144         set_name ("SessionProperties");
145
146         /* SYNC */
147
148         ComboOption<uint32_t>* spf = new ComboOption<uint32_t> (
149                 "subframes-per-frame",
150                 _("Subframes per frame"),
151                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_subframes_per_frame),
152                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_subframes_per_frame)
153                 );
154
155         spf->add (80, _("80"));
156         spf->add (100, _("100"));
157
158         add_option (_("Sync"), spf);
159
160         ComboOption<SyncSource>* ssrc = new ComboOption<SyncSource> (
161                 "sync-source",
162                 _("External sync source"),
163                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_sync_source),
164                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_sync_source)
165                 );
166         
167         s->MTC_PortChanged.connect (_session_connections, invalidator (*this), boost::bind (&SessionOptionEditor::populate_sync_options, this, s, ssrc), gui_context());
168         s->MIDIClock_PortChanged.connect (_session_connections, invalidator (*this), boost::bind (&SessionOptionEditor::populate_sync_options, this, s, ssrc), gui_context());
169         s->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&SessionOptionEditor::follow_sync_state, this, _1, s, ssrc), gui_context());
170
171         populate_sync_options (s, ssrc);
172         follow_sync_state (string ("external-sync"), s, ssrc);
173
174         add_option (_("Sync"), ssrc);
175
176         ComboOption<TimecodeFormat>* smf = new ComboOption<TimecodeFormat> (
177                 "timecode-format",
178                 _("Timecode frames-per-second"),
179                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_format),
180                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_format)
181                 );
182
183         smf->add (timecode_23976, _("23.976"));
184         smf->add (timecode_24, _("24"));
185         smf->add (timecode_24976, _("24.976"));
186         smf->add (timecode_25, _("25"));
187         smf->add (timecode_2997, _("29.97"));
188         smf->add (timecode_2997drop, _("29.97 drop"));
189         smf->add (timecode_30, _("30"));
190         smf->add (timecode_30drop, _("30 drop"));
191         smf->add (timecode_5994, _("59.94"));
192         smf->add (timecode_60, _("60"));
193
194         add_option (_("Sync"), smf);
195
196         add_option (_("Sync"), new BoolOption (
197                             "timecode-source-is-synced",
198                             _("Timecode source shares sample clock with audio interface"),
199                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_source_is_synced),
200                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_source_is_synced)
201                             ));
202
203         ComboOption<float>* vpu = new ComboOption<float> (
204                 "video-pullup",
205                 _("Pull-up / pull-down"),
206                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_video_pullup),
207                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_video_pullup)
208                 );
209
210         vpu->add (4.1667 + 0.1, _("4.1667 + 0.1%"));
211         vpu->add (4.1667, _("4.1667"));
212         vpu->add (4.1667 - 0.1, _("4.1667 - 0.1%"));
213         vpu->add (0.1, _("0.1"));
214         vpu->add (0, _("none"));
215         vpu->add (-0.1, _("-0.1"));
216         vpu->add (-4.1667 + 0.1, _("-4.1667 + 0.1%"));
217         vpu->add (-4.1667, _("-4.1667"));
218         vpu->add (-4.1667 - 0.1, _("-4.1667 - 0.1%"));
219
220         add_option (_("Sync"), vpu);
221
222         /* FADES */
223
224         ComboOption<CrossfadeModel>* cfm = new ComboOption<CrossfadeModel> (
225                 "xfade-model",
226                 _("Crossfades are created"),
227                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfade_model),
228                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfade_model)
229                 );
230
231         cfm->add (FullCrossfade, _("to span entire overlap"));
232         cfm->add (ShortCrossfade, _("short"));
233
234         add_option (_("Fades"), cfm);
235
236         add_option (_("Fades"), new SpinOption<float> (
237                 _("short-xfade-seconds"),
238                 _("Short crossfade length"),
239                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_short_xfade_seconds),
240                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_short_xfade_seconds),
241                 0, 1000, 1, 10,
242                 _("ms"), 0.001
243                             ));
244
245         add_option (_("Fades"), new SpinOption<float> (
246                 _("destructive-xfade-seconds"),
247                 _("Destructive crossfade length"),
248                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_destructive_xfade_msecs),
249                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_destructive_xfade_msecs),
250                 0, 1000, 1, 10,
251                 _("ms")
252                             ));
253
254         add_option (_("Fades"), new BoolOption (
255                             "auto-xfade",
256                             _("Create crossfades automatically"),
257                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_auto_xfade),
258                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_auto_xfade)
259                             ));
260
261         add_option (_("Fades"), new BoolOption (
262                             "xfades-active",
263                             _("Crossfades active"),
264                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfades_active),
265                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfades_active)
266                             ));
267
268         add_option (_("Fades"), new BoolOption (
269                             "xfades-visible",
270                             _("Crossfades visible"),
271                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfades_visible),
272                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfades_visible)
273                             ));
274
275         add_option (_("Fades"), new BoolOption (
276                             "use-region-fades",
277                             _("Region fades active"),
278                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_region_fades),
279                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_region_fades)
280                             ));
281
282         add_option (_("Fades"), new BoolOption (
283                             "show-region-fades",
284                             _("Region fades visible"),
285                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_region_fades),
286                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_region_fades)
287                             ));
288
289         /* MISC */
290
291         add_option (_("Misc"), new OptionEditorHeading (_("Audio file format")));
292
293         ComboOption<SampleFormat>* sf = new ComboOption<SampleFormat> (
294                 "native-file-data-format",
295                 _("Sample format"),
296                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_data_format),
297                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_data_format)
298                 );
299
300         sf->add (FormatFloat, _("32-bit floating point"));
301         sf->add (FormatInt24, _("24-bit integer"));
302         sf->add (FormatInt16, _("16-bit integer"));
303
304         add_option (_("Misc"), sf);
305
306         ComboOption<HeaderFormat>* hf = new ComboOption<HeaderFormat> (
307                 "native-file-header-format",
308                 _("File type"),
309                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_header_format),
310                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_header_format)
311                 );
312
313         hf->add (BWF, _("Broadcast WAVE"));
314         hf->add (WAVE, _("WAVE"));
315         hf->add (WAVE64, _("WAVE-64"));
316         hf->add (CAF, _("CAF"));
317
318         add_option (_("Misc"), hf);
319
320         add_option (_("Misc"), new OptionEditorHeading (_("Layering")));
321
322         ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
323                 "layer-model",
324                 _("Layering model in overlaid mode"),
325                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_layer_model),
326                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_layer_model)
327                 );
328
329         lm->add (LaterHigher, _("later is higher"));
330         lm->add (MoveAddHigher, _("most recently moved or added is higher"));
331         lm->add (AddHigher, _("most recently added is higher"));
332
333         add_option (_("Misc"), lm);
334
335         add_option (_("Misc"), new OptionEditorHeading (_("Broadcast WAVE metadata")));
336
337         add_option (_("Misc"), new EntryOption (
338                             "bwf-country-code",
339                             _("Country code"),
340                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_bwf_country_code),
341                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_bwf_country_code)
342                             ));
343
344         add_option (_("Misc"), new EntryOption (
345                             "bwf-organization-code",
346                             _("Organization code"),
347                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_bwf_organization_code),
348                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_bwf_organization_code)
349                             ));
350
351         add_option (_("Connections"), new ConnectionOptions (this, s));
352 }
353
354 void
355 SessionOptionEditor::populate_sync_options (Session* s, Option* opt)
356 {
357         ComboOption<SyncSource>* sync_opt = dynamic_cast<ComboOption<SyncSource>* > (opt);
358
359         vector<SyncSource> sync_opts = s->get_available_sync_options ();
360
361         sync_opt->clear ();
362
363         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
364                 sync_opt->add (*i, sync_source_to_string (*i));
365         }
366 }
367
368 void
369 SessionOptionEditor::follow_sync_state (std::string p, Session* s, Option* opt)
370 {
371         ComboOption<SyncSource>* sync_opt = dynamic_cast<ComboOption<SyncSource>* > (opt);
372         if (p == "external-sync") {
373                 if (s->config.get_external_sync()) {
374                         sync_opt->set_sensitive (false);
375                 } else {
376                         sync_opt->set_sensitive (true);
377                 }
378         }
379 }