Optimize automation-event process splitting
[ardour.git] / gtk2_ardour / sfdb_ui.cc
1 /*
2     Copyright (C) 2005-2006 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 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #endif
23
24 #include <map>
25 #include <cerrno>
26 #include <sstream>
27
28 #include <unistd.h>
29 #include <limits.h>
30
31 #include <gtkmm/box.h>
32 #include <gtkmm/scrolledwindow.h>
33 #include <gtkmm/stock.h>
34
35 #include "pbd/gstdio_compat.h"
36 #include <glibmm/fileutils.h>
37
38 #include "pbd/tokenizer.h"
39 #include "pbd/enumwriter.h"
40 #include "pbd/pthread_utils.h"
41 #include "pbd/string_convert.h"
42 #include "pbd/xml++.h"
43
44 #include <gtkmm2ext/utils.h>
45
46 #include "evoral/SMF.hpp"
47
48 #include "ardour/audio_library.h"
49 #include "ardour/auditioner.h"
50 #include "ardour/audioregion.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/midi_region.h"
53 #include "ardour/smf_source.h"
54 #include "ardour/region_factory.h"
55 #include "ardour/source_factory.h"
56 #include "ardour/session.h"
57 #include "ardour/session_directory.h"
58 #include "ardour/srcfilesource.h"
59 #include "ardour/profile.h"
60
61 #include "ardour_ui.h"
62 #include "editing.h"
63 #include "gui_thread.h"
64 #include "sfdb_ui.h"
65 #include "editing.h"
66 #include "gain_meter.h"
67 #include "main_clock.h"
68 #include "public_editor.h"
69 #include "timers.h"
70 #include "ui_config.h"
71
72 #include "sfdb_freesound_mootcher.h"
73
74 #include "pbd/i18n.h"
75
76 using namespace ARDOUR;
77 using namespace PBD;
78 using namespace std;
79 using namespace Gtk;
80 using namespace Gtkmm2ext;
81 using namespace Editing;
82
83 using std::string;
84
85 string SoundFileBrowser::persistent_folder;
86 typedef TreeView::Selection::ListHandle_Path ListPath;
87
88 static MidiTrackNameSource
89 string2miditracknamesource (string const & str)
90 {
91         if (str == _("by track number")) {
92                 return SMFTrackNumber;
93         } else if (str == _("by track name")) {
94                 return SMFTrackName;
95         } else if (str == _("by instrument name")) {
96                 return SMFInstrumentName;
97         }
98
99         warning << string_compose (_("programming error: unknown midi track name source string %1"), str) << endmsg;
100
101         return SMFTrackNumber;
102 }
103
104 static ImportMode
105 string2importmode (string const & str)
106 {
107         if (str == _("as new tracks")) {
108                 return ImportAsTrack;
109         } else if (str == _("to selected tracks")) {
110                 return ImportToTrack;
111         } else if (str == _("to region list")) {
112                 return ImportAsRegion;
113         } else if (str == _("as new tape tracks")) {
114                 return ImportAsTapeTrack;
115         }
116
117         warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
118
119         return ImportAsTrack;
120 }
121
122 static string
123 importmode2string (ImportMode mode)
124 {
125         switch (mode) {
126         case ImportAsTrack:
127                 return _("as new tracks");
128         case ImportToTrack:
129                 return _("to selected tracks");
130         case ImportAsRegion:
131                 return _("to region list");
132         case ImportAsTapeTrack:
133                 return _("as new tape tracks");
134         }
135         abort(); /*NOTREACHED*/
136         return _("as new tracks");
137 }
138
139 SoundFileBox::SoundFileBox (bool /*persistent*/)
140         : table (7, 2),
141           length_clock ("sfboxLengthClock", true, "", false, false, true, false),
142           timecode_clock ("sfboxTimecodeClock", true, "", false, false, false, false),
143           main_box (false, 6),
144           autoplay_btn (_("Auto-play")),
145           seek_slider(0,1000,1),
146           _seeking(false),
147           _src_quality (SrcBest),
148           _import_position (ImportAtTimestamp)
149
150 {
151         set_name (X_("SoundFileBox"));
152         set_size_request (300, -1);
153
154         preview_label.set_markup (_("<b>Sound File Information</b>"));
155
156         border_frame.set_label_widget (preview_label);
157         border_frame.add (main_box);
158
159         pack_start (border_frame, true, true);
160         set_border_width (6);
161
162         main_box.set_border_width (6);
163
164         length.set_text (_("Length:"));
165         length.set_alignment (1, 0.5);
166         timecode.set_text (_("Timestamp:"));
167         timecode.set_alignment (1, 0.5);
168         format.set_text (_("Format:"));
169         format.set_alignment (1, 0.5);
170         channels.set_text (_("Channels:"));
171         channels.set_alignment (1, 0.5);
172         samplerate.set_text (_("Sample rate:"));
173         samplerate.set_alignment (1, 0.5);
174         tempomap.set_text (_("Tempo Map:"));
175         tempomap.set_alignment (1, 0.5);
176
177         preview_label.set_max_width_chars (50);
178         preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
179
180         format_text.set_max_width_chars (20);
181         format_text.set_ellipsize (Pango::ELLIPSIZE_END);
182         format_text.set_alignment (0, 1);
183
184         table.set_col_spacings (6);
185         table.set_homogeneous (false);
186         table.set_row_spacings (6);
187
188         table.attach (channels, 0, 1, 0, 1, FILL, FILL);
189         table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
190         table.attach (format, 0, 1, 2, 4, FILL, FILL);
191         table.attach (length, 0, 1, 4, 5, FILL, FILL);
192         table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
193         table.attach (tempomap, 0, 1, 6, 7, FILL, FILL);
194
195         table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
196         table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
197         table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
198         table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
199         table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
200         table.attach (tempomap_value, 1, 2, 6, 7, FILL, FILL);
201
202         length_clock.set_mode (ARDOUR_UI::instance()->primary_clock->mode());
203         timecode_clock.set_mode (AudioClock::Timecode);
204
205         main_box.pack_start (table, false, false);
206
207         tags_entry.set_editable (true);
208         tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
209         tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
210
211         Label* label = manage (new Label (_("Tags:")));
212         label->set_alignment (0.0f, 0.5f);
213         main_box.pack_start (*label, false, false);
214         main_box.pack_start (tags_entry, true, true);
215
216         main_box.pack_start (bottom_box, false, false);
217
218         play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
219 //      play_btn.set_label (_("Play"));
220
221         stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
222 //      stop_btn.set_label (_("Stop"));
223
224         bottom_box.set_homogeneous (false);
225         bottom_box.set_spacing (6);
226         bottom_box.pack_start(play_btn, true, true);
227         bottom_box.pack_start(stop_btn, true, true);
228         bottom_box.pack_start(autoplay_btn, false, false);
229
230         seek_slider.set_draw_value(false);
231
232         seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
233         seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
234         seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
235         main_box.pack_start (seek_slider, false, false);
236
237         play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
238         stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
239
240         update_autoplay ();
241         autoplay_btn.signal_toggled().connect(sigc::mem_fun (*this, &SoundFileBox::autoplay_toggled));
242
243         stop_btn.set_sensitive (false);
244
245         channels_value.set_alignment (0.0f, 0.5f);
246         samplerate_value.set_alignment (0.0f, 0.5f);
247 }
248
249 void
250 SoundFileBox::set_session(Session* s)
251 {
252         SessionHandlePtr::set_session (s);
253
254         length_clock.set_session (s);
255         timecode_clock.set_session (s);
256
257         if (!_session) {
258                 play_btn.set_sensitive (false);
259                 stop_btn.set_sensitive (false);
260                 auditioner_connections.drop_connections();
261         } else {
262                 auditioner_connections.drop_connections();
263                 _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
264                 _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
265         }
266 }
267
268 void
269 SoundFileBox::audition_active(bool active) {
270         stop_btn.set_sensitive (active);
271         seek_slider.set_sensitive (active);
272         if (!active) {
273                 seek_slider.set_value(0);
274         }
275 }
276
277 void
278 SoundFileBox::audition_progress(ARDOUR::samplecnt_t pos, ARDOUR::samplecnt_t len) {
279         if (!_seeking) {
280                 seek_slider.set_value( 1000.0 * pos / len);
281                 seek_slider.set_sensitive (true);
282         }
283 }
284
285 bool
286 SoundFileBox::seek_button_press(GdkEventButton*) {
287         _seeking = true;
288         return false; // pass on to slider
289 }
290
291 bool
292 SoundFileBox::seek_button_release(GdkEventButton*) {
293         _seeking = false;
294         _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
295         seek_slider.set_sensitive (false);
296         return false; // pass on to slider
297 }
298
299 bool
300 SoundFileBox::setup_labels (const string& filename)
301 {
302         if (!path.empty()) {
303                 // save existing tags
304                 tags_changed ();
305         }
306
307         path = filename;
308
309         string error_msg;
310
311         if (SMFSource::valid_midi_file (path)) {
312
313                 boost::shared_ptr<SMFSource> ms;
314                 try {
315                         ms = boost::dynamic_pointer_cast<SMFSource> (
316                                 SourceFactory::createExternal (DataType::MIDI, *_session,
317                                                                path, 0, Source::Flag (0), false));
318                 } catch (const std::exception& e) {
319                         error << string_compose(_("Could not read file: %1 (%2)."),
320                                                 path, e.what()) << endmsg;
321                 }
322
323                 preview_label.set_markup (_("<b>Midi File Information</b>"));
324
325                 format_text.set_text ("MIDI");
326                 samplerate_value.set_text ("-");
327                 tags_entry.get_buffer()->set_text ("");
328                 timecode_clock.set (0);
329                 tags_entry.set_sensitive (false);
330
331                 if (ms) {
332                         if (ms->is_type0()) {
333                                 channels_value.set_text (to_string<uint32_t>(ms->channels().size()));
334                         } else {
335                                 if (ms->num_tracks() > 1) {
336                                         channels_value.set_text (to_string(ms->num_tracks()) + _("(Tracks)"));
337                                 } else {
338                                         channels_value.set_text (to_string(ms->num_tracks()));
339                                 }
340                         }
341                         length_clock.set (ms->length(ms->timeline_position()));
342                         switch (ms->num_tempos()) {
343                         case 0:
344                                 tempomap_value.set_text (_("No tempo data"));
345                                 break;
346                         case 1: {
347                                 Evoral::SMF::Tempo* t = ms->nth_tempo (0);
348                                 assert (t);
349                                 tempomap_value.set_text (string_compose (_("%1/%2 \u2669 = %3"),
350                                                                          t->numerator,
351                                                                          t->denominator,
352                                                                          t->tempo ()));
353                                 break;
354                         }
355                         default:
356                                 tempomap_value.set_text (string_compose (_("map with %1 sections"),
357                                                                          ms->num_tempos()));
358                                 break;
359                         }
360                 } else {
361                         channels_value.set_text ("");
362                         length_clock.set (0);
363                         tempomap_value.set_text (_("No tempo data"));
364                 }
365
366                 if (_session && ms) {
367                         play_btn.set_sensitive (true);
368                 } else {
369                         play_btn.set_sensitive (false);
370                 }
371
372                 return true;
373         }
374
375         if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
376
377                 preview_label.set_markup (_("<b>Sound File Information</b>"));
378                 format_text.set_text ("");
379                 channels_value.set_text ("");
380                 samplerate_value.set_text ("");
381                 tags_entry.get_buffer()->set_text ("");
382
383                 length_clock.set (0);
384                 timecode_clock.set (0);
385
386                 tags_entry.set_sensitive (false);
387                 play_btn.set_sensitive (false);
388
389                 return false;
390         }
391
392         preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
393         std::string n = sf_info.format_name;
394         if (n.substr (0, 8) == X_("Format: ")) {
395                 n = n.substr (8);
396         }
397         format_text.set_text (n);
398         channels_value.set_text (to_string (sf_info.channels));
399
400         if (_session && sf_info.samplerate != _session->sample_rate()) {
401                 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
402                 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
403                 samplerate_value.set_name ("NewSessionSR1Label");
404                 samplerate.set_name ("NewSessionSR1Label");
405         } else {
406                 samplerate.set_text (_("Sample rate:"));
407                 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
408                 samplerate_value.set_name ("NewSessionSR2Label");
409                 samplerate.set_name ("NewSessionSR2Label");
410         }
411
412         samplecnt_t const nfr = _session ? _session->nominal_sample_rate() : 25;
413         double src_coef = (double) nfr / sf_info.samplerate;
414
415         length_clock.set (sf_info.length * src_coef + 0.5, true);
416         timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
417
418         // this is a hack that is fixed in trunk, i think (august 26th, 2007)
419
420         vector<string> tags = Library->get_tags (string ("//") + filename);
421
422         stringstream tag_string;
423         for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
424                 if (i != tags.begin()) {
425                         tag_string << ", ";
426                 }
427                 tag_string << *i;
428         }
429         tags_entry.get_buffer()->set_text (tag_string.str());
430
431         tags_entry.set_sensitive (true);
432         if (_session) {
433                 play_btn.set_sensitive (true);
434         }
435
436         return true;
437 }
438
439 void
440 SoundFileBox::update_autoplay ()
441 {
442         const bool config_autoplay = UIConfiguration::instance().get_autoplay_files();
443
444         if (autoplay_btn.get_active() != config_autoplay) {
445                 autoplay_btn.set_active (config_autoplay);
446         }
447 }
448
449 void
450 SoundFileBox::autoplay_toggled()
451 {
452         UIConfiguration::instance().set_autoplay_files(autoplay_btn.get_active());
453 }
454
455 bool
456 SoundFileBox::autoplay() const
457 {
458         return autoplay_btn.get_active();
459 }
460
461 bool
462 SoundFileBox::audition_oneshot()
463 {
464         audition ();
465         return false;
466 }
467
468 void
469 SoundFileBox::audition ()
470 {
471         if (!_session) {
472                 return;
473         }
474
475         _session->cancel_audition();
476
477         if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
478                 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
479                 return;
480         }
481
482         boost::shared_ptr<Region> r;
483
484         if (SMFSource::valid_midi_file (path)) {
485
486                 boost::shared_ptr<SMFSource> ms =
487                         boost::dynamic_pointer_cast<SMFSource> (
488                                         SourceFactory::createExternal (DataType::MIDI, *_session,
489                                                                                          path, 0, Source::Flag (0), false));
490
491                 string rname = region_name_from_path (ms->path(), false);
492
493                 PropertyList plist;
494
495                 plist.add (ARDOUR::Properties::start, 0);
496                 plist.add (ARDOUR::Properties::length, ms->length(ms->timeline_position()));
497                 plist.add (ARDOUR::Properties::name, rname);
498                 plist.add (ARDOUR::Properties::layer, 0);
499
500                 r = boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (boost::dynamic_pointer_cast<Source>(ms), plist, false));
501                 assert(r);
502
503         } else {
504
505                 SourceList srclist;
506                 boost::shared_ptr<AudioFileSource> afs;
507                 bool old_sbp = AudioSource::get_build_peakfiles ();
508
509                 /* don't even think of building peakfiles for these files */
510
511                 AudioSource::set_build_peakfiles (false);
512
513                 for (int n = 0; n < sf_info.channels; ++n) {
514                         try {
515                                 afs = boost::dynamic_pointer_cast<AudioFileSource> (
516                                         SourceFactory::createExternal (DataType::AUDIO, *_session,
517                                                                                          path, n,
518                                                                                          Source::Flag (ARDOUR::AudioFileSource::NoPeakFile), false));
519                                 if (afs->sample_rate() != _session->nominal_sample_rate()) {
520                                         boost::shared_ptr<SrcFileSource> sfs (new SrcFileSource(*_session, afs, _src_quality));
521                                         srclist.push_back(sfs);
522                                 } else {
523                                         srclist.push_back(afs);
524                                 }
525
526                         } catch (failed_constructor& err) {
527                                 error << _("Could not access soundfile: ") << path << endmsg;
528                                 AudioSource::set_build_peakfiles (old_sbp);
529                                 return;
530                         }
531                 }
532
533                 AudioSource::set_build_peakfiles (old_sbp);
534
535                 if (srclist.empty()) {
536                         return;
537                 }
538
539                 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
540                 string rname = region_name_from_path (afs->path(), false);
541
542                 PropertyList plist;
543
544                 plist.add (ARDOUR::Properties::start, 0);
545                 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
546                 plist.add (ARDOUR::Properties::name, rname);
547                 plist.add (ARDOUR::Properties::layer, 0);
548
549                 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
550         }
551
552         sampleoffset_t audition_position = 0;
553         switch(_import_position) {
554                 case ImportAtTimestamp:
555                         audition_position = 0;
556                         break;
557                 case ImportAtPlayhead:
558                         audition_position = _session->transport_sample();
559                         break;
560                 case ImportAtStart:
561                         audition_position = _session->current_start_sample();
562                         break;
563                 case ImportAtEditPoint:
564                         audition_position = PublicEditor::instance().get_preferred_edit_position ();
565                         break;
566         }
567         r->set_position(audition_position);
568
569         _session->audition_region(r);
570 }
571
572 void
573 SoundFileBox::stop_audition ()
574 {
575         if (_session) {
576                 _session->cancel_audition();
577         }
578 }
579
580 bool
581 SoundFileBox::tags_entry_left (GdkEventFocus *)
582 {
583         tags_changed ();
584         return false;
585 }
586
587 void
588 SoundFileBox::tags_changed ()
589 {
590         string tag_string = tags_entry.get_buffer()->get_text ();
591
592         if (tag_string.empty()) {
593                 return;
594         }
595
596         vector<string> tags;
597
598         if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
599                 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
600                 return;
601         }
602
603         save_tags (tags);
604 }
605
606 void
607 SoundFileBox::save_tags (const vector<string>& tags)
608 {
609         Library->set_tags (string ("//") + path, tags);
610         Library->save_changes ();
611 }
612
613 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
614         : ArdourWindow (title)
615         , found_list (ListStore::create(found_list_columns))
616         , freesound_list (ListStore::create(freesound_list_columns))
617         , chooser (FILE_CHOOSER_ACTION_OPEN)
618         , preview (persistent)
619         , found_search_btn (_("Search"))
620         , found_list_view (found_list)
621         , freesound_search_btn (_("Search"))
622         , freesound_list_view (freesound_list)
623         , resetting_ourselves (false)
624         , matches (0)
625         , _status (0)
626         , _done (false)
627         , import_button (_("Import"))
628         , gm (0)
629 {
630
631 #ifdef __APPLE__
632         try {
633                 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
634                 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
635                 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
636                 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
637         }
638         catch (Glib::Error & e) {
639                 std::cerr << "sfdb.add_shortcut_folder() threw Glib::Error " << e.what() << std::endl;
640         }
641 #endif
642         Gtkmm2ext::add_volume_shortcuts (chooser);
643
644         //add the file chooser
645
646         chooser.set_border_width (12);
647
648         audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
649         audio_and_midi_filter.set_name (_("Audio and MIDI files"));
650
651         audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
652         audio_filter.set_name (_("Audio files"));
653
654         midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
655         midi_filter.set_name (_("MIDI files"));
656
657         matchall_filter.add_pattern ("*.*");
658         matchall_filter.set_name (_("All files"));
659
660         chooser.add_filter (audio_and_midi_filter);
661         chooser.add_filter (audio_filter);
662         chooser.add_filter (midi_filter);
663         chooser.add_filter (matchall_filter);
664         chooser.set_select_multiple (true);
665         chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
666         chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
667
668 #ifdef __APPLE__
669         /* some broken redraw behaviour - this is a bandaid */
670         chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
671 #endif
672
673         if (!persistent_folder.empty()) {
674                 chooser.set_current_folder (persistent_folder);
675         }
676
677         notebook.append_page (chooser, _("Browse Files"));
678
679         hpacker.set_spacing (6);
680         hpacker.pack_start (notebook, true, true);
681         hpacker.pack_start (preview, false, false);
682
683         vpacker.set_spacing (6);
684         vpacker.pack_start (hpacker, true, true);
685
686         add (vpacker);
687
688         //add tag search
689
690         VBox* vbox;
691         HBox* hbox;
692
693
694         hbox = manage(new HBox);
695         hbox->pack_start (found_entry);
696         hbox->pack_start (found_search_btn);
697
698         Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
699         scroll->add(found_list_view);
700         scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
701
702         vbox = manage(new VBox);
703         vbox->pack_start (*hbox, PACK_SHRINK);
704         vbox->pack_start (*scroll);
705
706         found_list_view.append_column(_("Paths"), found_list_columns.pathname);
707
708         found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
709
710         found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
711
712         found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
713         found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
714
715         notebook.append_page (*vbox, _("Search Tags"));
716
717         //add freesound search
718 #ifdef FREESOUND_GOT_FIXED
719
720         HBox* passbox;
721         Label* label;
722
723         passbox = manage(new HBox);
724         passbox->set_spacing (6);
725
726         label = manage (new Label);
727         label->set_text (_("Tags:"));
728         passbox->pack_start (*label, false, false);
729         passbox->pack_start (freesound_entry, true, true);
730
731         label = manage (new Label);
732         label->set_text (_("Sort:"));
733         passbox->pack_start (*label, false, false);
734         passbox->pack_start (freesound_sort, false, false);
735         freesound_sort.clear_items();
736
737         // Order of the following must correspond with enum sortMethod
738         // in sfdb_freesound_mootcher.h
739         freesound_sort.append_text(_("None"));
740         freesound_sort.append_text(_("Longest"));
741         freesound_sort.append_text(_("Shortest"));
742         freesound_sort.append_text(_("Newest"));
743         freesound_sort.append_text(_("Oldest"));
744         freesound_sort.append_text(_("Most downloaded"));
745         freesound_sort.append_text(_("Least downloaded"));
746         freesound_sort.append_text(_("Highest rated"));
747         freesound_sort.append_text(_("Lowest rated"));
748         freesound_sort.set_active(0);
749
750         passbox->pack_start (freesound_search_btn, false, false);
751         passbox->pack_start (freesound_more_btn, false, false);
752         freesound_more_btn.set_label(_("More"));
753         freesound_more_btn.set_sensitive(false);
754
755         passbox->pack_start (freesound_similar_btn, false, false);
756         freesound_similar_btn.set_label(_("Similar"));
757         freesound_similar_btn.set_sensitive(false);
758
759         scroll = manage(new ScrolledWindow);
760         scroll->add(freesound_list_view);
761         scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
762
763         vbox = manage(new VBox);
764         vbox->set_spacing (3);
765         vbox->pack_start (*passbox, PACK_SHRINK);
766         vbox->pack_start (*scroll);
767
768         freesound_list_view.append_column(_("ID")      , freesound_list_columns.id);
769         freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
770         // freesound_list_view.append_column(_("URI")     , freesound_list_columns.uri);
771         freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
772         freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
773         freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
774         freesound_list_view.append_column(_("License"), freesound_list_columns.license);
775         freesound_list_view.get_column(0)->set_alignment(0.5);
776         freesound_list_view.get_column(1)->set_expand(true); // filename
777         freesound_list_view.get_column(1)->set_resizable(true); // filename
778         freesound_list_view.get_column(2)->set_alignment(0.5);
779         freesound_list_view.get_column(3)->set_alignment(0.5);
780         freesound_list_view.get_column(4)->set_alignment(0.5);
781         freesound_list_view.get_column(5)->set_alignment(0.5);
782
783         freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
784         freesound_list_view.set_tooltip_column(1);
785
786         freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
787         freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
788         freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
789         freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
790         freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
791         freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
792         notebook.append_page (*vbox, _("Search Freesound"));
793 #endif
794
795         notebook.set_size_request (500, -1);
796         notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
797
798         set_session (s);
799
800         Gtk::HButtonBox* button_box = manage (new HButtonBox);
801
802         button_box->set_layout (BUTTONBOX_END);
803
804         button_box->pack_start (import_button, false, false);
805         import_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
806
807         Gtkmm2ext::UI::instance()->set_tip (import_button, _("Press to import selected files"));
808
809         vpacker.pack_end (*button_box, false, false);
810
811         set_wmclass (X_("import"), PROGRAM_NAME);
812 }
813
814 SoundFileBrowser::~SoundFileBrowser ()
815 {
816         persistent_folder = chooser.get_current_folder();
817 }
818
819 int
820 SoundFileBrowser::run ()
821 {
822         set_modal (true);
823         show_all ();
824         present ();
825
826         _done = false;
827
828         while (!_done) {
829                 gtk_main_iteration ();
830         }
831
832         return _status;
833 }
834
835 void
836 SoundFileBrowser::set_action_sensitive (bool yn)
837 {
838         import_button.set_sensitive (yn);
839 }
840
841 bool
842 SoundFileBrowser::get_action_sensitive () const
843 {
844         return import_button.get_sensitive ();
845 }
846
847 void
848 SoundFileBrowser::do_something (int action)
849 {
850         _done = true;
851         _status = action;
852 }
853
854 void
855 SoundFileBrowser::on_show ()
856 {
857         ArdourWindow::on_show ();
858         reset_options ();
859         start_metering ();
860 }
861
862 bool
863 SoundFileBrowser::on_key_press_event (GdkEventKey* ev)
864 {
865         if (ev->keyval == GDK_Escape) {
866                 do_something (RESPONSE_CLOSE);
867                 return true;
868         }
869         if (ev->keyval == GDK_space && ev->type == GDK_KEY_PRESS) {
870                 if (get_action_sensitive()) {
871                         preview.audition();
872                         return true;
873                 }
874         }
875         return ArdourWindow::on_key_press_event (ev);
876 }
877
878 void
879 SoundFileBrowser::clear_selection ()
880 {
881         chooser.unselect_all ();
882         found_list_view.get_selection()->unselect_all ();
883 }
884
885 void
886 SoundFileBrowser::chooser_file_activated ()
887 {
888         do_something (RESPONSE_OK);
889 }
890
891 void
892 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
893 {
894         preview.audition ();
895 }
896
897 void
898 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
899 {
900         preview.audition ();
901 }
902
903 void
904 SoundFileBrowser::set_session (Session* s)
905 {
906         ArdourWindow::set_session (s);
907         preview.set_session (s);
908
909         if (_session) {
910                 add_gain_meter ();
911         } else {
912                 remove_gain_meter ();
913         }
914 }
915
916 void
917 SoundFileBrowser::add_gain_meter ()
918 {
919         delete gm;
920
921         gm = new GainMeter (_session, 250);
922
923         boost::shared_ptr<Route> r = _session->the_auditioner ();
924
925         gm->set_controls (r, r->shared_peak_meter(), r->amp(), r->gain_control());
926         gm->set_fader_name (X_("GainFader"));
927
928         meter_packer.set_border_width (12);
929         meter_packer.pack_start (*gm, false, true);
930         hpacker.pack_end (meter_packer, false, false);
931         meter_packer.show_all ();
932         start_metering ();
933 }
934
935 void
936 SoundFileBrowser::remove_gain_meter ()
937 {
938         if (gm) {
939                 meter_packer.remove (*gm);
940                 hpacker.remove (meter_packer);
941                 delete gm;
942                 gm = 0;
943         }
944 }
945
946 void
947 SoundFileBrowser::start_metering ()
948 {
949         metering_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
950 }
951
952 void
953 SoundFileBrowser::stop_metering ()
954 {
955         metering_connection.disconnect();
956 }
957
958 void
959 SoundFileBrowser::meter ()
960 {
961         if (is_mapped () && _session && gm) {
962                 gm->update_meters ();
963         }
964 }
965
966 bool
967 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
968 {
969         return AudioFileSource::safe_audio_file_extension (filter_info.filename);
970 }
971
972 bool
973 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
974 {
975         return SMFSource::safe_midi_file_extension (filter_info.filename);
976 }
977
978 bool
979 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
980 {
981         return on_audio_filter (filter_info) || on_midi_filter (filter_info);
982 }
983
984 void
985 SoundFileBrowser::update_preview ()
986 {
987         if (preview.setup_labels (chooser.get_preview_filename())) {
988                 if (preview.autoplay()) {
989                         Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
990                 }
991         }
992 }
993
994 void
995 SoundFileBrowser::found_list_view_selected ()
996 {
997         if (!reset_options ()) {
998                 set_action_sensitive (false);
999         } else {
1000                 string file;
1001
1002                 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1003
1004                 if (!rows.empty()) {
1005                         TreeIter iter = found_list->get_iter(*rows.begin());
1006                         file = (*iter)[found_list_columns.pathname];
1007                         chooser.set_filename (file);
1008                         set_action_sensitive (true);
1009                 } else {
1010                         set_action_sensitive (false);
1011                 }
1012
1013                 preview.setup_labels (file);
1014         }
1015 }
1016
1017 void
1018 SoundFileBrowser::found_search_clicked ()
1019 {
1020         string tag_string = found_entry.get_text ();
1021
1022         vector<string> tags;
1023
1024         if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
1025                 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
1026                 return;
1027         }
1028
1029         vector<string> results;
1030         Library->search_members_and (results, tags);
1031
1032         found_list->clear();
1033         for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
1034                 TreeModel::iterator new_row = found_list->append();
1035                 TreeModel::Row row = *new_row;
1036                 string path = Glib::filename_from_uri (string ("file:") + *i);
1037                 row[found_list_columns.pathname] = path;
1038         }
1039 }
1040
1041
1042 std::string
1043 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
1044 {
1045
1046         Mootcher *mootcher = new Mootcher;
1047         std::string file;
1048
1049         string id  = (*iter)[freesound_list_columns.id];
1050         string uri = (*iter)[freesound_list_columns.uri];
1051         string ofn = (*iter)[freesound_list_columns.filename];
1052
1053         if (mootcher->checkAudioFile(ofn, id)) {
1054                 // file already exists, no need to download it again
1055                 file = mootcher->audioFileName;
1056                 delete mootcher;
1057                 (*iter)[freesound_list_columns.started] = false;
1058                 return file;
1059         }
1060         if (!(*iter)[freesound_list_columns.started]) {
1061                 // start downloading the sound file
1062                 (*iter)[freesound_list_columns.started] = true;
1063                 mootcher->fetchAudioFile(ofn, id, uri, this);
1064         }
1065         return "";
1066 }
1067
1068 void
1069 SoundFileBrowser::freesound_list_view_selected ()
1070 {
1071
1072         if (!reset_options ()) {
1073                 set_action_sensitive (false);
1074         } else {
1075                 std::string file;
1076                 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1077                 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1078                         file = freesound_get_audio_file (freesound_list->get_iter(*i));
1079                 }
1080
1081                 switch (rows.size()) {
1082                         case 0:
1083                                 // nothing selected
1084                                 freesound_similar_btn.set_sensitive(false);
1085                                 set_action_sensitive (false);
1086                                 break;
1087                         case 1:
1088                                 // exactly one item selected
1089                                 if (file != "") {
1090                                         // file exists on disk already
1091                                         chooser.set_filename (file);
1092                                         preview.setup_labels (file);
1093                                         set_action_sensitive (true);
1094                                 }
1095                                 freesound_similar_btn.set_sensitive(true);
1096                                 break;
1097                         default:
1098                                 // multiple items selected
1099                                 preview.setup_labels ("");
1100                                 freesound_similar_btn.set_sensitive(false);
1101                                 break;
1102                 }
1103
1104         }
1105 }
1106
1107 void
1108 SoundFileBrowser::refresh_display(std::string ID, std::string file)
1109 {
1110         // called when the mootcher has finished downloading a file
1111         ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1112         if (rows.size() == 1) {
1113                 // there's a single item selected in the freesound list
1114                 //XXX make a function to be used to construct the actual file name both here and in the mootcher
1115                 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
1116                 std::string selected_ID = (*row)[freesound_list_columns.id];
1117                 if (ID == selected_ID) {
1118                         // the selected item in the freesound list is the item that has just finished downloading
1119                         chooser.set_filename(file);
1120                         preview.setup_labels (file);
1121                         set_action_sensitive (true);
1122                 }
1123         }
1124 }
1125
1126 void
1127 SoundFileBrowser::freesound_search_clicked ()
1128 {
1129         freesound_page = 1;
1130         freesound_list->clear();
1131         matches = 0;
1132         freesound_search();
1133 }
1134
1135 void
1136 SoundFileBrowser::freesound_more_clicked ()
1137 {
1138         char row_path[21];
1139         freesound_page++;
1140         freesound_search();
1141         snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
1142         freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
1143 }
1144
1145 void
1146 SoundFileBrowser::freesound_similar_clicked ()
1147 {
1148         ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1149         if (rows.size() == 1) {
1150                 Mootcher mootcher;
1151                 string id;
1152                 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
1153                 id = (*iter)[freesound_list_columns.id];
1154                 freesound_list->clear();
1155
1156                 GdkCursor *prev_cursor;
1157                 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1158                 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1159                 gdk_flush();
1160
1161                 std::string theString = mootcher.searchSimilar(id);
1162
1163                 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1164                 handle_freesound_results(theString);
1165         }
1166 }
1167
1168 void
1169 SoundFileBrowser::freesound_search()
1170 {
1171         Mootcher mootcher;
1172
1173         string search_string = freesound_entry.get_text ();
1174         enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1175
1176         GdkCursor *prev_cursor;
1177         prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1178         gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1179         gdk_flush();
1180
1181         std::string theString = mootcher.searchText(
1182                         search_string,
1183                         freesound_page,
1184 #ifdef __APPLE__
1185                         "", // OSX eats anything incl mp3
1186 #else
1187                         "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1188 #endif
1189                         sort_method
1190                         );
1191
1192         gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1193         handle_freesound_results(theString);
1194 }
1195
1196 void
1197 SoundFileBrowser::handle_freesound_results(std::string theString) {
1198         XMLTree doc;
1199         doc.read_buffer( theString );
1200         XMLNode *root = doc.root();
1201
1202         if (!root) {
1203                 error << "no root XML node!" << endmsg;
1204                 return;
1205         }
1206
1207         if ( strcmp(root->name().c_str(), "response") != 0) {
1208                 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1209                 return;
1210         }
1211
1212         // find out how many pages are available to search
1213         int freesound_n_pages = 1;
1214         XMLNode *res = root->child("num_pages");
1215         if (res) {
1216                 string result = res->child("text")->content();
1217                 freesound_n_pages = atoi(result);
1218         }
1219
1220         int more_pages = freesound_n_pages - freesound_page;
1221
1222         if (more_pages > 0) {
1223                 freesound_more_btn.set_sensitive(true);
1224                 freesound_more_btn.set_tooltip_text(string_compose(P_(
1225                                                 "%1 more page of 100 results available",
1226                                                 "%1 more pages of 100 results available",
1227                                                 more_pages), more_pages));
1228         } else {
1229                 freesound_more_btn.set_sensitive(false);
1230                 freesound_more_btn.set_tooltip_text(_("No more results available"));
1231         }
1232
1233         XMLNode *sounds_root = root->child("sounds");
1234         if (!sounds_root) {
1235                 error << "no child node \"sounds\" found!" << endmsg;
1236                 return;
1237         }
1238
1239         XMLNodeList sounds = sounds_root->children();
1240         if (sounds.size() == 0) {
1241                 /* nothing found */
1242                 return;
1243         }
1244
1245         XMLNodeConstIterator niter;
1246         XMLNode *node;
1247         for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1248                 node = *niter;
1249                 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1250                         error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1251                         break;
1252                 }
1253
1254                 // node->dump(cerr, "node:");
1255
1256
1257                 XMLNode *id_node  = node->child ("id");
1258                 XMLNode *uri_node = node->child ("serve");
1259                 XMLNode *ofn_node = node->child ("original_filename");
1260                 XMLNode *dur_node = node->child ("duration");
1261                 XMLNode *siz_node = node->child ("filesize");
1262                 XMLNode *srt_node = node->child ("samplerate");
1263                 XMLNode *lic_node = node->child ("license");
1264
1265                 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1266
1267                         std::string  id =  id_node->child("text")->content();
1268                         std::string uri = uri_node->child("text")->content();
1269                         std::string ofn = ofn_node->child("text")->content();
1270                         std::string dur = dur_node->child("text")->content();
1271                         std::string siz = siz_node->child("text")->content();
1272                         std::string srt = srt_node->child("text")->content();
1273                         std::string lic = lic_node->child("text")->content();
1274
1275                         std::string r;
1276                         // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1277
1278                         double duration_seconds = atof(dur);
1279                         double h, m, s;
1280                         char duration_hhmmss[16];
1281                         if (duration_seconds >= 99 * 60 * 60) {
1282                                 strcpy(duration_hhmmss, ">99h");
1283                         } else {
1284                                 s = modf(duration_seconds/60, &m) * 60;
1285                                 m = modf(m/60, &h) * 60;
1286                                 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1287                                                 h, m, s
1288                                        );
1289                         }
1290
1291                         double size_bytes = atof(siz);
1292                         char bsize[32];
1293                         if (size_bytes < 1000) {
1294                                 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1295                         } else if (size_bytes < 1000000 ) {
1296                                 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1297                         } else if (size_bytes < 10000000) {
1298                                 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1299                         } else if (size_bytes < 1000000000) {
1300                                 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1301                         } else {
1302                                 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1303                         }
1304
1305                         /* see http://www.freesound.org/help/faq/#licenses */
1306                         char shortlicense[64];
1307                         if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1308                                 sprintf(shortlicense, "CC-BY-NC");
1309                         } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1310                                 sprintf(shortlicense, "CC-BY");
1311                         } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1312                                 sprintf(shortlicense, "sampling+");
1313                         } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1314                                 sprintf(shortlicense, "PD");
1315                         } else {
1316                                 snprintf(shortlicense, 64, "%s", lic.c_str());
1317                                 shortlicense[63]= '\0';
1318                         }
1319
1320                         TreeModel::iterator new_row = freesound_list->append();
1321                         TreeModel::Row row = *new_row;
1322
1323                         row[freesound_list_columns.id      ] = id;
1324                         row[freesound_list_columns.uri     ] = uri;
1325                         row[freesound_list_columns.filename] = ofn;
1326                         row[freesound_list_columns.duration] = duration_hhmmss;
1327                         row[freesound_list_columns.filesize] = bsize;
1328                         row[freesound_list_columns.smplrate] = srt;
1329                         row[freesound_list_columns.license ] = shortlicense;
1330                         matches++;
1331                 }
1332         }
1333 }
1334
1335 vector<string>
1336 SoundFileBrowser::get_paths ()
1337 {
1338         vector<string> results;
1339
1340         int n = notebook.get_current_page ();
1341
1342         if (n == 0) {
1343                 vector<string> filenames = chooser.get_filenames();
1344                 vector<string>::iterator i;
1345
1346                 for (i = filenames.begin(); i != filenames.end(); ++i) {
1347                         GStatBuf buf;
1348                         if ((!g_stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1349                                 results.push_back (*i);
1350                         }
1351                 }
1352
1353         } else if (n == 1) {
1354
1355                 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1356                 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1357                         TreeIter iter = found_list->get_iter(*i);
1358                         string str = (*iter)[found_list_columns.pathname];
1359
1360                         results.push_back (str);
1361                 }
1362         } else {
1363                 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1364                 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1365                         string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1366                         if (str != "") {
1367                                 results.push_back (str);
1368                         }
1369                 }
1370         }
1371
1372         return results;
1373 }
1374
1375 void
1376 SoundFileOmega::reset_options_noret ()
1377 {
1378         if (!resetting_ourselves) {
1379                 (void) reset_options ();
1380         }
1381 }
1382
1383 bool
1384 SoundFileOmega::reset_options ()
1385 {
1386         if (_import_active) {
1387                 _reset_post_import = true;
1388                 return true;
1389         }
1390
1391         vector<string> paths = get_paths ();
1392
1393         if (paths.empty()) {
1394
1395                 channel_combo.set_sensitive (false);
1396                 action_combo.set_sensitive (false);
1397                 where_combo.set_sensitive (false);
1398                 copy_files_btn.set_active (true);
1399                 copy_files_btn.set_sensitive (false);
1400
1401                 return false;
1402
1403         } else {
1404
1405                 channel_combo.set_sensitive (true);
1406                 action_combo.set_sensitive (true);
1407                 where_combo.set_sensitive (true);
1408
1409                 /* if we get through this function successfully, this may be
1410                    reset at the end, once we know if we can use hard links
1411                    to do embedding (or if we are importing a MIDI file).
1412                 */
1413
1414                 if (UIConfiguration::instance().get_only_copy_imported_files()) {
1415                         copy_files_btn.set_sensitive (false);
1416                 } else {
1417                         copy_files_btn.set_sensitive (false);
1418                 }
1419         }
1420
1421         bool same_size;
1422         bool src_needed;
1423         bool selection_includes_multichannel;
1424         bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1425         ImportMode mode;
1426
1427         /* See if we are thinking about importing any MIDI files */
1428         vector<string>::iterator i = paths.begin ();
1429         while (i != paths.end() && SMFSource::valid_midi_file (*i) == false) {
1430                 ++i;
1431         }
1432         bool const have_a_midi_file = (i != paths.end ());
1433
1434         if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1435                 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1436                 return false;
1437         }
1438
1439         if (have_a_midi_file) {
1440                 smf_tempo_btn.show ();
1441         } else {
1442                 smf_tempo_btn.hide ();
1443         }
1444
1445         string existing_choice;
1446         vector<string> action_strings;
1447
1448         resetting_ourselves = true;
1449
1450         if (chooser.get_filter() == &audio_filter) {
1451
1452                 /* AUDIO */
1453
1454                 if (selected_audio_track_cnt > 0) {
1455                         if (channel_combo.get_active_text().length()) {
1456                                 ImportDisposition id = get_channel_disposition();
1457
1458                                 switch (id) {
1459                                 case Editing::ImportDistinctFiles:
1460                                         if (selected_audio_track_cnt == paths.size()) {
1461                                                 action_strings.push_back (importmode2string (ImportToTrack));
1462                                         }
1463                                         break;
1464
1465                                 case Editing::ImportDistinctChannels:
1466                                         /* XXX it would be nice to allow channel-per-selected track
1467                                            but its too hard we don't want to deal with all the
1468                                            different per-file + per-track channel configurations.
1469                                         */
1470                                         break;
1471
1472                                 default:
1473                                         action_strings.push_back (importmode2string (ImportToTrack));
1474                                         break;
1475                                 }
1476                         }
1477                 }
1478
1479         }  else {
1480
1481                 /* MIDI ONLY */
1482
1483                 if (selected_midi_track_cnt > 0) {
1484                         action_strings.push_back (importmode2string (ImportToTrack));
1485                 }
1486         }
1487
1488         action_strings.push_back (importmode2string (ImportAsTrack));
1489         action_strings.push_back (importmode2string (ImportAsRegion));
1490         if (!Profile->get_mixbus()) {
1491                 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1492         }
1493
1494         existing_choice = action_combo.get_active_text();
1495
1496         set_popdown_strings (action_combo, action_strings);
1497
1498         /* preserve any existing choice, if possible */
1499
1500
1501         if (existing_choice.length()) {
1502                 vector<string>::iterator x;
1503                 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1504                         if (*x == existing_choice) {
1505                                 action_combo.set_active_text (existing_choice);
1506                                 break;
1507                         }
1508                 }
1509                 if (x == action_strings.end()) {
1510                         action_combo.set_active_text (action_strings.front());
1511                 }
1512         } else {
1513                 action_combo.set_active_text (action_strings.front());
1514         }
1515
1516         resetting_ourselves = false;
1517
1518         if ((mode = get_mode()) == ImportAsRegion) {
1519                 where_combo.set_sensitive (false);
1520         } else {
1521                 where_combo.set_sensitive (true);
1522         }
1523
1524         vector<string> channel_strings;
1525
1526         if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1527
1528                 if (selection_includes_multichannel) {
1529                         channel_strings.push_back (_("one track per channel"));
1530                 }
1531
1532                 channel_strings.push_back (_("one track per file"));
1533
1534                 if (paths.size() > 1) {
1535                         /* tape tracks are a single region per track, so we cannot
1536                            sequence multiple files.
1537                         */
1538                         if (mode != ImportAsTapeTrack) {
1539                                 channel_strings.push_back (_("sequence files"));
1540                         }
1541                         if (same_size) {
1542                                 channel_strings.push_back (_("all files in one track"));
1543                                 channel_strings.push_back (_("merge files"));
1544                         }
1545
1546                 }
1547
1548         } else {
1549                 channel_strings.push_back (_("one region per file"));
1550
1551                 if (selection_includes_multichannel) {
1552                         channel_strings.push_back (_("one region per channel"));
1553                 }
1554
1555                 if (paths.size() > 1) {
1556                         if (same_size) {
1557                                 channel_strings.push_back (_("all files in one region"));
1558                         }
1559                 }
1560         }
1561
1562         resetting_ourselves = true;
1563
1564         existing_choice = channel_combo.get_active_text();
1565
1566         set_popdown_strings (channel_combo, channel_strings);
1567
1568         /* preserve any existing choice, if possible */
1569
1570         if (existing_choice.length()) {
1571                 vector<string>::iterator x;
1572                 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1573                         if (*x == existing_choice) {
1574                                 channel_combo.set_active_text (existing_choice);
1575                                 break;
1576                         }
1577                 }
1578                 if (x == channel_strings.end()) {
1579                         channel_combo.set_active_text (channel_strings.front());
1580                 }
1581         } else {
1582                 channel_combo.set_active_text (channel_strings.front());
1583         }
1584
1585         resetting_ourselves = false;
1586
1587         if (src_needed) {
1588                 src_combo.set_sensitive (true);
1589         } else {
1590                 src_combo.set_sensitive (false);
1591         }
1592
1593         /* We must copy MIDI files or those from Freesound
1594          * or any file if we are under nsm control */
1595         bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1596
1597         if (UIConfiguration::instance().get_only_copy_imported_files()) {
1598
1599                 if (selection_can_be_embedded_with_links && !must_copy) {
1600                         copy_files_btn.set_sensitive (true);
1601                 } else {
1602                         if (must_copy) {
1603                                 copy_files_btn.set_active (true);
1604                         }
1605                         copy_files_btn.set_sensitive (false);
1606                 }
1607
1608         }  else {
1609
1610                 if (must_copy) {
1611                         copy_files_btn.set_active (true);
1612                 }
1613                 copy_files_btn.set_sensitive (!must_copy);
1614         }
1615
1616         return true;
1617 }
1618
1619
1620 bool
1621 SoundFileOmega::bad_file_message()
1622 {
1623         MessageDialog msg (*this,
1624                            string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1625                            true,
1626                            Gtk::MESSAGE_INFO,
1627                            Gtk::BUTTONS_OK);
1628         msg.run ();
1629         resetting_ourselves = true;
1630         chooser.unselect_uri (chooser.get_preview_uri());
1631         resetting_ourselves = false;
1632
1633         return false;
1634 }
1635
1636 bool
1637 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1638 {
1639         SoundFileInfo info;
1640         samplepos_t sz = 0;
1641         bool err = false;
1642         string errmsg;
1643
1644         same_size = true;
1645         src_needed = false;
1646         multichannel = false;
1647
1648         for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1649
1650                 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1651                         if (info.channels > 1) {
1652                                 multichannel = true;
1653                         }
1654                         if (sz == 0) {
1655                                 sz = info.length;
1656                         } else {
1657                                 if (sz != info.length) {
1658                                         same_size = false;
1659                                 }
1660                         }
1661
1662                         if (info.samplerate != _session->sample_rate()) {
1663                                 src_needed = true;
1664                         }
1665
1666                 } else if (SMFSource::valid_midi_file (*i)) {
1667
1668                         Evoral::SMF reader;
1669
1670                         if (reader.open (*i)) {
1671                                 err = true;
1672                         } else {
1673                                 if (reader.is_type0 ()) {
1674                                         if (reader.channels().size() > 1) {
1675                                                 /* for type-0 files, we can split
1676                                                  * "one track per channel"
1677                                                  */
1678                                                 multichannel = true;
1679                                         }
1680                                 } else {
1681                                         if (reader.num_tracks() > 1) {
1682                                                 multichannel = true;
1683                                         }
1684                                 }
1685                         }
1686
1687                 } else {
1688                         err = true;
1689                 }
1690         }
1691
1692         return err;
1693 }
1694
1695
1696 bool
1697 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1698 {
1699 #ifdef PLATFORM_WINDOWS
1700         return false;
1701 #else
1702         std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1703         bool ret = false;
1704
1705         if (g_mkdir (tmpdir.c_str(), 0744)) {
1706                 if (errno != EEXIST) {
1707                         return false;
1708                 }
1709         }
1710
1711         for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1712
1713                 char tmpc[PATH_MAX+1];
1714
1715                 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1716
1717                 /* can we link ? */
1718
1719                 if (link ((*i).c_str(), tmpc)) {
1720                         goto out;
1721                 }
1722
1723                 ::g_unlink (tmpc);
1724         }
1725
1726         ret = true;
1727
1728   out:
1729         g_rmdir (tmpdir.c_str());
1730         return ret;
1731 #endif
1732 }
1733
1734 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1735         : SoundFileBrowser (title, s, false)
1736 {
1737         chooser.set_select_multiple (false);
1738         found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1739         freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1740 }
1741
1742 void
1743 SoundFileChooser::on_hide ()
1744 {
1745         ArdourWindow::on_hide();
1746         stop_metering ();
1747
1748         if (_session) {
1749                 _session->cancel_audition();
1750         }
1751 }
1752
1753 string
1754 SoundFileChooser::get_filename ()
1755 {
1756         vector<string> paths;
1757
1758         paths = get_paths ();
1759
1760         if (paths.empty()) {
1761                 return string ();
1762         }
1763
1764         if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1765                 return string();
1766         }
1767
1768         return paths.front();
1769 }
1770
1771 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1772                                 uint32_t selected_audio_tracks,
1773                                 uint32_t selected_midi_tracks,
1774                                 bool persistent,
1775                                 Editing::ImportMode mode_hint)
1776         : SoundFileBrowser (title, s, persistent)
1777         , copy_files_btn ( _("Copy files to session"))
1778         , smf_tempo_btn (_("Use MIDI Tempo Map (if defined)"))
1779         , selected_audio_track_cnt (selected_audio_tracks)
1780         , selected_midi_track_cnt (selected_midi_tracks)
1781         , _import_active (false)
1782         , _reset_post_import (false)
1783 {
1784         vector<string> str;
1785
1786         set_size_request (-1, 550);
1787
1788         block_two.set_border_width (12);
1789         block_three.set_border_width (12);
1790         block_four.set_border_width (12);
1791
1792         str.clear ();
1793         str.push_back (_("file timestamp"));
1794         str.push_back (_("edit point"));
1795         str.push_back (_("playhead"));
1796         str.push_back (_("session start"));
1797         set_popdown_strings (where_combo, str);
1798         where_combo.set_active_text (str.back());
1799         where_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::where_combo_changed));
1800
1801         Label* l = manage (new Label);
1802         l->set_markup (_("<b>Add files ...</b>"));
1803         options.attach (*l, 0, 1, 0, 1, FILL, SHRINK, 8, 0);
1804         options.attach (action_combo, 0, 1, 1, 2, FILL, SHRINK, 8, 0);
1805
1806         l = manage (new Label);
1807         l->set_markup (_("<b>Insert at</b>"));
1808         options.attach (*l, 0, 1, 3, 4, FILL, SHRINK, 8, 0);
1809         options.attach (where_combo, 0, 1, 4, 5, FILL, SHRINK, 8, 0);
1810
1811         l = manage (new Label);
1812         l->set_markup (_("<b>Mapping</b>"));
1813         options.attach (*l, 1, 2, 0, 1, FILL, SHRINK, 8, 0);
1814         options.attach (channel_combo, 1, 2, 1, 2, FILL, SHRINK, 8, 0);
1815
1816         l = manage (new Label);
1817         l->set_markup (_("<b>Conversion quality</b>"));
1818         options.attach (*l, 1, 2, 3, 4, FILL, SHRINK, 8, 0);
1819         options.attach (src_combo, 1, 2, 4, 5, FILL, SHRINK, 8, 0);
1820
1821         l = manage (new Label);
1822         l->set_markup (_("<b>MIDI Track Names</b>"));
1823         options.attach (*l, 2, 3, 0, 1, FILL, SHRINK, 8, 0);
1824         options.attach (midi_track_name_combo, 2, 3, 1, 2, FILL, SHRINK, 8, 0);
1825
1826         options.attach (smf_tempo_btn, 2, 3, 3, 4, FILL, SHRINK, 8, 0);
1827
1828         l = manage (new Label);
1829         l->set_markup (_("<b>Instrument</b>"));
1830         options.attach (*l, 3, 4, 0, 1, FILL, SHRINK, 8, 0);
1831         options.attach (instrument_combo, 3, 4, 1, 2, FILL, SHRINK, 8, 0);
1832
1833         Alignment *hspace = manage (new Alignment ());
1834         hspace->set_size_request (2, 2);
1835         options.attach (*hspace, 0, 3, 2, 3, FILL, SHRINK, 0, 8);
1836
1837         Alignment *vspace = manage (new Alignment ());
1838         vspace->set_size_request (2, 2);
1839         options.attach (*vspace, 2, 3, 0, 3, EXPAND, SHRINK, 0, 0);
1840
1841         str.clear ();
1842         str.push_back (_("by track number"));
1843         str.push_back (_("by track name"));
1844         str.push_back (_("by instrument name"));
1845         set_popdown_strings (midi_track_name_combo, str);
1846         midi_track_name_combo.set_active_text (str.front());
1847
1848         str.clear ();
1849         str.push_back (_("one track per file"));
1850         set_popdown_strings (channel_combo, str);
1851         channel_combo.set_active_text (str.front());
1852         channel_combo.set_sensitive (false);
1853
1854         str.clear ();
1855         str.push_back (_("Best"));
1856         str.push_back (_("Good"));
1857         str.push_back (_("Quick"));
1858         str.push_back (_("Fast"));
1859         str.push_back (_("Fastest"));
1860
1861         set_popdown_strings (src_combo, str);
1862         src_combo.set_active_text (str.front());
1863         src_combo.set_sensitive (false);
1864         src_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::src_combo_changed));
1865
1866         action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1867         channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1868
1869         copy_files_btn.set_active (true);
1870
1871         Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1872
1873         if (copy_label) {
1874                 copy_label->set_size_request (175, -1);
1875                 copy_label->set_line_wrap (true);
1876         }
1877
1878         block_four.pack_start (copy_files_btn, false, false);
1879         options.attach (block_four, 3, 4, 4, 5, FILL, SHRINK, 8, 0);
1880
1881         vpacker.pack_start (options, false, true);
1882
1883         /* setup disposition map */
1884
1885         disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1886         disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1887         disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1888         disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1889
1890         disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1891         disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1892         disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1893         disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1894
1895         chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1896
1897         /* set size requests for a couple of combos to allow them to display the longest text
1898            they will ever be asked to display.  This prevents them being resized when the user
1899            selects a file to import, which in turn prevents the size of the dialog from jumping
1900            around. */
1901
1902         str.clear ();
1903         str.push_back (_("one track per file"));
1904         str.push_back (_("one track per channel"));
1905         str.push_back (_("sequence files"));
1906         str.push_back (_("all files in one region"));
1907         set_popdown_strings (channel_combo, str);
1908
1909         str.clear ();
1910         str.push_back (importmode2string (ImportAsTrack));
1911         str.push_back (importmode2string (ImportToTrack));
1912         str.push_back (importmode2string (ImportAsRegion));
1913         str.push_back (importmode2string (ImportAsTapeTrack));
1914         set_popdown_strings (action_combo, str);
1915         action_combo.set_active_text (importmode2string(mode_hint));
1916
1917         reset (selected_audio_tracks, selected_midi_tracks);
1918 }
1919
1920 void
1921 SoundFileOmega::set_mode (ImportMode mode)
1922 {
1923         action_combo.set_active_text (importmode2string (mode));
1924 }
1925
1926 ImportMode
1927 SoundFileOmega::get_mode () const
1928 {
1929         return string2importmode (action_combo.get_active_text());
1930 }
1931
1932 void
1933 SoundFileOmega::on_hide ()
1934 {
1935         ArdourWindow::on_hide();
1936         if (_session) {
1937                 _session->cancel_audition();
1938         }
1939 }
1940
1941 ImportPosition
1942 SoundFileOmega::get_position() const
1943 {
1944         string str = where_combo.get_active_text();
1945
1946         if (str == _("file timestamp")) {
1947                 return ImportAtTimestamp;
1948         } else if (str == _("edit point")) {
1949                 return ImportAtEditPoint;
1950         } else if (str == _("playhead")) {
1951                 return ImportAtPlayhead;
1952         } else {
1953                 return ImportAtStart;
1954         }
1955 }
1956
1957 SrcQuality
1958 SoundFileOmega::get_src_quality() const
1959 {
1960         string str = src_combo.get_active_text();
1961
1962         if (str == _("Best")) {
1963                 return SrcBest;
1964         } else if (str == _("Good")) {
1965                 return SrcGood;
1966         } else if (str == _("Quick")) {
1967                 return SrcQuick;
1968         } else if (str == _("Fast")) {
1969                 return SrcFast;
1970         } else {
1971                 return SrcFastest;
1972         }
1973 }
1974
1975 void
1976 SoundFileOmega::src_combo_changed()
1977 {
1978         preview.set_src_quality(get_src_quality());
1979 }
1980
1981 void
1982 SoundFileOmega::where_combo_changed()
1983 {
1984         preview.set_import_position(get_position());
1985 }
1986
1987 MidiTrackNameSource
1988 SoundFileOmega::get_midi_track_name_source () const
1989 {
1990         return string2miditracknamesource (midi_track_name_combo.get_active_text());
1991 }
1992
1993 bool
1994 SoundFileOmega::get_use_smf_tempo_map () const
1995 {
1996         return smf_tempo_btn.get_active ();
1997 }
1998
1999 ImportDisposition
2000 SoundFileOmega::get_channel_disposition () const
2001 {
2002         /* we use a map here because the channel combo can contain different strings
2003            depending on the state of the other combos. the map contains all possible strings
2004            and the ImportDisposition enum that corresponds to it.
2005         */
2006
2007         string str = channel_combo.get_active_text();
2008         DispositionMap::const_iterator x = disposition_map.find (str);
2009
2010         if (x == disposition_map.end()) {
2011                 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
2012                 abort(); /*NOTREACHED*/
2013         }
2014
2015         return x->second;
2016 }
2017
2018 void
2019 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
2020 {
2021         selected_audio_track_cnt = selected_audio_tracks;
2022         selected_midi_track_cnt = selected_midi_tracks;
2023
2024         if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
2025                 chooser.set_filter (midi_filter);
2026         } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
2027                 chooser.set_filter (audio_filter);
2028         } else {
2029                 chooser.set_filter (audio_and_midi_filter);
2030         }
2031
2032         if (is_visible()) {
2033                 reset_options ();
2034         }
2035 }
2036
2037 void
2038 SoundFileOmega::file_selection_changed ()
2039 {
2040         if (resetting_ourselves || !is_visible ()) {
2041                 return;
2042         }
2043
2044         if (!reset_options ()) {
2045                 set_action_sensitive (false);
2046         } else {
2047                 if (chooser.get_filenames().size() > 0) {
2048                         set_action_sensitive (true);
2049                 } else {
2050                         set_action_sensitive (false);
2051                 }
2052         }
2053 }
2054
2055 void
2056 SoundFileOmega::do_something (int action)
2057 {
2058         SoundFileBrowser::do_something (action);
2059
2060         if (action == RESPONSE_CLOSE || !ARDOUR_UI_UTILS::engine_is_running ()) {
2061                 hide ();
2062                 return;
2063         }
2064
2065         /* lets do it */
2066
2067         vector<string> paths = get_paths ();
2068         ImportPosition pos = get_position ();
2069         ImportMode mode = get_mode ();
2070         ImportDisposition chns = get_channel_disposition ();
2071         PluginInfoPtr instrument = instrument_combo.selected_instrument();
2072         samplepos_t where;
2073         MidiTrackNameSource mts = get_midi_track_name_source ();
2074         MidiTempoMapDisposition mtd = (get_use_smf_tempo_map () ? SMFTempoUse : SMFTempoIgnore);
2075
2076         switch (pos) {
2077         case ImportAtEditPoint:
2078                 where = PublicEditor::instance().get_preferred_edit_position ();
2079                 break;
2080         case ImportAtTimestamp:
2081                 where = -1;
2082                 break;
2083         case ImportAtPlayhead:
2084                 where = _session->transport_sample();
2085                 break;
2086         case ImportAtStart:
2087                 where = _session->current_start_sample();
2088                 break;
2089         }
2090
2091         SrcQuality quality = get_src_quality();
2092
2093         _import_active = true;
2094
2095         if (copy_files_btn.get_active()) {
2096                 PublicEditor::instance().do_import (paths, chns, mode, quality, mts, mtd, where, instrument);
2097         } else {
2098                 PublicEditor::instance().do_embed (paths, chns, mode, where, instrument);
2099         }
2100
2101         _import_active = false;
2102
2103         if (_reset_post_import) {
2104                 _reset_post_import = false;
2105                 reset_options ();
2106         }
2107 }