Add a new import file filter for audio and MIDI and use it by default (should fix...
[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 <sys/stat.h>
30 #include <sys/param.h>
31
32 #include <gtkmm/box.h>
33 #include <gtkmm/stock.h>
34 #include <glibmm/fileutils.h>
35
36 #include "pbd/convert.h"
37 #include "pbd/tokenizer.h"
38 #include "pbd/enumwriter.h"
39 #include "pbd/pthread_utils.h"
40 #include "pbd/xml++.h"
41
42 #include <gtkmm2ext/utils.h>
43
44 #include "evoral/SMF.hpp"
45
46 #include "ardour/amp.h"
47 #include "ardour/audio_library.h"
48 #include "ardour/auditioner.h"
49 #include "ardour/audioregion.h"
50 #include "ardour/audiofilesource.h"
51 #include "ardour/smf_source.h"
52 #include "ardour/region_factory.h"
53 #include "ardour/source_factory.h"
54 #include "ardour/session.h"
55 #include "ardour/session_directory.h"
56 #include "ardour/profile.h"
57
58 #include "ardour_ui.h"
59 #include "editing.h"
60 #include "gui_thread.h"
61 #include "prompter.h"
62 #include "sfdb_ui.h"
63 #include "editing.h"
64 #include "utils.h"
65 #include "gain_meter.h"
66
67 #ifdef FREESOUND
68 #include "sfdb_freesound_mootcher.h"
69 #endif
70
71 #include "i18n.h"
72
73 using namespace ARDOUR;
74 using namespace PBD;
75 using namespace std;
76 using namespace Gtk;
77 using namespace Gtkmm2ext;
78 using namespace Editing;
79
80 using std::string;
81
82 string SoundFileBrowser::persistent_folder;
83
84 static ImportMode
85 string2importmode (string str)
86 {
87         if (str == _("as new tracks")) {
88                 return ImportAsTrack;
89         } else if (str == _("to selected tracks")) {
90                 return ImportToTrack;
91         } else if (str == _("to region list")) {
92                 return ImportAsRegion;
93         } else if (str == _("as new tape tracks")) {
94                 return ImportAsTapeTrack;
95         }
96
97         warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
98
99         return ImportAsTrack;
100 }
101
102 static string
103 importmode2string (ImportMode mode)
104 {
105         switch (mode) {
106         case ImportAsTrack:
107                 return _("as new tracks");
108         case ImportToTrack:
109                 return _("to selected tracks");
110         case ImportAsRegion:
111                 return _("to region list");
112         case ImportAsTapeTrack:
113                 return _("as new tape tracks");
114         }
115         /*NOTREACHED*/
116         return _("as new tracks");
117 }
118
119 SoundFileBox::SoundFileBox (bool persistent)
120         : table (6, 2),
121           length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
122           timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
123           main_box (false, 6),
124           autoplay_btn (_("Auto-play"))
125
126 {
127         set_name (X_("SoundFileBox"));
128         set_size_request (300, -1);
129
130         preview_label.set_markup (_("<b>Sound File Information</b>"));
131
132         border_frame.set_label_widget (preview_label);
133         border_frame.add (main_box);
134
135         pack_start (border_frame, true, true);
136         set_border_width (6);
137
138         main_box.set_border_width (6);
139
140         length.set_text (_("Length:"));
141         length.set_alignment (1, 0.5);
142         timecode.set_text (_("Timestamp:"));
143         timecode.set_alignment (1, 0.5);
144         format.set_text (_("Format:"));
145         format.set_alignment (1, 0.5);
146         channels.set_text (_("Channels:"));
147         channels.set_alignment (1, 0.5);
148         samplerate.set_text (_("Sample rate:"));
149         samplerate.set_alignment (1, 0.5);
150
151         preview_label.set_max_width_chars (50);
152         preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
153
154         format_text.set_max_width_chars (20);
155         format_text.set_ellipsize (Pango::ELLIPSIZE_END);
156         format_text.set_alignment (0, 1);
157
158         table.set_col_spacings (6);
159         table.set_homogeneous (false);
160         table.set_row_spacings (6);
161
162         table.attach (channels, 0, 1, 0, 1, FILL, FILL);
163         table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
164         table.attach (format, 0, 1, 2, 4, FILL, FILL);
165         table.attach (length, 0, 1, 4, 5, FILL, FILL);
166         table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
167
168         table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
169         table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
170         table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
171         table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
172         table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
173
174         length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
175         timecode_clock.set_mode (AudioClock::Timecode);
176
177         main_box.pack_start (table, false, false);
178
179         tags_entry.set_editable (true);
180         tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
181         tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
182
183         Label* label = manage (new Label (_("Tags:")));
184         label->set_alignment (0.0f, 0.5f);
185         main_box.pack_start (*label, false, false);
186         main_box.pack_start (tags_entry, true, true);
187
188         main_box.pack_start (bottom_box, false, false);
189
190         play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
191 //      play_btn.set_label (_("Play"));
192
193         stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
194 //      stop_btn.set_label (_("Stop"));
195
196         bottom_box.set_homogeneous (false);
197         bottom_box.set_spacing (6);
198         bottom_box.pack_start(play_btn, true, true);
199         bottom_box.pack_start(stop_btn, true, true);
200         bottom_box.pack_start(autoplay_btn, false, false);
201
202         play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
203         stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
204
205         channels_value.set_alignment (0.0f, 0.5f);
206         samplerate_value.set_alignment (0.0f, 0.5f);
207 }
208
209 void
210 SoundFileBox::set_session(Session* s)
211 {
212         SessionHandlePtr::set_session (s);
213
214         length_clock.set_session (s);
215         timecode_clock.set_session (s);
216
217         if (!_session) {
218                 play_btn.set_sensitive (false);
219                 stop_btn.set_sensitive (false);
220         }
221 }
222
223 bool
224 SoundFileBox::setup_labels (const string& filename)
225 {
226         if (!path.empty()) {
227                 // save existing tags
228                 tags_changed ();
229         }
230
231         path = filename;
232
233         string error_msg;
234
235         if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
236
237                 preview_label.set_markup (_("<b>Sound File Information</b>"));
238                 format_text.set_text ("");
239                 channels_value.set_text ("");
240                 samplerate_value.set_text ("");
241                 tags_entry.get_buffer()->set_text ("");
242
243                 length_clock.set (0);
244                 timecode_clock.set (0);
245
246                 tags_entry.set_sensitive (false);
247                 play_btn.set_sensitive (false);
248
249                 return false;
250         }
251
252         preview_label.set_markup (string_compose ("<b>%1</b>", Glib::path_get_basename (filename)));
253         std::string n = sf_info.format_name;
254         if (n.substr (0, 8) == X_("Format: ")) {
255                 n = n.substr (8);
256         }
257         format_text.set_text (n);
258         channels_value.set_text (to_string (sf_info.channels, std::dec));
259
260         if (_session && sf_info.samplerate != _session->frame_rate()) {
261                 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
262                 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
263                 samplerate_value.set_name ("NewSessionSR1Label");
264                 samplerate.set_name ("NewSessionSR1Label");
265         } else {
266                 samplerate.set_text (_("Sample rate:"));
267                 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
268                 samplerate_value.set_name ("NewSessionSR2Label");
269                 samplerate.set_name ("NewSessionSR2Label");
270         }
271
272         framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
273         double src_coef = (double) nfr / sf_info.samplerate;
274
275         length_clock.set (sf_info.length * src_coef + 0.5, true);
276         timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
277
278         // this is a hack that is fixed in trunk, i think (august 26th, 2007)
279
280         vector<string> tags = Library->get_tags (string ("//") + filename);
281
282         stringstream tag_string;
283         for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
284                 if (i != tags.begin()) {
285                         tag_string << ", ";
286                 }
287                 tag_string << *i;
288         }
289         tags_entry.get_buffer()->set_text (tag_string.str());
290
291         tags_entry.set_sensitive (true);
292         if (_session) {
293                 play_btn.set_sensitive (true);
294         }
295
296         return true;
297 }
298
299 bool
300 SoundFileBox::autoplay() const
301 {
302         return autoplay_btn.get_active();
303 }
304
305 bool
306 SoundFileBox::audition_oneshot()
307 {
308         audition ();
309         return false;
310 }
311
312 void
313 SoundFileBox::audition ()
314 {
315         if (!_session) {
316                 return;
317         }
318
319         if (SMFSource::safe_midi_file_extension (path)) {
320                 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
321                 return;
322         }
323
324         _session->cancel_audition();
325
326         if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
327                 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
328                 return;
329         }
330
331         boost::shared_ptr<Region> r;
332         SourceList srclist;
333         boost::shared_ptr<AudioFileSource> afs;
334         bool old_sbp = AudioSource::get_build_peakfiles ();
335
336         /* don't even think of building peakfiles for these files */
337
338         AudioSource::set_build_peakfiles (false);
339
340         for (int n = 0; n < sf_info.channels; ++n) {
341                 try {
342                         afs = boost::dynamic_pointer_cast<AudioFileSource> (
343                                         SourceFactory::createReadable (DataType::AUDIO, *_session,
344                                                         path, n, Source::Flag (0), false));
345
346                         srclist.push_back(afs);
347
348                 } catch (failed_constructor& err) {
349                         error << _("Could not access soundfile: ") << path << endmsg;
350                         AudioSource::set_build_peakfiles (old_sbp);
351                         return;
352                 }
353         }
354
355         AudioSource::set_build_peakfiles (old_sbp);
356
357         if (srclist.empty()) {
358                 return;
359         }
360
361         afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
362         string rname = region_name_from_path (afs->path(), false);
363
364         PropertyList plist;
365
366         plist.add (ARDOUR::Properties::start, 0);
367         plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
368         plist.add (ARDOUR::Properties::name, rname);
369         plist.add (ARDOUR::Properties::layer, 0);
370
371         r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
372
373         _session->audition_region(r);
374 }
375
376 void
377 SoundFileBox::stop_audition ()
378 {
379         if (_session) {
380                 _session->cancel_audition();
381         }
382 }
383
384 bool
385 SoundFileBox::tags_entry_left (GdkEventFocus *)
386 {
387         tags_changed ();
388         return false;
389 }
390
391 void
392 SoundFileBox::tags_changed ()
393 {
394         string tag_string = tags_entry.get_buffer()->get_text ();
395
396         if (tag_string.empty()) {
397                 return;
398         }
399
400         vector<string> tags;
401
402         if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
403                 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
404                 return;
405         }
406
407         save_tags (tags);
408 }
409
410 void
411 SoundFileBox::save_tags (const vector<string>& tags)
412 {
413         Library->set_tags (string ("//") + path, tags);
414         Library->save_changes ();
415 }
416
417 SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::Session* s, bool persistent)
418         : ArdourDialog (parent, title, false, false),
419           found_list (ListStore::create(found_list_columns)),
420           freesound_list (ListStore::create(freesound_list_columns)),
421           chooser (FILE_CHOOSER_ACTION_OPEN),
422           preview (persistent),
423           found_search_btn (_("Search")),
424           found_list_view (found_list),
425           freesound_search_btn (_("Search")),
426           freesound_list_view (freesound_list)
427 {
428         resetting_ourselves = false;
429         gm = 0;
430
431         resetting_ourselves = false;
432         gm = 0;
433
434 #ifdef GTKOSX
435         chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
436         chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
437         chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
438
439         chooser.add_shortcut_folder_uri("file:///Volumes");
440 #endif
441
442 #ifdef FREESOUND
443         mootcher = new Mootcher();
444 #endif
445
446         //add the file chooser
447         {
448                 chooser.set_border_width (12);
449
450                 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
451                 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
452
453                 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
454                 audio_filter.set_name (_("Audio files"));
455
456                 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
457                 midi_filter.set_name (_("MIDI files"));
458
459                 matchall_filter.add_pattern ("*.*");
460                 matchall_filter.set_name (_("All files"));
461
462                 chooser.add_filter (audio_and_midi_filter);
463                 chooser.add_filter (audio_filter);
464                 chooser.add_filter (midi_filter);
465                 chooser.add_filter (matchall_filter);
466                 chooser.set_select_multiple (true);
467                 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
468                 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
469 #ifdef GTKOSX
470                 /* some broken redraw behaviour - this is a bandaid */
471                 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
472 #endif
473
474                 if (!persistent_folder.empty()) {
475                         chooser.set_current_folder (persistent_folder);
476                 }
477                 notebook.append_page (chooser, _("Browse Files"));
478         }
479
480         hpacker.set_spacing (6);
481         hpacker.pack_start (notebook, true, true);
482         hpacker.pack_start (preview, false, false);
483
484         get_vbox()->pack_start (hpacker, true, true);
485
486         //add tag search
487         {
488                 VBox* vbox;
489                 HBox* hbox;
490
491
492                 hbox = manage(new HBox);
493                 hbox->pack_start (found_entry);
494                 hbox->pack_start (found_search_btn);
495
496                 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
497                 scroll->add(found_list_view);
498                 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
499
500                 vbox = manage(new VBox);
501                 vbox->pack_start (*hbox, PACK_SHRINK);
502                 vbox->pack_start (*scroll);
503
504                 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
505
506                 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
507
508                 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
509
510                 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
511                 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
512
513                 freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
514
515                 notebook.append_page (*vbox, _("Search Tags"));
516         }
517
518         //add freesound search
519 #ifdef FREESOUND
520         {
521                 VBox* vbox;
522                 HBox* passbox;
523                 Label* label;
524
525                 passbox = manage(new HBox);
526                 passbox->set_border_width (12);
527                 passbox->set_spacing (6);
528
529                 label = manage (new Label);
530                 label->set_text (_("Tags:"));
531                 passbox->pack_start (*label, false, false);
532                 passbox->pack_start (freesound_entry, false, false);
533
534                 label = manage (new Label);
535                 label->set_text (_("Sort:"));
536                 passbox->pack_start (*label, false, false);
537                 passbox->pack_start (freesound_sort, false, false);
538                 freesound_sort.clear_items();
539                 
540                 // Order of the following must correspond with enum sortMethod
541                 // in sfdb_freesound_mootcher.h 
542                 freesound_sort.append_text(_("None"));
543                 freesound_sort.append_text(_("Longest"));
544                 freesound_sort.append_text(_("Shortest"));
545                 freesound_sort.append_text(_("Newest"));
546                 freesound_sort.append_text(_("Oldest"));
547                 freesound_sort.append_text(_("Most downloaded"));
548                 freesound_sort.append_text(_("Least downloaded"));
549                 freesound_sort.append_text(_("Highest rated"));
550                 freesound_sort.append_text(_("Lowest rated"));
551                 freesound_sort.set_active(0);
552
553                 passbox->pack_start (freesound_search_btn, false, false);
554                 passbox->pack_start (freesound_progress_bar);
555                 passbox->pack_end   (freesound_stop_btn, false, false);
556                 freesound_stop_btn.set_label(_("Stop"));
557                 
558                 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
559                 scroll->add(freesound_list_view);
560                 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
561
562                 vbox = manage(new VBox);
563                 vbox->pack_start (*passbox, PACK_SHRINK);
564                 vbox->pack_start (*scroll);
565
566                 freesound_list_view.append_column(_("ID")      , freesound_list_columns.id);
567                 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
568                 // freesound_list_view.append_column(_("URI")     , freesound_list_columns.uri);
569                 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
570                 freesound_list_view.get_column(1)->set_expand(true);
571
572                 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
573
574                 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
575                 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
576                 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
577                 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
578                 freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
579                 notebook.append_page (*vbox, _("Search Freesound"));
580         }
581
582 #endif
583
584
585         notebook.set_size_request (500, -1);
586
587         set_session (s);
588
589         add_button (Stock::CANCEL, RESPONSE_CANCEL);
590         add_button (Stock::APPLY, RESPONSE_APPLY);
591         add_button (Stock::OK, RESPONSE_OK);
592
593 }
594
595 SoundFileBrowser::~SoundFileBrowser ()
596 {
597         persistent_folder = chooser.get_current_folder();
598 }
599
600
601 void
602 SoundFileBrowser::on_show ()
603 {
604         ArdourDialog::on_show ();
605         start_metering ();
606 }
607
608 void
609 SoundFileBrowser::clear_selection ()
610 {
611         chooser.unselect_all ();
612         found_list_view.get_selection()->unselect_all ();
613 }
614
615 void
616 SoundFileBrowser::chooser_file_activated ()
617 {
618         preview.audition ();
619 }
620
621 void
622 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
623 {
624         preview.audition ();
625 }
626
627 void
628 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
629 {
630         preview.audition ();
631 }
632
633 void
634 SoundFileBrowser::set_session (Session* s)
635 {
636         ArdourDialog::set_session (s);
637         preview.set_session (s);
638
639         if (_session) {
640                 add_gain_meter ();
641         } else {
642                 remove_gain_meter ();
643         }
644 }
645
646 void
647 SoundFileBrowser::add_gain_meter ()
648 {
649         delete gm;
650
651         gm = new GainMeter (_session, 250);
652
653         boost::shared_ptr<Route> r = _session->the_auditioner ();
654
655         gm->set_controls (r, r->shared_peak_meter(), r->amp());
656
657         meter_packer.set_border_width (12);
658         meter_packer.pack_start (*gm, false, true);
659         hpacker.pack_end (meter_packer, false, false);
660         meter_packer.show_all ();
661         start_metering ();
662 }
663
664 void
665 SoundFileBrowser::remove_gain_meter ()
666 {
667         if (gm) {
668                 meter_packer.remove (*gm);
669                 hpacker.remove (meter_packer);
670                 delete gm;
671                 gm = 0;
672         }
673 }
674
675 void
676 SoundFileBrowser::start_metering ()
677 {
678         metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
679 }
680
681 void
682 SoundFileBrowser::stop_metering ()
683 {
684         metering_connection.disconnect();
685 }
686
687 void
688 SoundFileBrowser::meter ()
689 {
690         if (is_mapped () && _session && gm) {
691                 gm->update_meters ();
692         }
693 }
694
695 bool
696 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
697 {
698         return AudioFileSource::safe_audio_file_extension (filter_info.filename);
699 }
700
701 bool
702 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
703 {
704         return SMFSource::safe_midi_file_extension (filter_info.filename);
705 }
706
707 bool
708 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
709 {
710         return on_audio_filter (filter_info) || on_midi_filter (filter_info);
711 }
712
713 void
714 SoundFileBrowser::update_preview ()
715 {
716         if (preview.setup_labels (chooser.get_filename())) {
717                 if (preview.autoplay()) {
718                         Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
719                 }
720         }
721 }
722
723 void
724 SoundFileBrowser::found_list_view_selected ()
725 {
726         if (!reset_options ()) {
727                 set_response_sensitive (RESPONSE_OK, false);
728         } else {
729                 string file;
730
731                 TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
732
733                 if (!rows.empty()) {
734                         TreeIter iter = found_list->get_iter(*rows.begin());
735                         file = (*iter)[found_list_columns.pathname];
736                         chooser.set_filename (file);
737                         set_response_sensitive (RESPONSE_OK, true);
738                 } else {
739                         set_response_sensitive (RESPONSE_OK, false);
740                 }
741
742                 preview.setup_labels (file);
743         }
744 }
745
746 void
747 SoundFileBrowser::freesound_list_view_selected ()
748 {
749         freesound_download_cancel = false;
750
751 #ifdef FREESOUND
752         if (!reset_options ()) {
753                 set_response_sensitive (RESPONSE_OK, false);
754         } else {
755
756                 string file;
757
758                 TreeView::Selection::ListHandle_Path rows = freesound_list_view.get_selection()->get_selected_rows ();
759
760                 if (!rows.empty()) {
761                         TreeIter iter = freesound_list->get_iter(*rows.begin());
762
763                         string id  = (*iter)[freesound_list_columns.id];
764                         string uri = (*iter)[freesound_list_columns.uri];
765                         string ofn = (*iter)[freesound_list_columns.filename];
766
767                         // download the sound file                      
768                         GdkCursor *prev_cursor;
769                         prev_cursor = gdk_window_get_cursor (get_window()->gobj());
770                         gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
771                         gdk_flush();
772
773                         file = mootcher->getAudioFile(ofn, id, uri, this);
774
775                         gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
776
777                         if (file != "") {
778                                 chooser.set_filename (file);
779                                 set_response_sensitive (RESPONSE_OK, true);
780                         }
781                 } else {
782                         set_response_sensitive (RESPONSE_OK, false);
783                 }
784
785                 preview.setup_labels (file);
786         }
787 #endif
788 }
789
790 void
791 SoundFileBrowser::found_search_clicked ()
792 {
793         string tag_string = found_entry.get_text ();
794
795         vector<string> tags;
796
797         if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
798                 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
799                 return;
800         }
801
802         vector<string> results;
803         Library->search_members_and (results, tags);
804
805         found_list->clear();
806         for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
807                 TreeModel::iterator new_row = found_list->append();
808                 TreeModel::Row row = *new_row;
809                 string path = Glib::filename_from_uri (string ("file:") + *i);
810                 row[found_list_columns.pathname] = path;
811         }
812 }
813
814 void
815 SoundFileBrowser::freesound_search_clicked ()
816 {
817         freesound_search_cancel = false;
818         freesound_search();
819 }
820
821 void
822 SoundFileBrowser::freesound_stop_clicked ()
823 {
824         freesound_download_cancel = true;
825         freesound_search_cancel = true;
826 }
827
828
829 void
830 SoundFileBrowser::freesound_search()
831 {
832 #ifdef FREESOUND
833         freesound_list->clear();
834
835         string search_string = freesound_entry.get_text ();
836         enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
837
838         GdkCursor *prev_cursor;
839         prev_cursor = gdk_window_get_cursor (get_window()->gobj());
840         gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
841         gdk_flush();
842         for (int page = 1; page <= 99; page++ ) {
843                 
844                 std::string prog;
845                 prog = string_compose (_("Page %1, [Stop]->"), page);
846                 freesound_progress_bar.set_text(prog);
847                 while (Glib::MainContext::get_default()->iteration (false)) {
848                         /* do nothing */
849                 }
850
851                 std::string theString = mootcher->searchText(
852                         search_string, 
853                         page,
854                         "", // filter, could do, e.g. "type:wav"
855                         sort_method
856                 );
857
858                 XMLTree doc;
859                 doc.read_buffer( theString );
860                 XMLNode *root = doc.root();
861
862                 if (!root) {
863                         cerr << "no root XML node!" << endl;
864                         break;
865                 }
866
867                 if ( strcmp(root->name().c_str(), "response") != 0) {
868                         cerr << "root node name == " << root->name() << ", != \"response\"!" << endl;
869                         break;
870                 }
871
872                 XMLNode *sounds_root = root->child("sounds");
873                 
874                 if (!sounds_root) {
875                         cerr << "no child node \"sounds\" found!" << endl;
876                         break;
877                 }
878                 
879                 XMLNodeList sounds = sounds_root->children();
880                 XMLNodeConstIterator niter;
881                 XMLNode *node;
882                 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
883                         node = *niter;
884                         if( strcmp( node->name().c_str(), "resource") != 0 ){
885                                 cerr << "node->name()=" << node->name() << ",!= \"resource\"!" << endl;
886                                 freesound_search_cancel = true;
887                                 break;
888                         }
889
890                         // node->dump(cerr, "node:");
891                         
892                         XMLNode *id_node  = node->child ("id");
893                         XMLNode *uri_node = node->child ("serve");
894                         XMLNode *ofn_node = node->child ("original_filename");
895                         XMLNode *dur_node = node->child ("duration");
896
897                         if (id_node && uri_node && ofn_node && dur_node) {
898                                 
899                                 std::string  id =  id_node->child("text")->content();
900                                 std::string uri = uri_node->child("text")->content();
901                                 std::string ofn = ofn_node->child("text")->content();
902                                 std::string dur = dur_node->child("text")->content();
903
904                                 std::string r;
905                                 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
906                                 
907                                 double duration_seconds = atof(dur.c_str());
908                                 double h, m, s;
909                                 char duration_hhmmss[16];
910                                 if (duration_seconds >= 99 * 60 * 60) {
911                                         strcpy(duration_hhmmss, ">99h");
912                                 } else {
913                                         s = modf(duration_seconds/60, &m) * 60;
914                                         m = modf(m/60, &h) * 60;
915                                         sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
916                                                 h, m, s
917                                         );
918                                 }
919
920                                 TreeModel::iterator new_row = freesound_list->append();
921                                 TreeModel::Row row = *new_row;
922                                 
923                                 row[freesound_list_columns.id      ] = id;
924                                 row[freesound_list_columns.uri     ] = uri;
925                                 row[freesound_list_columns.filename] = ofn;
926                                 row[freesound_list_columns.duration] = duration_hhmmss;
927
928                         }
929                 }
930         
931                 if (freesound_search_cancel)
932                         break;
933
934         }  //page "for" loop
935
936         gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
937
938         freesound_progress_bar.set_text("");
939
940 #endif
941 }
942
943 vector<string>
944 SoundFileBrowser::get_paths ()
945 {
946         vector<string> results;
947
948         int n = notebook.get_current_page ();
949
950         if (n == 0) {
951                 vector<string> filenames = chooser.get_filenames();
952                 vector<string>::iterator i;
953
954                 for (i = filenames.begin(); i != filenames.end(); ++i) {
955                         struct stat buf;
956                         if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
957                                 results.push_back (*i);
958                         }
959                 }
960
961         } else if (n==1){
962
963                 typedef TreeView::Selection::ListHandle_Path ListPath;
964
965                 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
966                 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
967                         TreeIter iter = found_list->get_iter(*i);
968                         string str = (*iter)[found_list_columns.pathname];
969
970                         results.push_back (str);
971                 }
972         } else {
973 #ifdef FREESOUND
974                 typedef TreeView::Selection::ListHandle_Path ListPath;
975
976                 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
977                 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
978                         TreeIter iter = freesound_list->get_iter(*i);
979                         string id  = (*iter)[freesound_list_columns.id];
980                         string uri = (*iter)[freesound_list_columns.uri];
981                         string ofn = (*iter)[freesound_list_columns.filename];
982
983                         GdkCursor *prev_cursor;
984                         prev_cursor = gdk_window_get_cursor (get_window()->gobj());
985                         gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
986                         gdk_flush();
987
988                         string str = mootcher->getAudioFile(ofn, id, uri, this);
989                         if (str != "") {
990                                 results.push_back (str);
991                         }
992                         
993                         gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
994
995                 }
996 #endif
997         }
998
999         return results;
1000 }
1001
1002 void
1003 SoundFileOmega::reset_options_noret ()
1004 {
1005         if (!resetting_ourselves) {
1006                 (void) reset_options ();
1007         }
1008 }
1009
1010 bool
1011 SoundFileOmega::reset_options ()
1012 {
1013         vector<string> paths = get_paths ();
1014
1015         if (paths.empty()) {
1016
1017                 channel_combo.set_sensitive (false);
1018                 action_combo.set_sensitive (false);
1019                 where_combo.set_sensitive (false);
1020                 copy_files_btn.set_sensitive (false);
1021
1022                 return false;
1023
1024         } else {
1025
1026                 channel_combo.set_sensitive (true);
1027                 action_combo.set_sensitive (true);
1028                 where_combo.set_sensitive (true);
1029
1030                 /* if we get through this function successfully, this may be
1031                    reset at the end, once we know if we can use hard links
1032                    to do embedding
1033                 */
1034
1035                 if (Config->get_only_copy_imported_files()) {
1036                         copy_files_btn.set_sensitive (false);
1037                 } else {
1038                         copy_files_btn.set_sensitive (false);
1039                 }
1040         }
1041
1042         bool same_size;
1043         bool src_needed;
1044         bool selection_includes_multichannel;
1045         bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1046         ImportMode mode;
1047
1048         if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1049                 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1050                 return false;
1051         }
1052
1053         string existing_choice;
1054         vector<string> action_strings;
1055
1056         if (chooser.get_filter() == &audio_filter) {
1057
1058                 /* AUDIO */
1059
1060                 if (selected_audio_track_cnt > 0) {
1061                         if (channel_combo.get_active_text().length()) {
1062                                 ImportDisposition id = get_channel_disposition();
1063                                 
1064                                 switch (id) {
1065                                 case Editing::ImportDistinctFiles:
1066                                         if (selected_audio_track_cnt == paths.size()) {
1067                                                 action_strings.push_back (importmode2string (ImportToTrack));
1068                                         }
1069                                         break;
1070                                         
1071                                 case Editing::ImportDistinctChannels:
1072                                         /* XXX it would be nice to allow channel-per-selected track
1073                                            but its too hard we don't want to deal with all the
1074                                            different per-file + per-track channel configurations.
1075                                         */
1076                                         break;
1077                                         
1078                                 default:
1079                                         action_strings.push_back (importmode2string (ImportToTrack));
1080                                         break;
1081                                 }
1082                         }
1083                 }
1084
1085         }  else {
1086
1087                 /* MIDI */
1088
1089                 if (selected_midi_track_cnt > 0) {
1090                         action_strings.push_back (importmode2string (ImportToTrack));
1091                 }
1092         }
1093
1094         action_strings.push_back (importmode2string (ImportAsTrack));
1095         action_strings.push_back (importmode2string (ImportAsRegion));
1096         action_strings.push_back (importmode2string (ImportAsTapeTrack));
1097
1098         resetting_ourselves = true;
1099
1100         existing_choice = action_combo.get_active_text();
1101
1102         set_popdown_strings (action_combo, action_strings);
1103
1104         /* preserve any existing choice, if possible */
1105
1106
1107         if (existing_choice.length()) {
1108                 vector<string>::iterator x;
1109                 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1110                         if (*x == existing_choice) {
1111                                 action_combo.set_active_text (existing_choice);
1112                                 break;
1113                         }
1114                 }
1115                 if (x == action_strings.end()) {
1116                         action_combo.set_active_text (action_strings.front());
1117                 }
1118         } else {
1119                 action_combo.set_active_text (action_strings.front());
1120         }
1121
1122         resetting_ourselves = false;
1123
1124         if ((mode = get_mode()) == ImportAsRegion) {
1125                 where_combo.set_sensitive (false);
1126         } else {
1127                 where_combo.set_sensitive (true);
1128         }
1129
1130         vector<string> channel_strings;
1131
1132         if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1133                 channel_strings.push_back (_("one track per file"));
1134
1135                 if (selection_includes_multichannel) {
1136                         channel_strings.push_back (_("one track per channel"));
1137                 }
1138
1139                 if (paths.size() > 1) {
1140                         /* tape tracks are a single region per track, so we cannot
1141                            sequence multiple files.
1142                         */
1143                         if (mode != ImportAsTapeTrack) {
1144                                 channel_strings.push_back (_("sequence files"));
1145                         }
1146                         if (same_size) {
1147                                 channel_strings.push_back (_("all files in one track"));
1148                                 channel_strings.push_back (_("merge files"));
1149                         }
1150
1151                 }
1152
1153         } else {
1154                 channel_strings.push_back (_("one region per file"));
1155
1156                 if (selection_includes_multichannel) {
1157                         channel_strings.push_back (_("one region per channel"));
1158                 }
1159
1160                 if (paths.size() > 1) {
1161                         if (same_size) {
1162                                 channel_strings.push_back (_("all files in one region"));
1163                         }
1164                 }
1165         }
1166
1167         resetting_ourselves = true;
1168
1169         existing_choice = channel_combo.get_active_text();
1170
1171         set_popdown_strings (channel_combo, channel_strings);
1172
1173         /* preserve any existing choice, if possible */
1174
1175         if (existing_choice.length()) {
1176                 vector<string>::iterator x;
1177                 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1178                         if (*x == existing_choice) {
1179                                 channel_combo.set_active_text (existing_choice);
1180                                 break;
1181                         }
1182                 }
1183                 if (x == channel_strings.end()) {
1184                         channel_combo.set_active_text (channel_strings.front());
1185                 }
1186         } else {
1187                 channel_combo.set_active_text (channel_strings.front());
1188         }
1189
1190         resetting_ourselves = false;
1191
1192         if (src_needed) {
1193                 src_combo.set_sensitive (true);
1194         } else {
1195                 src_combo.set_sensitive (false);
1196         }
1197
1198         if (Config->get_only_copy_imported_files()) {
1199
1200                 if (selection_can_be_embedded_with_links) {
1201                         copy_files_btn.set_sensitive (true);
1202                 } else {
1203                         copy_files_btn.set_sensitive (false);
1204                 }
1205
1206         }  else {
1207
1208                 copy_files_btn.set_sensitive (true);
1209         }
1210
1211         return true;
1212 }
1213
1214
1215 bool
1216 SoundFileOmega::bad_file_message()
1217 {
1218         MessageDialog msg (*this,
1219                            string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1220                            true,
1221                            Gtk::MESSAGE_INFO,
1222                            Gtk::BUTTONS_OK);
1223         msg.run ();
1224         resetting_ourselves = true;
1225         chooser.unselect_uri (chooser.get_preview_uri());
1226         resetting_ourselves = false;
1227
1228         return false;
1229 }
1230
1231 bool
1232 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1233 {
1234         SoundFileInfo info;
1235         framepos_t sz = 0;
1236         bool err = false;
1237         string errmsg;
1238
1239         same_size = true;
1240         src_needed = false;
1241         multichannel = false;
1242
1243         for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1244
1245                 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1246                         if (info.channels > 1) {
1247                                 multichannel = true;
1248                         }
1249                         if (sz == 0) {
1250                                 sz = info.length;
1251                         } else {
1252                                 if (sz != info.length) {
1253                                         same_size = false;
1254                                 }
1255                         }
1256
1257                         if (info.samplerate != _session->frame_rate()) {
1258                                 src_needed = true;
1259                         }
1260
1261                 } else if (SMFSource::safe_midi_file_extension (*i)) {
1262
1263                         Evoral::SMF reader;
1264                         reader.open(*i);
1265                         if (reader.num_tracks() > 1) {
1266                                 multichannel = true; // "channel" == track here...
1267                         }
1268
1269                         /* XXX we need err = true handling here in case
1270                            we can't check the file
1271                         */
1272
1273                 } else {
1274                         err = true;
1275                 }
1276         }
1277
1278         return err;
1279 }
1280
1281
1282 bool
1283 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1284 {
1285         sys::path path = s->session_directory().sound_path() / "linktest";
1286         string tmpdir = path.to_string();
1287         bool ret = false;
1288
1289         if (mkdir (tmpdir.c_str(), 0744)) {
1290                 if (errno != EEXIST) {
1291                         return false;
1292                 }
1293         }
1294
1295         for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1296
1297                 char tmpc[MAXPATHLEN+1];
1298
1299                 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1300
1301                 /* can we link ? */
1302
1303                 if (link ((*i).c_str(), tmpc)) {
1304                         goto out;
1305                 }
1306
1307                 unlink (tmpc);
1308         }
1309
1310         ret = true;
1311
1312   out:
1313         rmdir (tmpdir.c_str());
1314         return ret;
1315 }
1316
1317 SoundFileChooser::SoundFileChooser (Gtk::Window& parent, string title, ARDOUR::Session* s)
1318         : SoundFileBrowser (parent, title, s, false)
1319 {
1320         chooser.set_select_multiple (false);
1321         found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1322         freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1323 }
1324
1325 void
1326 SoundFileChooser::on_hide ()
1327 {
1328         ArdourDialog::on_hide();
1329         stop_metering ();
1330
1331         if (_session) {
1332                 _session->cancel_audition();
1333         }
1334 }
1335
1336 string
1337 SoundFileChooser::get_filename ()
1338 {
1339         vector<string> paths;
1340
1341         paths = get_paths ();
1342
1343         if (paths.empty()) {
1344                 return string ();
1345         }
1346
1347         if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1348                 return string();
1349         }
1350
1351         return paths.front();
1352 }
1353
1354 SoundFileOmega::SoundFileOmega (Gtk::Window& parent, string title, ARDOUR::Session* s, 
1355                                 uint32_t selected_audio_tracks, 
1356                                 uint32_t selected_midi_tracks, 
1357                                 bool persistent,
1358                                 Editing::ImportMode mode_hint)
1359         : SoundFileBrowser (parent, title, s, persistent)
1360         , copy_files_btn ( _("Copy files to session"))
1361         , selected_audio_track_cnt (selected_audio_tracks)
1362         , selected_midi_track_cnt (selected_midi_tracks)
1363 {
1364         VBox* vbox;
1365         HBox* hbox;
1366         vector<string> str;
1367
1368         set_size_request (-1, 450);
1369
1370         block_two.set_border_width (12);
1371         block_three.set_border_width (12);
1372         block_four.set_border_width (12);
1373
1374         options.set_spacing (12);
1375
1376         str.clear ();
1377         str.push_back (_("file timestamp"));
1378         str.push_back (_("edit point"));
1379         str.push_back (_("playhead"));
1380         str.push_back (_("session start"));
1381         set_popdown_strings (where_combo, str);
1382         where_combo.set_active_text (str.front());
1383
1384         Label* l = manage (new Label);
1385         l->set_text (_("Add files:"));
1386
1387         hbox = manage (new HBox);
1388         hbox->set_border_width (12);
1389         hbox->set_spacing (6);
1390         hbox->pack_start (*l, false, false);
1391         hbox->pack_start (action_combo, false, false);
1392         vbox = manage (new VBox);
1393         vbox->pack_start (*hbox, false, false);
1394         options.pack_start (*vbox, false, false);
1395
1396         /* dummy entry for action combo so that it doesn't look odd if we
1397            come up with no tracks selected.
1398         */
1399
1400         str.clear ();
1401         str.push_back (importmode2string (mode_hint));
1402         set_popdown_strings (action_combo, str);
1403         action_combo.set_active_text (str.front());
1404         action_combo.set_sensitive (false);
1405
1406         l = manage (new Label);
1407         l->set_text (_("Insert at:"));
1408
1409         hbox = manage (new HBox);
1410         hbox->set_border_width (12);
1411         hbox->set_spacing (6);
1412         hbox->pack_start (*l, false, false);
1413         hbox->pack_start (where_combo, false, false);
1414         vbox = manage (new VBox);
1415         vbox->pack_start (*hbox, false, false);
1416         options.pack_start (*vbox, false, false);
1417
1418
1419         l = manage (new Label);
1420         l->set_text (_("Mapping:"));
1421
1422         hbox = manage (new HBox);
1423         hbox->set_border_width (12);
1424         hbox->set_spacing (6);
1425         hbox->pack_start (*l, false, false);
1426         hbox->pack_start (channel_combo, false, false);
1427         vbox = manage (new VBox);
1428         vbox->pack_start (*hbox, false, false);
1429         options.pack_start (*vbox, false, false);
1430
1431         str.clear ();
1432         str.push_back (_("one track per file"));
1433         set_popdown_strings (channel_combo, str);
1434         channel_combo.set_active_text (str.front());
1435         channel_combo.set_sensitive (false);
1436
1437         l = manage (new Label);
1438         l->set_text (_("Conversion quality:"));
1439
1440         hbox = manage (new HBox);
1441         hbox->set_border_width (12);
1442         hbox->set_spacing (6);
1443         hbox->pack_start (*l, false, false);
1444         hbox->pack_start (src_combo, false, false);
1445         vbox = manage (new VBox);
1446         vbox->pack_start (*hbox, false, false);
1447         options.pack_start (*vbox, false, false);
1448
1449         str.clear ();
1450         str.push_back (_("Best"));
1451         str.push_back (_("Good"));
1452         str.push_back (_("Quick"));
1453         str.push_back (_("Fast"));
1454         str.push_back (_("Fastest"));
1455
1456         set_popdown_strings (src_combo, str);
1457         src_combo.set_active_text (str.front());
1458         src_combo.set_sensitive (false);
1459
1460         reset_options ();
1461
1462         action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1463         channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1464
1465         copy_files_btn.set_active (true);
1466
1467         block_four.pack_start (copy_files_btn, false, false);
1468
1469         options.pack_start (block_four, false, false);
1470
1471         get_vbox()->pack_start (options, false, false);
1472
1473         /* setup disposition map */
1474
1475         disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1476         disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1477         disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1478         disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1479
1480         disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1481         disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1482         disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1483         disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1484
1485         chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1486
1487         /* set size requests for a couple of combos to allow them to display the longest text
1488            they will ever be asked to display.  This prevents them being resized when the user
1489            selects a file to import, which in turn prevents the size of the dialog from jumping
1490            around. */
1491
1492         vector<string> t;
1493         t.push_back (_("one track per file"));
1494         t.push_back (_("one track per channel"));
1495         t.push_back (_("sequence files"));
1496         t.push_back (_("all files in one region"));
1497         set_popdown_strings (channel_combo, t);
1498
1499         t.clear ();
1500         t.push_back (importmode2string (ImportAsTrack));
1501         t.push_back (importmode2string (ImportToTrack));
1502         t.push_back (importmode2string (ImportAsRegion));
1503         t.push_back (importmode2string (ImportAsTapeTrack));
1504         set_popdown_strings (action_combo, t);
1505 }
1506
1507 void
1508 SoundFileOmega::set_mode (ImportMode mode)
1509 {
1510         action_combo.set_active_text (importmode2string (mode));
1511 }
1512
1513 ImportMode
1514 SoundFileOmega::get_mode () const
1515 {
1516         return string2importmode (action_combo.get_active_text());
1517 }
1518
1519 void
1520 SoundFileOmega::on_hide ()
1521 {
1522         ArdourDialog::on_hide();
1523         if (_session) {
1524                 _session->cancel_audition();
1525         }
1526 }
1527
1528 ImportPosition
1529 SoundFileOmega::get_position() const
1530 {
1531         string str = where_combo.get_active_text();
1532
1533         if (str == _("file timestamp")) {
1534                 return ImportAtTimestamp;
1535         } else if (str == _("edit point")) {
1536                 return ImportAtEditPoint;
1537         } else if (str == _("playhead")) {
1538                 return ImportAtPlayhead;
1539         } else {
1540                 return ImportAtStart;
1541         }
1542 }
1543
1544 SrcQuality
1545 SoundFileOmega::get_src_quality() const
1546 {
1547         string str = where_combo.get_active_text();
1548
1549         if (str == _("Best")) {
1550                 return SrcBest;
1551         } else if (str == _("Good")) {
1552                 return SrcGood;
1553         } else if (str == _("Quick")) {
1554                 return SrcQuick;
1555         } else if (str == _("Fast")) {
1556                 return SrcFast;
1557         } else {
1558                 return SrcFastest;
1559         }
1560 }
1561
1562 ImportDisposition
1563 SoundFileOmega::get_channel_disposition () const
1564 {
1565         /* we use a map here because the channel combo can contain different strings
1566            depending on the state of the other combos. the map contains all possible strings
1567            and the ImportDisposition enum that corresponds to it.
1568         */
1569
1570         string str = channel_combo.get_active_text();
1571         DispositionMap::const_iterator x = disposition_map.find (str);
1572
1573         if (x == disposition_map.end()) {
1574                 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1575                 /*NOTREACHED*/
1576         }
1577
1578         return x->second;
1579 }
1580
1581 void
1582 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1583 {
1584         selected_audio_track_cnt = selected_audio_tracks;
1585         selected_midi_track_cnt = selected_midi_tracks;
1586         reset_options ();
1587 }
1588
1589 void
1590 SoundFileOmega::file_selection_changed ()
1591 {
1592         if (resetting_ourselves) {
1593                 return;
1594         }
1595
1596         if (!reset_options ()) {
1597                 set_response_sensitive (RESPONSE_OK, false);
1598         } else {
1599                 if (chooser.get_filenames().size() > 0) {
1600                         set_response_sensitive (RESPONSE_OK, true);
1601                 } else {
1602                         set_response_sensitive (RESPONSE_OK, false);
1603                 }
1604         }
1605 }
1606