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