pass it back to linux
[ardour.git] / gtk2_ardour / new_session_dialog.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 "i18n.h"
21 #include "new_session_dialog.h"
22
23 #include <pbd/error.h>
24
25 #include <ardour/recent_sessions.h>
26 #include <ardour/session.h>
27 #include <ardour/profile.h>
28
29 #include <gtkmm/entry.h>
30 #include <gtkmm/filechooserbutton.h>
31 #include <gtkmm/spinbutton.h>
32 #include <gtkmm/checkbutton.h>
33 #include <gtkmm/radiobutton.h>
34 #include <gtkmm/filefilter.h>
35 #include <gtkmm/stock.h>
36 #include <gdkmm/cursor.h>
37
38 #include <gtkmm2ext/window_title.h>
39
40 using namespace Gtkmm2ext;
41 using namespace PBD;
42
43 #include "opts.h"
44 #include "utils.h"
45
46 NewSessionDialog::NewSessionDialog()
47         : ArdourDialog ("session control")
48 {
49         in_destructor = false;
50         session_name_label = Gtk::manage(new class Gtk::Label(_("Name :")));
51         m_name = Gtk::manage(new class Gtk::Entry());
52         m_name->set_text(ARDOUR_COMMAND_LINE::session_name);
53
54         chan_count_label_1 = Gtk::manage(new class Gtk::Label(_("channels")));
55         chan_count_label_2 = Gtk::manage(new class Gtk::Label(_("channels")));
56         chan_count_label_3 = Gtk::manage(new class Gtk::Label(_("channels")));
57         chan_count_label_4 = Gtk::manage(new class Gtk::Label(_("channels")));
58
59         chan_count_label_1->set_alignment(0,0.5);
60         chan_count_label_1->set_padding(0,0);
61         chan_count_label_1->set_line_wrap(false);
62
63         chan_count_label_2->set_alignment(0,0.5);
64         chan_count_label_2->set_padding(0,0);
65         chan_count_label_2->set_line_wrap(false);
66
67         chan_count_label_3->set_alignment(0,0.5);
68         chan_count_label_3->set_padding(0,0);
69         chan_count_label_3->set_line_wrap(false);
70
71         chan_count_label_4->set_alignment(0,0.5);
72         chan_count_label_4->set_padding(0,0);
73         chan_count_label_4->set_line_wrap(false);
74
75         bus_label = Gtk::manage(new class Gtk::Label(_("<b>Busses</b>")));
76         input_label = Gtk::manage(new class Gtk::Label(_("<b>Inputs</b>")));
77         output_label = Gtk::manage(new class Gtk::Label(_("<b>Outputs</b>")));
78
79         session_location_label = Gtk::manage(new class Gtk::Label(_("Create Folder In :")));
80         m_folder = Gtk::manage(new class Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER));
81         session_template_label = Gtk::manage(new class Gtk::Label(_("Template :")));
82         m_template = Gtk::manage(new class Gtk::FileChooserButton());
83         m_create_control_bus = Gtk::manage(new class Gtk::CheckButton(_("Create Monitor Bus")));
84         
85         Gtk::Adjustment *m_control_bus_channel_count_adj = Gtk::manage(new class Gtk::Adjustment(2, 0, 100, 1, 10, 10));
86         m_control_bus_channel_count = Gtk::manage(new class Gtk::SpinButton(*m_control_bus_channel_count_adj, 1, 0));
87         
88         Gtk::Adjustment *m_master_bus_channel_count_adj = Gtk::manage(new class Gtk::Adjustment(2, 0, 100, 1, 10, 10));
89         m_master_bus_channel_count = Gtk::manage(new class Gtk::SpinButton(*m_master_bus_channel_count_adj, 1, 0));
90         m_create_master_bus = Gtk::manage(new class Gtk::CheckButton(_("Create Master Bus")));
91         advanced_table = Gtk::manage(new class Gtk::Table(2, 2, true));
92         m_connect_inputs = Gtk::manage(new class Gtk::CheckButton(_("Automatically Connect to Physical Inputs")));
93         m_limit_input_ports = Gtk::manage(new class Gtk::CheckButton(_("Use only")));
94         
95         Gtk::Adjustment *m_input_limit_count_adj = Gtk::manage(new class Gtk::Adjustment(1, 0, 100, 1, 10, 10));
96         m_input_limit_count = Gtk::manage(new class Gtk::SpinButton(*m_input_limit_count_adj, 1, 0));
97         input_port_limit_hbox = Gtk::manage(new class Gtk::HBox(false, 0));
98         input_port_vbox = Gtk::manage(new class Gtk::VBox(false, 0));
99         input_table = Gtk::manage(new class Gtk::Table(2, 2, false));
100
101         bus_frame = Gtk::manage(new class Gtk::Frame());
102         bus_table = Gtk::manage (new Gtk::Table (2, 3, false));
103
104         input_frame = Gtk::manage(new class Gtk::Frame());
105         m_connect_outputs = Gtk::manage(new class Gtk::CheckButton(_("Automatically Connect Outputs")));
106         m_limit_output_ports = Gtk::manage(new class Gtk::CheckButton(_("Use only")));
107         
108         Gtk::Adjustment *m_output_limit_count_adj = Gtk::manage(new class Gtk::Adjustment(1, 0, 100, 1, 10, 10));
109         m_output_limit_count = Gtk::manage(new class Gtk::SpinButton(*m_output_limit_count_adj, 1, 0));
110         output_port_limit_hbox = Gtk::manage(new class Gtk::HBox(false, 0));
111         output_port_vbox = Gtk::manage(new class Gtk::VBox(false, 0));
112         
113         Gtk::RadioButton::Group _RadioBGroup_m_connect_outputs_to_master;
114         m_connect_outputs_to_master = Gtk::manage(new class Gtk::RadioButton(_RadioBGroup_m_connect_outputs_to_master, _("... to Master Bus")));
115         m_connect_outputs_to_physical = Gtk::manage(new class Gtk::RadioButton(_RadioBGroup_m_connect_outputs_to_master, _("... to Physical Outputs")));
116         output_conn_vbox = Gtk::manage(new class Gtk::VBox(false, 0));
117         output_vbox = Gtk::manage(new class Gtk::VBox(false, 0));
118
119         output_frame = Gtk::manage(new class Gtk::Frame());
120         advanced_vbox = Gtk::manage(new class Gtk::VBox(false, 0));
121         advanced_label = Gtk::manage(new class Gtk::Label(_("Advanced Options")));
122         advanced_expander = Gtk::manage(new class Gtk::Expander());
123         new_session_table = Gtk::manage(new class Gtk::Table(2, 2, false));
124         m_open_filechooser = Gtk::manage(new class Gtk::FileChooserButton());
125         open_session_hbox = Gtk::manage(new class Gtk::HBox(false, 0));
126         m_treeview = Gtk::manage(new class Gtk::TreeView());
127         recent_scrolledwindow = Gtk::manage(new class Gtk::ScrolledWindow());
128
129         recent_sesion_label = Gtk::manage(new class Gtk::Label(_("Recent:")));
130         recent_frame = Gtk::manage(new class Gtk::Frame());
131         open_session_vbox = Gtk::manage(new class Gtk::VBox(false, 0));
132         m_notebook = Gtk::manage(new class Gtk::Notebook());
133         session_name_label->set_alignment(0, 0.5);
134         session_name_label->set_padding(6,0);
135         session_name_label->set_line_wrap(false);
136         session_name_label->set_selectable(false);
137         m_name->set_editable(true);
138         m_name->set_max_length(0);
139         m_name->set_has_frame(true);
140         m_name->set_activates_default(true);
141         m_name->set_width_chars (40);
142         session_location_label->set_alignment(0,0.5);
143         session_location_label->set_padding(6,0);
144         session_location_label->set_line_wrap(false);
145         session_location_label->set_selectable(false);
146         session_template_label->set_alignment(0,0.5);
147         session_template_label->set_padding(6,0);
148         session_template_label->set_line_wrap(false);
149         session_template_label->set_selectable(false);
150         m_create_control_bus->set_flags(Gtk::CAN_FOCUS);
151         m_create_control_bus->set_relief(Gtk::RELIEF_NORMAL);
152         m_create_control_bus->set_mode(true);
153         m_create_control_bus->set_active(false);
154         m_create_control_bus->set_border_width(0);
155         m_control_bus_channel_count->set_flags(Gtk::CAN_FOCUS);
156         m_control_bus_channel_count->set_update_policy(Gtk::UPDATE_ALWAYS);
157         m_control_bus_channel_count->set_numeric(true);
158         m_control_bus_channel_count->set_digits(0);
159         m_control_bus_channel_count->set_wrap(false);
160         m_control_bus_channel_count->set_sensitive(false);
161         m_master_bus_channel_count->set_flags(Gtk::CAN_FOCUS);
162         m_master_bus_channel_count->set_update_policy(Gtk::UPDATE_ALWAYS);
163         m_master_bus_channel_count->set_numeric(true);
164         m_master_bus_channel_count->set_digits(0);
165         m_master_bus_channel_count->set_wrap(false);
166         open_session_file_label = Gtk::manage(new class Gtk::Label(_("Browse:")));
167         open_session_file_label->set_alignment(0, 0.5);
168         m_create_master_bus->set_flags(Gtk::CAN_FOCUS);
169         m_create_master_bus->set_relief(Gtk::RELIEF_NORMAL);
170         m_create_master_bus->set_mode(true);
171         m_create_master_bus->set_active(true);
172         m_create_master_bus->set_border_width(0);
173         advanced_table->set_row_spacings(0);
174         advanced_table->set_col_spacings(0);
175
176         m_connect_inputs->set_flags(Gtk::CAN_FOCUS);
177         m_connect_inputs->set_relief(Gtk::RELIEF_NORMAL);
178         m_connect_inputs->set_mode(true);
179         m_connect_inputs->set_active(true);
180         m_connect_inputs->set_border_width(0);
181
182         m_limit_input_ports->set_flags(Gtk::CAN_FOCUS);
183         m_limit_input_ports->set_relief(Gtk::RELIEF_NORMAL);
184         m_limit_input_ports->set_mode(true);
185         m_limit_input_ports->set_sensitive(true);
186         m_limit_input_ports->set_border_width(0);
187         m_input_limit_count->set_flags(Gtk::CAN_FOCUS);
188         m_input_limit_count->set_update_policy(Gtk::UPDATE_ALWAYS);
189         m_input_limit_count->set_numeric(true);
190         m_input_limit_count->set_digits(0);
191         m_input_limit_count->set_wrap(false);
192         m_input_limit_count->set_sensitive(false);
193
194         bus_hbox = Gtk::manage (new Gtk::HBox (false, 0));
195         bus_hbox->pack_start (*bus_table, Gtk::PACK_SHRINK, 18);
196
197         bus_label->set_alignment(0, 0.5);
198         bus_label->set_padding(0,0);
199         bus_label->set_line_wrap(false);
200         bus_label->set_selectable(false);
201         bus_label->set_use_markup(true);
202         bus_frame->set_shadow_type(Gtk::SHADOW_NONE);
203         bus_frame->set_label_align(0,0.5);
204         bus_frame->add(*bus_hbox);
205         bus_frame->set_label_widget(*bus_label);
206         
207         bus_table->set_row_spacings (0);
208         bus_table->set_col_spacings (0);
209         bus_table->attach (*m_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
210         bus_table->attach (*m_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
211         bus_table->attach (*chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
212         bus_table->attach (*m_create_control_bus, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
213         bus_table->attach (*m_control_bus_channel_count, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
214         bus_table->attach (*chan_count_label_2, 2, 3, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
215
216         input_port_limit_hbox->pack_start(*m_limit_input_ports, Gtk::PACK_SHRINK, 6);
217         input_port_limit_hbox->pack_start(*m_input_limit_count, Gtk::PACK_SHRINK, 0);
218         input_port_limit_hbox->pack_start(*chan_count_label_3, Gtk::PACK_SHRINK, 6);
219         input_port_vbox->pack_start(*m_connect_inputs, Gtk::PACK_SHRINK, 0);
220         input_port_vbox->pack_start(*input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
221         input_table->set_row_spacings(0);
222         input_table->set_col_spacings(0);
223         input_table->attach(*input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
224
225         input_hbox = Gtk::manage (new Gtk::HBox (false, 0));
226         input_hbox->pack_start (*input_table, Gtk::PACK_SHRINK, 18);
227
228         input_label->set_alignment(0, 0.5);
229         input_label->set_padding(0,0);
230         input_label->set_line_wrap(false);
231         input_label->set_selectable(false);
232         input_label->set_use_markup(true);
233         input_frame->set_shadow_type(Gtk::SHADOW_NONE);
234         input_frame->set_label_align(0,0.5);
235         input_frame->add(*input_hbox);
236         input_frame->set_label_widget(*input_label);
237
238         m_connect_outputs->set_flags(Gtk::CAN_FOCUS);
239         m_connect_outputs->set_relief(Gtk::RELIEF_NORMAL);
240         m_connect_outputs->set_mode(true);
241         m_connect_outputs->set_active(true);
242         m_connect_outputs->set_border_width(0);
243         m_limit_output_ports->set_flags(Gtk::CAN_FOCUS);
244         m_limit_output_ports->set_relief(Gtk::RELIEF_NORMAL);
245         m_limit_output_ports->set_mode(true);
246         m_limit_output_ports->set_sensitive(true);
247         m_limit_output_ports->set_border_width(0);
248         m_output_limit_count->set_flags(Gtk::CAN_FOCUS);
249         m_output_limit_count->set_update_policy(Gtk::UPDATE_ALWAYS);
250         m_output_limit_count->set_numeric(false);
251         m_output_limit_count->set_digits(0);
252         m_output_limit_count->set_wrap(false);
253         m_output_limit_count->set_sensitive(false);
254         output_port_limit_hbox->pack_start(*m_limit_output_ports, Gtk::PACK_SHRINK, 6);
255         output_port_limit_hbox->pack_start(*m_output_limit_count, Gtk::PACK_SHRINK, 0);
256         output_port_limit_hbox->pack_start(*chan_count_label_4, Gtk::PACK_SHRINK, 6);
257         m_connect_outputs_to_master->set_flags(Gtk::CAN_FOCUS);
258         m_connect_outputs_to_master->set_relief(Gtk::RELIEF_NORMAL);
259         m_connect_outputs_to_master->set_mode(true);
260         m_connect_outputs_to_master->set_active(false);
261         m_connect_outputs_to_master->set_border_width(0);
262         m_connect_outputs_to_physical->set_flags(Gtk::CAN_FOCUS);
263         m_connect_outputs_to_physical->set_relief(Gtk::RELIEF_NORMAL);
264         m_connect_outputs_to_physical->set_mode(true);
265         m_connect_outputs_to_physical->set_active(false);
266         m_connect_outputs_to_physical->set_border_width(0);
267         output_conn_vbox->pack_start(*m_connect_outputs, Gtk::PACK_SHRINK, 0);
268         output_conn_vbox->pack_start(*m_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
269         output_conn_vbox->pack_start(*m_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
270         output_vbox->set_border_width(6);
271
272         output_port_vbox->pack_start(*output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
273
274         output_vbox->pack_start(*output_conn_vbox);
275         output_vbox->pack_start(*output_port_vbox);
276
277         output_label->set_alignment(0, 0.5);
278         output_label->set_padding(0,0);
279         output_label->set_line_wrap(false);
280         output_label->set_selectable(false);
281         output_label->set_use_markup(true);
282         output_frame->set_shadow_type(Gtk::SHADOW_NONE);
283         output_frame->set_label_align(0,0.5);
284
285         output_hbox = Gtk::manage (new Gtk::HBox (false, 0));
286         output_hbox->pack_start (*output_vbox, Gtk::PACK_SHRINK, 18);
287
288         output_frame->add(*output_hbox);
289         output_frame->set_label_widget(*output_label);
290
291         advanced_vbox->pack_start(*advanced_table, Gtk::PACK_SHRINK, 0);
292         advanced_vbox->pack_start(*bus_frame, Gtk::PACK_SHRINK, 6);
293         advanced_vbox->pack_start(*input_frame, Gtk::PACK_SHRINK, 6);
294         advanced_vbox->pack_start(*output_frame, Gtk::PACK_SHRINK, 0);
295         advanced_label->set_padding(0,0);
296         advanced_label->set_line_wrap(false);
297         advanced_label->set_selectable(false);
298         advanced_label->set_alignment(0, 0.5);
299         advanced_expander->set_flags(Gtk::CAN_FOCUS);
300         advanced_expander->set_border_width(0);
301         advanced_expander->set_expanded(false);
302         advanced_expander->set_spacing(0);
303         advanced_expander->add(*advanced_vbox);
304         advanced_expander->set_label_widget(*advanced_label);
305         new_session_table->set_border_width(12);
306         new_session_table->set_row_spacings(6);
307         new_session_table->set_col_spacings(0);
308         new_session_table->attach(*session_name_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL, 0, 0);
309         new_session_table->attach(*m_name, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0);
310         new_session_table->attach(*session_location_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL, 0, 0);
311         new_session_table->attach(*m_folder, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0);
312         new_session_table->attach(*session_template_label, 0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 0, 0);
313         new_session_table->attach(*m_template, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0);
314
315         if (!ARDOUR::Profile->get_sae()) {
316                 new_session_table->attach(*advanced_expander, 0, 2, 3, 4, Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 6);
317         }
318
319         open_session_hbox->pack_start(*open_session_file_label, false, false, 12);
320         open_session_hbox->pack_start(*m_open_filechooser, true, true, 12);
321         m_treeview->set_flags(Gtk::CAN_FOCUS);
322         m_treeview->set_headers_visible(true);
323         m_treeview->set_rules_hint(false);
324         m_treeview->set_reorderable(false);
325         m_treeview->set_enable_search(true);
326         m_treeview->set_fixed_height_mode(false);
327         m_treeview->set_hover_selection(false);
328         m_treeview->set_size_request(-1, 150);
329         recent_scrolledwindow->set_flags(Gtk::CAN_FOCUS);
330         recent_scrolledwindow->set_border_width(6);
331         recent_scrolledwindow->set_shadow_type(Gtk::SHADOW_IN);
332         recent_scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
333         recent_scrolledwindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT);
334         recent_scrolledwindow->add(*m_treeview);
335
336         recent_sesion_label->set_padding(0,0);
337         recent_sesion_label->set_line_wrap(false);
338         recent_sesion_label->set_selectable(false);
339         recent_frame->set_border_width(12);
340         recent_frame->set_shadow_type(Gtk::SHADOW_NONE);
341         recent_frame->add(*recent_scrolledwindow);
342         recent_frame->set_label_widget(*recent_sesion_label);
343         open_session_vbox->pack_start(*recent_frame, Gtk::PACK_EXPAND_WIDGET, 0);
344         open_session_vbox->pack_start(*open_session_hbox, Gtk::PACK_SHRINK, 12);
345
346         m_notebook->set_flags(Gtk::CAN_FOCUS);
347         m_notebook->set_scrollable(true);
348         
349         get_vbox()->set_homogeneous(false);
350         get_vbox()->set_spacing(0);
351         get_vbox()->pack_start(*m_notebook, Gtk::PACK_SHRINK, 0);
352
353         /* 
354            icon setting is done again in the editor (for the whole app),
355            but its all chickens and eggs at this point.
356         */
357
358         list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
359         Glib::RefPtr<Gdk::Pixbuf> icon;
360
361         if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
362                 window_icons.push_back (icon);
363         }
364         if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
365                 window_icons.push_back (icon);
366         }
367         if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
368                 window_icons.push_back (icon);
369         }
370         if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
371                 window_icons.push_back (icon);
372         }
373         if (!window_icons.empty()) {
374                 set_icon_list (window_icons);
375         }
376
377         WindowTitle title(Glib::get_application_name());
378         title += _("Session Control");
379         set_title(title.get_string());
380
381         //set_modal(false);
382         //property_window_position().set_value(Gtk::WIN_POS_NONE);
383         set_resizable(false);
384         //property_destroy_with_parent().set_value(false);
385         set_has_separator(false);
386         // add_button(Gtk::Stock::HELP, Gtk::RESPONSE_HELP);
387         add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CANCEL);
388         add_button(Gtk::Stock::CLEAR, Gtk::RESPONSE_NONE);
389         m_okbutton = add_button(Gtk::Stock::NEW, Gtk::RESPONSE_OK);
390
391         recent_model = Gtk::TreeStore::create (recent_columns);
392         m_treeview->set_model (recent_model);
393         m_treeview->append_column (_("Recent Sessions"), recent_columns.visible_name);
394         m_treeview->set_headers_visible (false);
395         m_treeview->get_selection()->set_mode (Gtk::SELECTION_SINGLE);
396
397         std::string path = ARDOUR::get_user_ardour_path();
398         
399         if (path.empty()) {
400                 path = ARDOUR::get_system_data_path();
401         }
402
403         const char * const template_dir_name = X_("templates");
404
405         if (!path.empty()) {
406                 string user_template_path = path + template_dir_name;
407
408                 if (Glib::file_test(user_template_path, Glib::FILE_TEST_IS_DIR))
409                 {
410                         m_template->set_current_folder (user_template_path);
411                 }
412         }
413
414         const std::string sys_templates_dir = ARDOUR::get_system_data_path() + template_dir_name;
415         
416         if (Glib::file_test(sys_templates_dir, Glib::FILE_TEST_IS_DIR))
417         {
418                 m_template->add_shortcut_folder(sys_templates_dir);
419         }
420
421         m_template->set_title(_("select template"));
422         Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
423         session_filter->add_pattern(X_("*.ardour"));
424         session_filter->add_pattern(X_("*.ardour.bak"));
425         m_open_filechooser->set_filter (*session_filter);
426         m_open_filechooser->set_current_folder(getenv ("HOME"));
427         m_open_filechooser->set_title(_("select session file"));
428
429         Gtk::FileFilter* template_filter = manage (new (Gtk::FileFilter));
430         template_filter->add_pattern(X_("*.ardour"));
431         template_filter->add_pattern(X_("*.ardour.bak"));
432         template_filter->add_pattern(X_("*.template"));
433         m_template->set_filter (*template_filter);
434
435         m_folder->set_current_folder(getenv ("HOME"));
436         m_folder->set_title(_("select directory"));
437
438         on_new_session_page = true;
439         m_notebook->set_current_page(0);
440         m_notebook->show();
441         m_notebook->show_all_children();
442
443
444         set_default_response (Gtk::RESPONSE_OK);
445         if (!ARDOUR_COMMAND_LINE::session_name.length()) {
446                 set_response_sensitive (Gtk::RESPONSE_OK, false);
447                 set_response_sensitive (Gtk::RESPONSE_NONE, false);
448         } else {
449                 set_response_sensitive (Gtk::RESPONSE_OK, true);
450                 set_response_sensitive (Gtk::RESPONSE_NONE, true);
451         }
452
453         ///@ connect some signals
454
455         m_connect_inputs->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::connect_inputs_clicked));
456         m_connect_outputs->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::connect_outputs_clicked));
457         m_limit_input_ports->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::limit_inputs_clicked));
458         m_limit_output_ports->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::limit_outputs_clicked));
459         m_create_master_bus->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::master_bus_button_clicked));
460         m_create_control_bus->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::monitor_bus_button_clicked));
461         m_name->signal_changed().connect(mem_fun (*this, &NewSessionDialog::on_new_session_name_entry_changed));
462         m_notebook->signal_switch_page().connect (mem_fun (*this, &NewSessionDialog::notebook_page_changed));
463         m_treeview->get_selection()->signal_changed().connect (mem_fun (*this, &NewSessionDialog::treeview_selection_changed));
464         m_treeview->signal_row_activated().connect (mem_fun (*this, &NewSessionDialog::recent_row_activated));
465         m_open_filechooser->signal_selection_changed ().connect (mem_fun (*this, &NewSessionDialog::file_chosen));
466         m_template->signal_selection_changed ().connect (mem_fun (*this, &NewSessionDialog::template_chosen));
467         
468         page_set = Pages (0);
469 }
470
471 NewSessionDialog::~NewSessionDialog()
472 {
473         in_destructor = true;
474 }
475
476 int
477 NewSessionDialog::run ()
478 {
479         if (!page_set) {
480                 /* nothing to display */
481                 return Gtk::RESPONSE_OK;
482         }
483
484         return ArdourDialog::run ();
485 }
486
487 void
488 NewSessionDialog::set_have_engine (bool yn)
489 {
490         if (yn) {
491                 m_notebook->remove_page (engine_control);
492                 page_set = Pages (page_set & ~EnginePage);
493         } else {
494                 if (!(page_set & EnginePage)) {
495                         m_notebook->append_page (engine_control, _("Audio Setup"));
496                         m_notebook->show_all_children();
497                         page_set = Pages (page_set | EnginePage);
498                 }
499         }
500 }
501
502 void
503 NewSessionDialog::set_existing_session (bool yn)
504 {
505         if (yn) {
506
507                 if (page_set & NewPage) {
508                         m_notebook->remove_page (*new_session_table);
509                         page_set = Pages (page_set & ~NewPage);
510                 }
511
512                 if (page_set & OpenPage) {
513                         m_notebook->remove_page (*open_session_vbox);
514                         page_set = Pages (page_set & ~OpenPage);
515                 }
516
517         } else {
518                 if (!(page_set & NewPage)) {
519                         m_notebook->append_page(*new_session_table, _("New Session"));
520                         m_notebook->pages().back().set_tab_label_packing(false, true, Gtk::PACK_START);
521                         page_set = Pages (page_set | NewPage);
522                 }
523                 if (!(page_set & OpenPage)) {
524                         m_notebook->append_page(*open_session_vbox, _("Open Session"));
525                         m_notebook->pages().back().set_tab_label_packing(false, true, Gtk::PACK_START);
526                         page_set = Pages (page_set | OpenPage);
527                 }
528
529                 m_notebook->show_all_children();
530         }
531 }
532
533 void
534 NewSessionDialog::set_session_name (const Glib::ustring& name)
535 {
536         m_name->set_text (name);
537 }
538
539 void
540 NewSessionDialog::set_session_folder(const Glib::ustring& dir)
541 {
542         char buf[PATH_MAX];
543
544         char *res = realpath (dir.c_str(), buf);
545
546         if (res) {
547
548                 cerr << "canonical = " << res << endl;
549
550                 Glib::ustring realdir = res;
551                 
552                 if (!Glib::file_test (realdir, Glib::FILE_TEST_IS_DIR)) {
553                         realdir = Glib::path_get_dirname (realdir);
554                         cerr << "no such dir, use " << realdir << endl;
555                 }
556
557                 m_folder->set_current_folder (realdir);
558         } else {
559                 cerr << dir << " not resolvable\n";
560         }
561 }
562
563 std::string
564 NewSessionDialog::session_name() const
565 {
566         std::string str = Glib::filename_from_utf8(m_open_filechooser->get_filename());
567         std::string::size_type position = str.find_last_of ('/');
568         str = str.substr (position+1);
569         position = str.find_last_of ('.');
570         str = str.substr (0, position);
571
572         /*
573           XXX what to do if it's a .bak file?
574           load_session doesn't allow it!
575
576         if ((position = str.rfind(".bak")) != string::npos) {
577                 str = str.substr (0, position);
578         }         
579         */
580
581         switch (which_page()) {
582         case NewPage:
583         case EnginePage:
584                 /* new or audio setup pages */
585                 return Glib::filename_from_utf8(m_name->get_text());
586         default:
587                 break;
588         } 
589
590         if (m_treeview->get_selection()->count_selected_rows() == 0) {
591                 return Glib::filename_from_utf8(str);
592         }
593         Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected();
594         return (*i)[recent_columns.visible_name];
595 }
596
597 std::string
598 NewSessionDialog::session_folder() const
599 {
600         switch (which_page()) {
601         case NewPage:
602                 return Glib::filename_from_utf8(m_folder->get_filename());
603                 
604         default:
605                 break;
606         }
607                
608         if (m_treeview->get_selection()->count_selected_rows() == 0) {
609                 const string filename(Glib::filename_from_utf8(m_open_filechooser->get_filename()));
610                 return Glib::path_get_dirname(filename);
611         }
612
613         Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected();
614         return (*i)[recent_columns.fullpath];
615 }
616
617 bool
618 NewSessionDialog::use_session_template() const
619 {
620         if(m_template->get_filename().empty() && (which_page() == NewPage)) return false;
621         return true;
622 }
623
624 std::string
625 NewSessionDialog::session_template_name() const
626 {
627         return Glib::filename_from_utf8(m_template->get_filename());
628 }
629
630 bool
631 NewSessionDialog::create_master_bus() const
632 {
633         return m_create_master_bus->get_active();
634 }
635
636 int
637 NewSessionDialog::master_channel_count() const
638 {
639         return m_master_bus_channel_count->get_value_as_int();
640 }
641
642 bool
643 NewSessionDialog::create_control_bus() const
644 {
645         return m_create_control_bus->get_active();
646 }
647
648 int
649 NewSessionDialog::control_channel_count() const
650 {
651         return m_control_bus_channel_count->get_value_as_int();
652 }
653
654 bool
655 NewSessionDialog::connect_inputs() const
656 {
657         return m_connect_inputs->get_active();
658 }
659
660 bool
661 NewSessionDialog::limit_inputs_used_for_connection() const
662 {
663         return m_limit_input_ports->get_active();
664 }
665
666 int
667 NewSessionDialog::input_limit_count() const
668 {
669         return m_input_limit_count->get_value_as_int();
670 }
671
672 bool
673 NewSessionDialog::connect_outputs() const
674 {
675         return m_connect_outputs->get_active();
676 }
677
678 bool
679 NewSessionDialog::limit_outputs_used_for_connection() const
680 {
681         return m_limit_output_ports->get_active();
682 }
683
684 int
685 NewSessionDialog::output_limit_count() const
686 {
687         return m_output_limit_count->get_value_as_int();
688 }
689
690 bool
691 NewSessionDialog::connect_outs_to_master() const
692 {
693         return m_connect_outputs_to_master->get_active();
694 }
695
696 bool
697 NewSessionDialog::connect_outs_to_physical() const
698 {
699         return m_connect_outputs_to_physical->get_active();
700 }
701
702 int
703 NewSessionDialog::get_current_page()
704 {
705         return m_notebook->get_current_page();
706 }
707
708 NewSessionDialog::Pages
709 NewSessionDialog::which_page () const
710 {
711         int num = m_notebook->get_current_page();
712
713         if (page_set == NewPage) {
714                 return NewPage;
715
716         } else if (page_set == OpenPage) {
717                 return OpenPage;
718
719         } else if (page_set == EnginePage) {
720                 return EnginePage;
721
722         } else if (page_set == NewPage|OpenPage) {
723                 switch (num) {
724                 case 0:
725                         return NewPage;
726                 default:
727                         return OpenPage;
728                 }
729
730         } else if (page_set == NewPage|EnginePage) {
731                 switch (num) {
732                 case 0:
733                         return NewPage;
734                 default:
735                         return EnginePage;
736                 }
737
738         } else if (page_set == NewPage|EnginePage|OpenPage) {
739                 switch (num) {
740                 case 0:
741                         return NewPage;
742                 case 1:
743                         return OpenPage;
744                 default:
745                         return EnginePage;
746                 }
747
748         } else if (page_set == OpenPage|EnginePage) {
749                 switch (num) {
750                 case 0:
751                         return OpenPage;
752                 default:
753                         return EnginePage;
754                 }
755         }
756 }
757
758 void
759 NewSessionDialog::set_current_page(int page)
760 {
761         return m_notebook->set_current_page (page);
762 }
763
764 void
765 NewSessionDialog::reset_name()
766 {
767         m_name->set_text("");
768         set_response_sensitive (Gtk::RESPONSE_OK, false);
769         
770 }
771
772 void
773 NewSessionDialog::on_new_session_name_entry_changed ()
774 {
775         if (m_name->get_text() != "") {
776                 set_response_sensitive (Gtk::RESPONSE_OK, true);
777                 set_response_sensitive (Gtk::RESPONSE_NONE, true);
778         } else {
779                 set_response_sensitive (Gtk::RESPONSE_OK, false);
780         }
781 }
782
783 void
784 NewSessionDialog::notebook_page_changed (GtkNotebookPage* np, uint pagenum)
785 {
786         if (in_destructor) {
787                 return;
788         }
789
790         switch (which_page()) {
791         case OpenPage:
792                 on_new_session_page = false;
793                 m_okbutton->set_label(_("Open"));
794                 m_okbutton->set_image (*(manage (new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON))));
795                 set_response_sensitive (Gtk::RESPONSE_NONE, false);
796                 if (m_treeview->get_selection()->count_selected_rows() == 0) {
797                         set_response_sensitive (Gtk::RESPONSE_OK, false);
798                 } else {
799                         set_response_sensitive (Gtk::RESPONSE_OK, true);
800                 }
801                 break;
802
803         case EnginePage:
804                 on_new_session_page = false;
805                 m_okbutton->set_label(_("Open"));
806                 m_okbutton->set_image (*(manage (new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON))));
807                 set_response_sensitive (Gtk::RESPONSE_NONE, false);
808                 set_response_sensitive (Gtk::RESPONSE_OK, true);
809                 break;
810
811         default:
812                 on_new_session_page = true;
813                 m_okbutton->set_label(_("New"));
814                 m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON)));
815                 if (m_name->get_text() == "") {
816                         set_response_sensitive (Gtk::RESPONSE_OK, false);
817                         m_name->grab_focus();
818                 } else {
819                         set_response_sensitive (Gtk::RESPONSE_OK, true);
820                 }
821         }
822 }
823
824 void
825 NewSessionDialog::treeview_selection_changed ()
826 {
827         if (m_treeview->get_selection()->count_selected_rows() == 0) {
828                 if (!m_open_filechooser->get_filename().empty()) {
829                         set_response_sensitive (Gtk::RESPONSE_OK, true);
830                 } else {
831                         set_response_sensitive (Gtk::RESPONSE_OK, false);
832                 }
833         } else {
834                 set_response_sensitive (Gtk::RESPONSE_OK, true);
835         }
836 }
837
838 void
839 NewSessionDialog::file_chosen ()
840 {
841         switch (which_page()) {
842       case OpenPage:
843          break;
844            case NewPage:
845            case EnginePage:
846                    return;
847         }
848
849         m_treeview->get_selection()->unselect_all();
850
851         Glib::RefPtr<Gdk::Window> win (get_window());
852
853         if (win) {
854                 win->set_cursor(Gdk::Cursor(Gdk::WATCH));
855         }
856
857         if (!m_open_filechooser->get_filename().empty()) {
858                 set_response_sensitive (Gtk::RESPONSE_OK, true);
859                 response (Gtk::RESPONSE_OK);
860         } else {
861                 set_response_sensitive (Gtk::RESPONSE_OK, false);
862         }
863 }
864
865 void
866 NewSessionDialog::template_chosen ()
867 {
868         if (m_template->get_filename() != "" ) {;
869                 set_response_sensitive (Gtk::RESPONSE_NONE, true);
870         } else {
871                 set_response_sensitive (Gtk::RESPONSE_NONE, false);
872         }
873 }
874
875 void
876 NewSessionDialog::recent_row_activated (const Gtk::TreePath& path, Gtk::TreeViewColumn* col)
877 {
878         response (Gtk::RESPONSE_YES);
879 }
880
881 void
882 NewSessionDialog::connect_inputs_clicked ()
883 {
884         m_limit_input_ports->set_sensitive(m_connect_inputs->get_active());
885
886                 if (m_connect_inputs->get_active() && m_limit_input_ports->get_active()) {
887                 m_input_limit_count->set_sensitive(true);
888                 } else {
889                 m_input_limit_count->set_sensitive(false);
890                 }
891 }
892
893 void
894 NewSessionDialog::connect_outputs_clicked ()
895 {
896         m_limit_output_ports->set_sensitive(m_connect_outputs->get_active());
897
898                 if (m_connect_outputs->get_active() && m_limit_output_ports->get_active()) {
899                 m_output_limit_count->set_sensitive(true);
900                 } else {
901                 m_output_limit_count->set_sensitive(false);
902                 }
903 }
904
905 void
906 NewSessionDialog::limit_inputs_clicked ()
907 {
908         m_input_limit_count->set_sensitive(m_limit_input_ports->get_active());
909 }
910
911 void
912 NewSessionDialog::limit_outputs_clicked ()
913 {
914         m_output_limit_count->set_sensitive(m_limit_output_ports->get_active());
915 }
916
917 void
918 NewSessionDialog::master_bus_button_clicked ()
919 {
920         m_master_bus_channel_count->set_sensitive(m_create_master_bus->get_active());
921 }
922
923 void
924 NewSessionDialog::monitor_bus_button_clicked ()
925 {
926         m_control_bus_channel_count->set_sensitive(m_create_control_bus->get_active());
927 }
928
929 void
930 NewSessionDialog::reset_template()
931 {
932         m_template->unselect_all ();
933 }
934
935 void
936 NewSessionDialog::reset_recent()
937 {
938         /* Shamelessly ripped from ardour_ui.cc */
939         std::vector<string *> *sessions;
940         std::vector<string *>::iterator i;
941         RecentSessionsSorter cmp;
942         
943         recent_model->clear ();
944
945         ARDOUR::RecentSessions rs;
946         ARDOUR::read_recent_sessions (rs);
947         
948         /* sort them alphabetically */
949         sort (rs.begin(), rs.end(), cmp);
950         sessions = new std::vector<std::string*>;
951         
952         for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
953                 sessions->push_back (new string ((*i).second));
954         }
955         
956         for (i = sessions->begin(); i != sessions->end(); ++i) {
957
958                 std::vector<std::string*>* states;
959                 std::vector<const gchar*> item;
960                 std::string fullpath = *(*i);
961                 
962                 /* remove any trailing / */
963                 
964                 if (fullpath[fullpath.length()-1] == '/') {
965                         fullpath = fullpath.substr (0, fullpath.length()-1);
966                 }
967             
968                 /* now get available states for this session */
969                   
970                 if ((states = ARDOUR::Session::possible_states (fullpath)) == 0) {
971                         /* no state file? */
972                         continue;
973                 }
974             
975                 Gtk::TreeModel::Row row = *(recent_model->append());
976                 
977                 row[recent_columns.visible_name] = Glib::path_get_basename (fullpath);
978                 row[recent_columns.fullpath] = fullpath;
979                 
980                 if (states->size()) {
981                     
982                         /* add the children */
983                     
984                         for (std::vector<std::string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
985
986                                 Gtk::TreeModel::Row child_row = *(recent_model->append (row.children()));
987                                 
988                                 child_row[recent_columns.visible_name] = **i2;
989                                 child_row[recent_columns.fullpath] = fullpath;
990                                 
991                                 delete *i2;
992                         }
993                 }
994
995                 delete states;
996         }
997         delete sessions;
998 }
999
1000 void
1001 NewSessionDialog::reset()
1002 {
1003         reset_name();
1004         reset_template();
1005         set_response_sensitive (Gtk::RESPONSE_NONE, false);
1006 }