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