2 Copyright (C) 2008 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "session_import_dialog.h"
23 #include "pbd/failed_constructor.h"
25 #include "ardour/audio_region_importer.h"
26 #include "ardour/audio_playlist_importer.h"
27 #include "ardour/audio_track_importer.h"
28 #include "ardour/location_importer.h"
29 #include "ardour/tempo_map_importer.h"
31 #include <gtkmm2ext/utils.h>
33 #include "gui_thread.h"
38 using namespace ARDOUR
;
42 SessionImportDialog::SessionImportDialog (ARDOUR::Session
* target
) :
43 ArdourDialog (_("Import From Session")),
44 file_browse_button (_("Browse"))
49 file_entry
.set_name ("ImportFileNameEntry");
50 file_entry
.set_text ("/");
51 Gtkmm2ext::set_size_request_to_display_given_text (file_entry
, X_("Kg/quite/a/reasonable/size/for/files/i/think"), 5, 8);
53 file_browse_button
.set_name ("EditorGTKButton");
54 file_browse_button
.signal_clicked().connect (sigc::mem_fun(*this, &SessionImportDialog::browse
));
56 file_hbox
.set_spacing (5);
57 file_hbox
.set_border_width (5);
58 file_hbox
.pack_start (file_entry
, true, true);
59 file_hbox
.pack_start (file_browse_button
, false, false);
61 file_frame
.add (file_hbox
);
62 file_frame
.set_border_width (5);
63 file_frame
.set_name ("ImportFrom");
64 file_frame
.set_label (_("Import from Session"));
66 get_vbox()->pack_start (file_frame
, false, false);
69 session_tree
= TreeStore::create (sb_cols
);
70 session_browser
.set_model (session_tree
);
72 session_browser
.set_name ("SessionBrowser");
73 session_browser
.append_column (_("Elements"), sb_cols
.name
);
74 session_browser
.append_column_editable (_("Import"), sb_cols
.queued
);
75 session_browser
.set_tooltip_column (3);
76 session_browser
.get_column(0)->set_min_width (180);
77 session_browser
.get_column(1)->set_min_width (40);
78 session_browser
.get_column(1)->set_sizing (TREE_VIEW_COLUMN_AUTOSIZE
);
80 session_scroll
.set_policy (POLICY_AUTOMATIC
, POLICY_AUTOMATIC
);
81 session_scroll
.add (session_browser
);
82 session_scroll
.set_size_request (220, 400);
85 CellRendererToggle
*toggle
= dynamic_cast<CellRendererToggle
*> (session_browser
.get_column_cell_renderer (1));
86 toggle
->signal_toggled().connect(sigc::mem_fun (*this, &SessionImportDialog::update
));
87 session_browser
.signal_row_activated().connect(sigc::mem_fun (*this, &SessionImportDialog::show_info
));
89 get_vbox()->pack_start (session_scroll
, false, false);
92 cancel_button
= add_button (Stock::CANCEL
, RESPONSE_CANCEL
);
93 cancel_button
->signal_clicked().connect (sigc::mem_fun (*this, &SessionImportDialog::end_dialog
));
94 ok_button
= add_button (_("Import"), RESPONSE_ACCEPT
);
95 ok_button
->signal_clicked().connect (sigc::mem_fun (*this, &SessionImportDialog::do_merge
));
97 // prompt signals XXX: problem - handlers to be in the same thread since they return values
98 ElementImporter::Rename
.connect_same_thread (connections
, boost::bind (&SessionImportDialog::open_rename_dialog
, this, _1
, _2
));
99 ElementImporter::Prompt
.connect_same_thread (connections
, boost::bind (&SessionImportDialog::open_prompt_dialog
, this, _1
));
106 SessionImportDialog::load_session (const string
& filename
)
109 if (tree
.read (filename
)) {
110 error
<< string_compose (_("Cannot load XML for session from %1"), filename
) << endmsg
;
113 boost::shared_ptr
<AudioRegionImportHandler
> region_handler (new AudioRegionImportHandler (tree
, *_session
));
114 boost::shared_ptr
<AudioPlaylistImportHandler
> pl_handler (new AudioPlaylistImportHandler (tree
, *_session
, *region_handler
));
116 handlers
.push_back (boost::static_pointer_cast
<ElementImportHandler
> (region_handler
));
117 handlers
.push_back (boost::static_pointer_cast
<ElementImportHandler
> (pl_handler
));
118 handlers
.push_back (HandlerPtr(new UnusedAudioPlaylistImportHandler (tree
, *_session
, *region_handler
)));
119 handlers
.push_back (HandlerPtr(new AudioTrackImportHandler (tree
, *_session
, *pl_handler
)));
120 handlers
.push_back (HandlerPtr(new LocationImportHandler (tree
, *_session
)));
121 handlers
.push_back (HandlerPtr(new TempoMapImportHandler (tree
, *_session
)));
125 if (ElementImportHandler::dirty()) {
127 string txt
= _("Some elements had errors in them. Please see the log for details");
128 MessageDialog
msg (txt
, false, MESSAGE_WARNING
, BUTTONS_OK
, true);
135 SessionImportDialog::fill_list ()
137 session_tree
->clear();
139 // Loop through element types
140 for (HandlerList::iterator handler
= handlers
.begin(); handler
!= handlers
.end(); ++handler
) {
141 TreeModel::iterator iter
= session_tree
->append();
142 TreeModel::Row row
= *iter
;
143 row
[sb_cols
.name
] = (*handler
)->get_info();
144 row
[sb_cols
.queued
] = false;
145 row
[sb_cols
.element
] = ElementPtr(); // "Null" pointer
147 // Loop through elements
148 ElementList
&elements
= (*handler
)->elements
;
149 for (ElementList::iterator element
= elements
.begin(); element
!= elements
.end(); ++element
) {
150 iter
= session_tree
->append(row
.children());
151 TreeModel::Row child
= *iter
;
152 child
[sb_cols
.name
] = (*element
)->get_name();
153 child
[sb_cols
.queued
] = false;
154 child
[sb_cols
.element
] = *element
;
155 child
[sb_cols
.info
] = (*element
)->get_info();
161 SessionImportDialog::browse ()
163 FileChooserDialog
dialog(_("Import from session"), browse_action());
164 dialog
.set_transient_for(*this);
165 dialog
.set_filename (file_entry
.get_text());
167 FileFilter session_filter
;
168 session_filter
.add_pattern ("*.ardour");
169 session_filter
.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME
));
170 dialog
.add_filter (session_filter
);
171 dialog
.set_filter (session_filter
);
173 dialog
.add_button(Stock::CANCEL
, RESPONSE_CANCEL
);
174 dialog
.add_button(Stock::OK
, RESPONSE_OK
);
176 int result
= dialog
.run();
178 if (result
== RESPONSE_OK
) {
179 string filename
= dialog
.get_filename();
181 if (filename
.length()) {
182 file_entry
.set_text (filename
);
183 load_session (filename
);
189 SessionImportDialog::do_merge ()
193 TreeModel::Children types
= session_browser
.get_model()->children();
194 TreeModel::Children::iterator ti
;
195 for (ti
= types
.begin(); ti
!= types
.end(); ++ti
) {
197 TreeModel::Children elements
= ti
->children();
198 TreeModel::Children::iterator ei
;
199 for (ei
= elements
.begin(); ei
!= elements
.end(); ++ei
) {
200 if ((*ei
)[sb_cols
.queued
]) {
201 ElementPtr element
= (*ei
)[sb_cols
.element
];
209 if (ElementImportHandler::errors()) {
211 string txt
= _("Some elements had errors in them. Please see the log for details");
212 MessageDialog
msg (txt
, false, MESSAGE_WARNING
, BUTTONS_OK
, true);
219 SessionImportDialog::update (string path
)
221 TreeModel::iterator cell
= session_browser
.get_model()->get_iter (path
);
223 // Select all elements if element type is selected
224 if (path
.size() == 1) {
226 // Prompt user for verification
227 string txt
= _("This will select all elements of this type!");
228 MessageDialog
msg (txt
, false, MESSAGE_QUESTION
, BUTTONS_OK_CANCEL
, true);
229 if (msg
.run() == RESPONSE_CANCEL
) {
230 (*cell
)[sb_cols
.queued
] = false;
235 TreeModel::Children elements
= cell
->children();
236 TreeModel::Children::iterator ei
;
237 for (ei
= elements
.begin(); ei
!= elements
.end(); ++ei
) {
238 ElementPtr element
= (*ei
)[sb_cols
.element
];
239 if (element
->prepare_move()) {
240 (*ei
)[sb_cols
.queued
] = true;
242 (*cell
)[sb_cols
.queued
] = false; // Not all are selected
248 ElementPtr element
= (*cell
)[sb_cols
.element
];
249 if ((*cell
)[sb_cols
.queued
]) {
250 if (!element
->prepare_move()) {
251 (*cell
)[sb_cols
.queued
] = false;
254 element
->cancel_move();
259 SessionImportDialog::show_info(const TreeModel::Path
& path
, TreeViewColumn
*)
261 if (path
.size() == 1) {
265 TreeModel::iterator cell
= session_browser
.get_model()->get_iter (path
);
266 string info
= (*cell
)[sb_cols
.info
];
268 MessageDialog
msg (info
, false, MESSAGE_INFO
, BUTTONS_OK
, true);
273 SessionImportDialog::end_dialog ()
278 ok_button
->set_sensitive(true);
281 std::pair
<bool, string
>
282 SessionImportDialog::open_rename_dialog (string text
, string name
)
284 ArdourPrompter
prompter(true);
287 prompter
.set_name ("Prompter");
288 prompter
.add_button (Stock::SAVE
, RESPONSE_ACCEPT
);
289 prompter
.set_prompt (text
);
290 prompter
.set_initial_text (name
);
292 if (prompter
.run() == RESPONSE_ACCEPT
) {
293 prompter
.get_result (new_name
);
294 if (new_name
.length()) {
297 return std::make_pair (true, new_name
);
299 return std::make_pair (false, new_name
);
303 SessionImportDialog::open_prompt_dialog (string text
)
305 MessageDialog
msg (text
, false, MESSAGE_QUESTION
, BUTTONS_OK_CANCEL
, true);
306 if (msg
.run() == RESPONSE_OK
) {