2 Copyright (C) 2005-2006 Paul Davis
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.
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.
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.
21 #include "gtk2ardour-config.h"
30 #include <sys/param.h>
32 #include <gtkmm/box.h>
33 #include <gtkmm/stock.h>
35 #include <glib/gstdio.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/convert.h"
39 #include "pbd/tokenizer.h"
40 #include "pbd/enumwriter.h"
41 #include "pbd/pthread_utils.h"
42 #include "pbd/xml++.h"
44 #include <gtkmm2ext/utils.h>
46 #include "evoral/SMF.hpp"
48 #include "ardour/audio_library.h"
49 #include "ardour/auditioner.h"
50 #include "ardour/audioregion.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/smf_source.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/source_factory.h"
55 #include "ardour/session.h"
56 #include "ardour/session_directory.h"
58 #include "ardour_ui.h"
60 #include "gui_thread.h"
65 #include "gain_meter.h"
66 #include "main_clock.h"
67 #include "public_editor.h"
70 #include "sfdb_freesound_mootcher.h"
75 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
80 using namespace Editing;
84 string SoundFileBrowser::persistent_folder;
85 typedef TreeView::Selection::ListHandle_Path ListPath;
88 string2importmode (string str)
90 if (str == _("as new tracks")) {
92 } else if (str == _("to selected tracks")) {
94 } else if (str == _("to region list")) {
95 return ImportAsRegion;
96 } else if (str == _("as new tape tracks")) {
97 return ImportAsTapeTrack;
100 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
102 return ImportAsTrack;
106 importmode2string (ImportMode mode)
110 return _("as new tracks");
112 return _("to selected tracks");
114 return _("to region list");
115 case ImportAsTapeTrack:
116 return _("as new tape tracks");
119 return _("as new tracks");
122 SoundFileBox::SoundFileBox (bool persistent)
124 length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
125 timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
127 autoplay_btn (_("Auto-play"))
130 set_name (X_("SoundFileBox"));
131 set_size_request (300, -1);
133 preview_label.set_markup (_("<b>Sound File Information</b>"));
135 border_frame.set_label_widget (preview_label);
136 border_frame.add (main_box);
138 pack_start (border_frame, true, true);
139 set_border_width (6);
141 main_box.set_border_width (6);
143 length.set_text (_("Length:"));
144 length.set_alignment (1, 0.5);
145 timecode.set_text (_("Timestamp:"));
146 timecode.set_alignment (1, 0.5);
147 format.set_text (_("Format:"));
148 format.set_alignment (1, 0.5);
149 channels.set_text (_("Channels:"));
150 channels.set_alignment (1, 0.5);
151 samplerate.set_text (_("Sample rate:"));
152 samplerate.set_alignment (1, 0.5);
154 preview_label.set_max_width_chars (50);
155 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
157 format_text.set_max_width_chars (20);
158 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
159 format_text.set_alignment (0, 1);
161 table.set_col_spacings (6);
162 table.set_homogeneous (false);
163 table.set_row_spacings (6);
165 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
166 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
167 table.attach (format, 0, 1, 2, 4, FILL, FILL);
168 table.attach (length, 0, 1, 4, 5, FILL, FILL);
169 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
171 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
172 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
173 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
174 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
175 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
177 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
178 timecode_clock.set_mode (AudioClock::Timecode);
180 main_box.pack_start (table, false, false);
182 tags_entry.set_editable (true);
183 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
184 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
186 Label* label = manage (new Label (_("Tags:")));
187 label->set_alignment (0.0f, 0.5f);
188 main_box.pack_start (*label, false, false);
189 main_box.pack_start (tags_entry, true, true);
191 main_box.pack_start (bottom_box, false, false);
193 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
194 // play_btn.set_label (_("Play"));
196 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
197 // stop_btn.set_label (_("Stop"));
199 bottom_box.set_homogeneous (false);
200 bottom_box.set_spacing (6);
201 bottom_box.pack_start(play_btn, true, true);
202 bottom_box.pack_start(stop_btn, true, true);
203 bottom_box.pack_start(autoplay_btn, false, false);
205 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
206 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
208 channels_value.set_alignment (0.0f, 0.5f);
209 samplerate_value.set_alignment (0.0f, 0.5f);
213 SoundFileBox::set_session(Session* s)
215 SessionHandlePtr::set_session (s);
217 length_clock.set_session (s);
218 timecode_clock.set_session (s);
221 play_btn.set_sensitive (false);
222 stop_btn.set_sensitive (false);
227 SoundFileBox::setup_labels (const string& filename)
230 // save existing tags
238 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
240 preview_label.set_markup (_("<b>Sound File Information</b>"));
241 format_text.set_text ("");
242 channels_value.set_text ("");
243 samplerate_value.set_text ("");
244 tags_entry.get_buffer()->set_text ("");
246 length_clock.set (0);
247 timecode_clock.set (0);
249 tags_entry.set_sensitive (false);
250 play_btn.set_sensitive (false);
255 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
256 std::string n = sf_info.format_name;
257 if (n.substr (0, 8) == X_("Format: ")) {
260 format_text.set_text (n);
261 channels_value.set_text (to_string (sf_info.channels, std::dec));
263 if (_session && sf_info.samplerate != _session->frame_rate()) {
264 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
265 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
266 samplerate_value.set_name ("NewSessionSR1Label");
267 samplerate.set_name ("NewSessionSR1Label");
269 samplerate.set_text (_("Sample rate:"));
270 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
271 samplerate_value.set_name ("NewSessionSR2Label");
272 samplerate.set_name ("NewSessionSR2Label");
275 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
276 double src_coef = (double) nfr / sf_info.samplerate;
278 length_clock.set (sf_info.length * src_coef + 0.5, true);
279 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
281 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
283 vector<string> tags = Library->get_tags (string ("//") + filename);
285 stringstream tag_string;
286 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
287 if (i != tags.begin()) {
292 tags_entry.get_buffer()->set_text (tag_string.str());
294 tags_entry.set_sensitive (true);
296 play_btn.set_sensitive (true);
303 SoundFileBox::autoplay() const
305 return autoplay_btn.get_active();
309 SoundFileBox::audition_oneshot()
316 SoundFileBox::audition ()
322 if (SMFSource::safe_midi_file_extension (path)) {
323 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
327 _session->cancel_audition();
329 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
330 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
334 boost::shared_ptr<Region> r;
336 boost::shared_ptr<AudioFileSource> afs;
337 bool old_sbp = AudioSource::get_build_peakfiles ();
339 /* don't even think of building peakfiles for these files */
341 AudioSource::set_build_peakfiles (false);
343 for (int n = 0; n < sf_info.channels; ++n) {
345 afs = boost::dynamic_pointer_cast<AudioFileSource> (
346 SourceFactory::createExternal (DataType::AUDIO, *_session,
348 Source::Flag (0), false));
350 srclist.push_back(afs);
352 } catch (failed_constructor& err) {
353 error << _("Could not access soundfile: ") << path << endmsg;
354 AudioSource::set_build_peakfiles (old_sbp);
359 AudioSource::set_build_peakfiles (old_sbp);
361 if (srclist.empty()) {
365 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
366 string rname = region_name_from_path (afs->path(), false);
370 plist.add (ARDOUR::Properties::start, 0);
371 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
372 plist.add (ARDOUR::Properties::name, rname);
373 plist.add (ARDOUR::Properties::layer, 0);
375 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
377 _session->audition_region(r);
381 SoundFileBox::stop_audition ()
384 _session->cancel_audition();
389 SoundFileBox::tags_entry_left (GdkEventFocus *)
396 SoundFileBox::tags_changed ()
398 string tag_string = tags_entry.get_buffer()->get_text ();
400 if (tag_string.empty()) {
406 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
407 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
415 SoundFileBox::save_tags (const vector<string>& tags)
417 Library->set_tags (string ("//") + path, tags);
418 Library->save_changes ();
421 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
422 : ArdourWindow (title)
423 , found_list (ListStore::create(found_list_columns))
424 , freesound_list (ListStore::create(freesound_list_columns))
425 , chooser (FILE_CHOOSER_ACTION_OPEN)
426 , preview (persistent)
427 , found_search_btn (_("Search"))
428 , found_list_view (found_list)
429 , freesound_search_btn (_("Search"))
430 , freesound_list_view (freesound_list)
431 , resetting_ourselves (false)
435 , ok_button (Stock::OK)
436 , cancel_button (Stock::CANCEL)
437 , apply_button (Stock::APPLY)
442 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
443 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
444 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
445 chooser.add_shortcut_folder_uri("file:///Volumes");
448 //add the file chooser
450 chooser.set_border_width (12);
452 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
453 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
455 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
456 audio_filter.set_name (_("Audio files"));
458 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
459 midi_filter.set_name (_("MIDI files"));
461 matchall_filter.add_pattern ("*.*");
462 matchall_filter.set_name (_("All files"));
464 chooser.add_filter (audio_and_midi_filter);
465 chooser.add_filter (audio_filter);
466 chooser.add_filter (midi_filter);
467 chooser.add_filter (matchall_filter);
468 chooser.set_select_multiple (true);
469 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
470 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
473 /* some broken redraw behaviour - this is a bandaid */
474 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
477 if (!persistent_folder.empty()) {
478 chooser.set_current_folder (persistent_folder);
481 notebook.append_page (chooser, _("Browse Files"));
483 hpacker.set_spacing (6);
484 hpacker.pack_start (notebook, true, true);
485 hpacker.pack_start (preview, false, false);
487 vpacker.set_spacing (6);
488 vpacker.pack_start (hpacker, true, true);
498 hbox = manage(new HBox);
499 hbox->pack_start (found_entry);
500 hbox->pack_start (found_search_btn);
502 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
503 scroll->add(found_list_view);
504 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
506 vbox = manage(new VBox);
507 vbox->pack_start (*hbox, PACK_SHRINK);
508 vbox->pack_start (*scroll);
510 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
512 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
514 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
516 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
517 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
519 notebook.append_page (*vbox, _("Search Tags"));
523 //add freesound search
528 passbox = manage(new HBox);
529 passbox->set_spacing (6);
531 label = manage (new Label);
532 label->set_text (_("Tags:"));
533 passbox->pack_start (*label, false, false);
534 passbox->pack_start (freesound_entry, true, true);
536 label = manage (new Label);
537 label->set_text (_("Sort:"));
538 passbox->pack_start (*label, false, false);
539 passbox->pack_start (freesound_sort, false, false);
540 freesound_sort.clear_items();
542 // Order of the following must correspond with enum sortMethod
543 // in sfdb_freesound_mootcher.h
544 freesound_sort.append_text(_("None"));
545 freesound_sort.append_text(_("Longest"));
546 freesound_sort.append_text(_("Shortest"));
547 freesound_sort.append_text(_("Newest"));
548 freesound_sort.append_text(_("Oldest"));
549 freesound_sort.append_text(_("Most downloaded"));
550 freesound_sort.append_text(_("Least downloaded"));
551 freesound_sort.append_text(_("Highest rated"));
552 freesound_sort.append_text(_("Lowest rated"));
553 freesound_sort.set_active(0);
555 passbox->pack_start (freesound_search_btn, false, false);
556 passbox->pack_start (freesound_more_btn, false, false);
557 freesound_more_btn.set_label(_("More"));
558 freesound_more_btn.set_sensitive(false);
560 passbox->pack_start (freesound_similar_btn, false, false);
561 freesound_similar_btn.set_label(_("Similar"));
562 freesound_similar_btn.set_sensitive(false);
564 scroll = manage(new ScrolledWindow);
565 scroll->add(freesound_list_view);
566 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
568 vbox = manage(new VBox);
569 vbox->set_spacing (3);
570 vbox->pack_start (*passbox, PACK_SHRINK);
571 vbox->pack_start (*scroll);
573 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
574 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
575 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
576 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
577 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
578 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
579 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
580 freesound_list_view.get_column(0)->set_alignment(0.5);
581 freesound_list_view.get_column(1)->set_expand(true); // filename
582 freesound_list_view.get_column(1)->set_resizable(true); // filename
583 freesound_list_view.get_column(2)->set_alignment(0.5);
584 freesound_list_view.get_column(3)->set_alignment(0.5);
585 freesound_list_view.get_column(4)->set_alignment(0.5);
586 freesound_list_view.get_column(5)->set_alignment(0.5);
588 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
589 freesound_list_view.set_tooltip_column(1);
591 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
592 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
593 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
594 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
595 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
596 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
597 notebook.append_page (*vbox, _("Search Freesound"));
600 notebook.set_size_request (500, -1);
601 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
605 Gtk::HButtonBox* button_box = manage (new HButtonBox);
607 button_box->set_layout (BUTTONBOX_END);
608 button_box->pack_start (cancel_button, false, false);
609 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
611 button_box->pack_start (apply_button, false, false);
612 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
615 button_box->pack_start (ok_button, false, false);
616 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
618 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
619 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
620 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
622 vpacker.pack_end (*button_box, false, false);
624 set_wmclass (X_("import"), PROGRAM_NAME);
627 SoundFileBrowser::~SoundFileBrowser ()
629 persistent_folder = chooser.get_current_folder();
633 SoundFileBrowser::run ()
642 gtk_main_iteration ();
649 SoundFileBrowser::set_action_sensitive (bool yn)
651 ok_button.set_sensitive (yn);
652 apply_button.set_sensitive (yn);
656 SoundFileBrowser::do_something (int action)
663 SoundFileBrowser::on_show ()
665 ArdourWindow::on_show ();
670 SoundFileBrowser::clear_selection ()
672 chooser.unselect_all ();
673 found_list_view.get_selection()->unselect_all ();
677 SoundFileBrowser::chooser_file_activated ()
683 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
689 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
695 SoundFileBrowser::set_session (Session* s)
697 ArdourWindow::set_session (s);
698 preview.set_session (s);
703 remove_gain_meter ();
708 SoundFileBrowser::add_gain_meter ()
712 gm = new GainMeter (_session, 250);
714 boost::shared_ptr<Route> r = _session->the_auditioner ();
716 gm->set_controls (r, r->shared_peak_meter(), r->amp());
717 gm->set_fader_name (X_("AudioTrackFader"));
719 meter_packer.set_border_width (12);
720 meter_packer.pack_start (*gm, false, true);
721 hpacker.pack_end (meter_packer, false, false);
722 meter_packer.show_all ();
727 SoundFileBrowser::remove_gain_meter ()
730 meter_packer.remove (*gm);
731 hpacker.remove (meter_packer);
738 SoundFileBrowser::start_metering ()
740 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
744 SoundFileBrowser::stop_metering ()
746 metering_connection.disconnect();
750 SoundFileBrowser::meter ()
752 if (is_mapped () && _session && gm) {
753 gm->update_meters ();
758 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
760 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
764 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
766 return SMFSource::safe_midi_file_extension (filter_info.filename);
770 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
772 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
776 SoundFileBrowser::update_preview ()
778 if (preview.setup_labels (chooser.get_preview_filename())) {
779 if (preview.autoplay()) {
780 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
786 SoundFileBrowser::found_list_view_selected ()
788 if (!reset_options ()) {
789 set_action_sensitive (false);
793 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
796 TreeIter iter = found_list->get_iter(*rows.begin());
797 file = (*iter)[found_list_columns.pathname];
798 chooser.set_filename (file);
799 set_action_sensitive (true);
801 set_action_sensitive (false);
804 preview.setup_labels (file);
809 SoundFileBrowser::found_search_clicked ()
811 string tag_string = found_entry.get_text ();
815 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
816 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
820 vector<string> results;
821 Library->search_members_and (results, tags);
824 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
825 TreeModel::iterator new_row = found_list->append();
826 TreeModel::Row row = *new_row;
827 string path = Glib::filename_from_uri (string ("file:") + *i);
828 row[found_list_columns.pathname] = path;
834 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
837 Mootcher *mootcher = new Mootcher;
840 string id = (*iter)[freesound_list_columns.id];
841 string uri = (*iter)[freesound_list_columns.uri];
842 string ofn = (*iter)[freesound_list_columns.filename];
844 if (mootcher->checkAudioFile(ofn, id)) {
845 // file already exists, no need to download it again
846 file = mootcher->audioFileName;
848 (*iter)[freesound_list_columns.started] = false;
851 if (!(*iter)[freesound_list_columns.started]) {
852 // start downloading the sound file
853 (*iter)[freesound_list_columns.started] = true;
854 mootcher->fetchAudioFile(ofn, id, uri, this);
860 SoundFileBrowser::freesound_list_view_selected ()
863 if (!reset_options ()) {
864 set_action_sensitive (false);
867 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
868 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
869 file = freesound_get_audio_file (freesound_list->get_iter(*i));
872 switch (rows.size()) {
875 freesound_similar_btn.set_sensitive(false);
876 set_action_sensitive (false);
879 // exactly one item selected
881 // file exists on disk already
882 chooser.set_filename (file);
883 preview.setup_labels (file);
884 set_action_sensitive (true);
886 freesound_similar_btn.set_sensitive(true);
889 // multiple items selected
890 preview.setup_labels ("");
891 freesound_similar_btn.set_sensitive(false);
899 SoundFileBrowser::refresh_display(std::string ID, std::string file)
901 // called when the mootcher has finished downloading a file
902 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
903 if (rows.size() == 1) {
904 // there's a single item selected in the freesound list
905 //XXX make a function to be used to construct the actual file name both here and in the mootcher
906 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
907 std::string selected_ID = (*row)[freesound_list_columns.id];
908 if (ID == selected_ID) {
909 // the selected item in the freesound list is the item that has just finished downloading
910 chooser.set_filename(file);
911 preview.setup_labels (file);
912 set_action_sensitive (true);
918 SoundFileBrowser::freesound_search_clicked ()
921 freesound_list->clear();
927 SoundFileBrowser::freesound_more_clicked ()
932 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
933 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
937 SoundFileBrowser::freesound_similar_clicked ()
939 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
940 if (rows.size() == 1) {
943 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
944 id = (*iter)[freesound_list_columns.id];
945 freesound_list->clear();
947 GdkCursor *prev_cursor;
948 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
949 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
952 std::string theString = mootcher.searchSimilar(id);
954 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
955 handle_freesound_results(theString);
960 SoundFileBrowser::freesound_search()
964 string search_string = freesound_entry.get_text ();
965 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
967 GdkCursor *prev_cursor;
968 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
969 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
972 std::string theString = mootcher.searchText(
976 "", // OSX eats anything incl mp3
978 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
983 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
984 handle_freesound_results(theString);
988 SoundFileBrowser::handle_freesound_results(std::string theString) {
990 doc.read_buffer( theString );
991 XMLNode *root = doc.root();
994 error << "no root XML node!" << endmsg;
998 if ( strcmp(root->name().c_str(), "response") != 0) {
999 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1003 // find out how many pages are available to search
1004 int freesound_n_pages = 1;
1005 XMLNode *res = root->child("num_pages");
1007 string result = res->child("text")->content();
1008 freesound_n_pages = atoi(result);
1011 int more_pages = freesound_n_pages - freesound_page;
1013 if (more_pages > 0) {
1014 freesound_more_btn.set_sensitive(true);
1015 freesound_more_btn.set_tooltip_text(string_compose(P_(
1016 "%1 more page of 100 results available",
1017 "%1 more pages of 100 results available",
1018 more_pages), more_pages));
1020 freesound_more_btn.set_sensitive(false);
1021 freesound_more_btn.set_tooltip_text(_("No more results available"));
1024 XMLNode *sounds_root = root->child("sounds");
1026 error << "no child node \"sounds\" found!" << endmsg;
1030 XMLNodeList sounds = sounds_root->children();
1031 if (sounds.size() == 0) {
1036 XMLNodeConstIterator niter;
1038 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1040 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1041 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1045 // node->dump(cerr, "node:");
1048 XMLNode *id_node = node->child ("id");
1049 XMLNode *uri_node = node->child ("serve");
1050 XMLNode *ofn_node = node->child ("original_filename");
1051 XMLNode *dur_node = node->child ("duration");
1052 XMLNode *siz_node = node->child ("filesize");
1053 XMLNode *srt_node = node->child ("samplerate");
1054 XMLNode *lic_node = node->child ("license");
1056 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1058 std::string id = id_node->child("text")->content();
1059 std::string uri = uri_node->child("text")->content();
1060 std::string ofn = ofn_node->child("text")->content();
1061 std::string dur = dur_node->child("text")->content();
1062 std::string siz = siz_node->child("text")->content();
1063 std::string srt = srt_node->child("text")->content();
1064 std::string lic = lic_node->child("text")->content();
1067 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1069 double duration_seconds = atof(dur);
1071 char duration_hhmmss[16];
1072 if (duration_seconds >= 99 * 60 * 60) {
1073 strcpy(duration_hhmmss, ">99h");
1075 s = modf(duration_seconds/60, &m) * 60;
1076 m = modf(m/60, &h) * 60;
1077 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1082 double size_bytes = atof(siz);
1084 if (size_bytes < 1000) {
1085 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1086 } else if (size_bytes < 1000000 ) {
1087 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1088 } else if (size_bytes < 10000000) {
1089 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1090 } else if (size_bytes < 1000000000) {
1091 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1093 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1096 /* see http://www.freesound.org/help/faq/#licenses */
1097 char shortlicense[64];
1098 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1099 sprintf(shortlicense, "CC-BY-NC");
1100 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1101 sprintf(shortlicense, "CC-BY");
1102 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1103 sprintf(shortlicense, "sampling+");
1104 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1105 sprintf(shortlicense, "PD");
1107 snprintf(shortlicense, 64, "%s", lic.c_str());
1108 shortlicense[63]= '\0';
1111 TreeModel::iterator new_row = freesound_list->append();
1112 TreeModel::Row row = *new_row;
1114 row[freesound_list_columns.id ] = id;
1115 row[freesound_list_columns.uri ] = uri;
1116 row[freesound_list_columns.filename] = ofn;
1117 row[freesound_list_columns.duration] = duration_hhmmss;
1118 row[freesound_list_columns.filesize] = bsize;
1119 row[freesound_list_columns.smplrate] = srt;
1120 row[freesound_list_columns.license ] = shortlicense;
1127 SoundFileBrowser::get_paths ()
1129 vector<string> results;
1131 int n = notebook.get_current_page ();
1134 vector<string> filenames = chooser.get_filenames();
1135 vector<string>::iterator i;
1137 for (i = filenames.begin(); i != filenames.end(); ++i) {
1139 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1140 results.push_back (*i);
1144 } else if (n == 1) {
1146 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1147 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1148 TreeIter iter = found_list->get_iter(*i);
1149 string str = (*iter)[found_list_columns.pathname];
1151 results.push_back (str);
1155 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1156 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1157 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1159 results.push_back (str);
1169 SoundFileOmega::reset_options_noret ()
1171 if (!resetting_ourselves) {
1172 (void) reset_options ();
1177 SoundFileOmega::reset_options ()
1179 vector<string> paths = get_paths ();
1181 if (paths.empty()) {
1183 channel_combo.set_sensitive (false);
1184 action_combo.set_sensitive (false);
1185 where_combo.set_sensitive (false);
1186 copy_files_btn.set_active (true);
1187 copy_files_btn.set_sensitive (false);
1193 channel_combo.set_sensitive (true);
1194 action_combo.set_sensitive (true);
1195 where_combo.set_sensitive (true);
1197 /* if we get through this function successfully, this may be
1198 reset at the end, once we know if we can use hard links
1199 to do embedding (or if we are importing a MIDI file).
1202 if (Config->get_only_copy_imported_files()) {
1203 copy_files_btn.set_sensitive (false);
1205 copy_files_btn.set_sensitive (false);
1211 bool selection_includes_multichannel;
1212 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1215 /* See if we are thinking about importing any MIDI files */
1216 vector<string>::iterator i = paths.begin ();
1217 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1220 bool const have_a_midi_file = (i != paths.end ());
1222 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1223 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1227 string existing_choice;
1228 vector<string> action_strings;
1230 resetting_ourselves = true;
1232 if (chooser.get_filter() == &audio_filter) {
1236 if (selected_audio_track_cnt > 0) {
1237 if (channel_combo.get_active_text().length()) {
1238 ImportDisposition id = get_channel_disposition();
1241 case Editing::ImportDistinctFiles:
1242 if (selected_audio_track_cnt == paths.size()) {
1243 action_strings.push_back (importmode2string (ImportToTrack));
1247 case Editing::ImportDistinctChannels:
1248 /* XXX it would be nice to allow channel-per-selected track
1249 but its too hard we don't want to deal with all the
1250 different per-file + per-track channel configurations.
1255 action_strings.push_back (importmode2string (ImportToTrack));
1265 if (selected_midi_track_cnt > 0) {
1266 action_strings.push_back (importmode2string (ImportToTrack));
1270 action_strings.push_back (importmode2string (ImportAsTrack));
1271 action_strings.push_back (importmode2string (ImportAsRegion));
1272 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1274 existing_choice = action_combo.get_active_text();
1276 set_popdown_strings (action_combo, action_strings);
1278 /* preserve any existing choice, if possible */
1281 if (existing_choice.length()) {
1282 vector<string>::iterator x;
1283 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1284 if (*x == existing_choice) {
1285 action_combo.set_active_text (existing_choice);
1289 if (x == action_strings.end()) {
1290 action_combo.set_active_text (action_strings.front());
1293 action_combo.set_active_text (action_strings.front());
1296 resetting_ourselves = false;
1298 if ((mode = get_mode()) == ImportAsRegion) {
1299 where_combo.set_sensitive (false);
1301 where_combo.set_sensitive (true);
1304 vector<string> channel_strings;
1306 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1307 channel_strings.push_back (_("one track per file"));
1309 if (selection_includes_multichannel) {
1310 channel_strings.push_back (_("one track per channel"));
1313 if (paths.size() > 1) {
1314 /* tape tracks are a single region per track, so we cannot
1315 sequence multiple files.
1317 if (mode != ImportAsTapeTrack) {
1318 channel_strings.push_back (_("sequence files"));
1321 channel_strings.push_back (_("all files in one track"));
1322 channel_strings.push_back (_("merge files"));
1328 channel_strings.push_back (_("one region per file"));
1330 if (selection_includes_multichannel) {
1331 channel_strings.push_back (_("one region per channel"));
1334 if (paths.size() > 1) {
1336 channel_strings.push_back (_("all files in one region"));
1341 resetting_ourselves = true;
1343 existing_choice = channel_combo.get_active_text();
1345 set_popdown_strings (channel_combo, channel_strings);
1347 /* preserve any existing choice, if possible */
1349 if (existing_choice.length()) {
1350 vector<string>::iterator x;
1351 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1352 if (*x == existing_choice) {
1353 channel_combo.set_active_text (existing_choice);
1357 if (x == channel_strings.end()) {
1358 channel_combo.set_active_text (channel_strings.front());
1361 channel_combo.set_active_text (channel_strings.front());
1364 resetting_ourselves = false;
1367 src_combo.set_sensitive (true);
1369 src_combo.set_sensitive (false);
1372 /* We must copy MIDI files or those from Freesound
1373 * or any file if we are under nsm control */
1374 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1376 if (Config->get_only_copy_imported_files()) {
1378 if (selection_can_be_embedded_with_links && !must_copy) {
1379 copy_files_btn.set_sensitive (true);
1382 copy_files_btn.set_active (true);
1384 copy_files_btn.set_sensitive (false);
1390 copy_files_btn.set_active (true);
1392 copy_files_btn.set_sensitive (!must_copy);
1400 SoundFileOmega::bad_file_message()
1402 MessageDialog msg (*this,
1403 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1408 resetting_ourselves = true;
1409 chooser.unselect_uri (chooser.get_preview_uri());
1410 resetting_ourselves = false;
1416 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1425 multichannel = false;
1427 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1429 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1430 if (info.channels > 1) {
1431 multichannel = true;
1436 if (sz != info.length) {
1441 if (info.samplerate != _session->frame_rate()) {
1445 } else if (SMFSource::safe_midi_file_extension (*i)) {
1449 if (reader.num_tracks() > 1) {
1450 multichannel = true; // "channel" == track here...
1453 /* XXX we need err = true handling here in case
1454 we can't check the file
1467 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1472 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1475 if (mkdir (tmpdir.c_str(), 0744)) {
1476 if (errno != EEXIST) {
1481 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1483 char tmpc[MAXPATHLEN+1];
1485 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1489 if (link ((*i).c_str(), tmpc)) {
1499 rmdir (tmpdir.c_str());
1504 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1505 : SoundFileBrowser (title, s, false)
1507 chooser.set_select_multiple (false);
1508 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1509 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1513 SoundFileChooser::on_hide ()
1515 ArdourWindow::on_hide();
1519 _session->cancel_audition();
1524 SoundFileChooser::get_filename ()
1526 vector<string> paths;
1528 paths = get_paths ();
1530 if (paths.empty()) {
1534 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1538 return paths.front();
1541 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1542 uint32_t selected_audio_tracks,
1543 uint32_t selected_midi_tracks,
1545 Editing::ImportMode mode_hint)
1546 : SoundFileBrowser (title, s, persistent)
1547 , copy_files_btn ( _("Copy files to session"))
1548 , selected_audio_track_cnt (selected_audio_tracks)
1549 , selected_midi_track_cnt (selected_midi_tracks)
1555 set_size_request (-1, 450);
1557 block_two.set_border_width (12);
1558 block_three.set_border_width (12);
1559 block_four.set_border_width (12);
1561 options.set_spacing (12);
1564 str.push_back (_("file timestamp"));
1565 str.push_back (_("edit point"));
1566 str.push_back (_("playhead"));
1567 str.push_back (_("session start"));
1568 set_popdown_strings (where_combo, str);
1569 where_combo.set_active_text (str.front());
1571 Label* l = manage (new Label);
1572 l->set_markup (_("<b>Add files as ...</b>"));
1574 vbox = manage (new VBox);
1575 vbox->set_border_width (12);
1576 vbox->set_spacing (6);
1577 vbox->pack_start (*l, false, false);
1578 vbox->pack_start (action_combo, false, false);
1579 hbox = manage (new HBox);
1580 hbox->pack_start (*vbox, false, false);
1581 options.pack_start (*hbox, false, false);
1583 /* dummy entry for action combo so that it doesn't look odd if we
1584 come up with no tracks selected.
1588 str.push_back (importmode2string (mode_hint));
1589 set_popdown_strings (action_combo, str);
1590 action_combo.set_active_text (str.front());
1591 action_combo.set_sensitive (false);
1593 l = manage (new Label);
1594 l->set_markup (_("<b>Insert at</b>"));
1596 vbox = manage (new VBox);
1597 vbox->set_border_width (12);
1598 vbox->set_spacing (6);
1599 vbox->pack_start (*l, false, false);
1600 vbox->pack_start (where_combo, false, false);
1601 hbox = manage (new HBox);
1602 hbox->pack_start (*vbox, false, false);
1603 options.pack_start (*hbox, false, false);
1606 l = manage (new Label);
1607 l->set_markup (_("<b>Mapping</b>"));
1609 vbox = manage (new VBox);
1610 vbox->set_border_width (12);
1611 vbox->set_spacing (6);
1612 vbox->pack_start (*l, false, false);
1613 vbox->pack_start (channel_combo, false, false);
1614 hbox = manage (new HBox);
1615 hbox->pack_start (*vbox, false, false);
1616 options.pack_start (*hbox, false, false);
1619 str.push_back (_("one track per file"));
1620 set_popdown_strings (channel_combo, str);
1621 channel_combo.set_active_text (str.front());
1622 channel_combo.set_sensitive (false);
1624 l = manage (new Label);
1625 l->set_markup (_("<b>Conversion quality</b>"));
1627 vbox = manage (new VBox);
1628 vbox->set_border_width (12);
1629 vbox->set_spacing (6);
1630 vbox->pack_start (*l, false, false);
1631 vbox->pack_start (src_combo, false, false);
1632 hbox = manage (new HBox);
1633 hbox->pack_start (*vbox, false, false);
1634 options.pack_start (*hbox, false, false);
1637 str.push_back (_("Best"));
1638 str.push_back (_("Good"));
1639 str.push_back (_("Quick"));
1640 str.push_back (_("Fast"));
1641 str.push_back (_("Fastest"));
1643 set_popdown_strings (src_combo, str);
1644 src_combo.set_active_text (str.front());
1645 src_combo.set_sensitive (false);
1649 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1650 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1652 copy_files_btn.set_active (true);
1654 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1657 copy_label->set_size_request (175, -1);
1658 copy_label->set_line_wrap (true);
1661 block_four.pack_start (copy_files_btn, false, false);
1663 options.pack_start (block_four, false, false);
1665 vpacker.pack_start (options, false, false);
1667 /* setup disposition map */
1669 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1670 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1671 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1672 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1674 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1675 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1676 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1677 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1679 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1681 /* set size requests for a couple of combos to allow them to display the longest text
1682 they will ever be asked to display. This prevents them being resized when the user
1683 selects a file to import, which in turn prevents the size of the dialog from jumping
1687 t.push_back (_("one track per file"));
1688 t.push_back (_("one track per channel"));
1689 t.push_back (_("sequence files"));
1690 t.push_back (_("all files in one region"));
1691 set_popdown_strings (channel_combo, t);
1694 t.push_back (importmode2string (ImportAsTrack));
1695 t.push_back (importmode2string (ImportToTrack));
1696 t.push_back (importmode2string (ImportAsRegion));
1697 t.push_back (importmode2string (ImportAsTapeTrack));
1698 set_popdown_strings (action_combo, t);
1702 SoundFileOmega::set_mode (ImportMode mode)
1704 action_combo.set_active_text (importmode2string (mode));
1708 SoundFileOmega::get_mode () const
1710 return string2importmode (action_combo.get_active_text());
1714 SoundFileOmega::on_hide ()
1716 ArdourWindow::on_hide();
1718 _session->cancel_audition();
1723 SoundFileOmega::get_position() const
1725 string str = where_combo.get_active_text();
1727 if (str == _("file timestamp")) {
1728 return ImportAtTimestamp;
1729 } else if (str == _("edit point")) {
1730 return ImportAtEditPoint;
1731 } else if (str == _("playhead")) {
1732 return ImportAtPlayhead;
1734 return ImportAtStart;
1739 SoundFileOmega::get_src_quality() const
1741 string str = src_combo.get_active_text();
1743 if (str == _("Best")) {
1745 } else if (str == _("Good")) {
1747 } else if (str == _("Quick")) {
1749 } else if (str == _("Fast")) {
1757 SoundFileOmega::get_channel_disposition () const
1759 /* we use a map here because the channel combo can contain different strings
1760 depending on the state of the other combos. the map contains all possible strings
1761 and the ImportDisposition enum that corresponds to it.
1764 string str = channel_combo.get_active_text();
1765 DispositionMap::const_iterator x = disposition_map.find (str);
1767 if (x == disposition_map.end()) {
1768 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1776 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1778 selected_audio_track_cnt = selected_audio_tracks;
1779 selected_midi_track_cnt = selected_midi_tracks;
1781 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1782 chooser.set_filter (midi_filter);
1783 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1784 chooser.set_filter (audio_filter);
1786 chooser.set_filter (audio_and_midi_filter);
1793 SoundFileOmega::file_selection_changed ()
1795 if (resetting_ourselves) {
1799 if (!reset_options ()) {
1800 set_action_sensitive (false);
1802 if (chooser.get_filenames().size() > 0) {
1803 set_action_sensitive (true);
1805 set_action_sensitive (false);
1811 SoundFileOmega::do_something (int action)
1813 SoundFileBrowser::do_something (action);
1815 if (action == RESPONSE_CANCEL) {
1822 vector<string> paths = get_paths ();
1823 ImportPosition pos = get_position ();
1824 ImportMode mode = get_mode ();
1825 ImportDisposition chns = get_channel_disposition ();
1829 case ImportAtEditPoint:
1830 where = PublicEditor::instance().get_preferred_edit_position ();
1832 case ImportAtTimestamp:
1835 case ImportAtPlayhead:
1836 where = _session->transport_frame();
1839 where = _session->current_start_frame();
1843 SrcQuality quality = get_src_quality();
1845 if (copy_files_btn.get_active()) {
1846 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1848 PublicEditor::instance().do_embed (paths, chns, mode, where);
1851 if (action == RESPONSE_OK) {