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>
34 #include <glibmm/fileutils.h>
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"
42 #include <gtkmm2ext/utils.h>
44 #include "evoral/SMF.hpp"
46 #include "ardour/audio_library.h"
47 #include "ardour/auditioner.h"
48 #include "ardour/audioregion.h"
49 #include "ardour/audiofilesource.h"
50 #include "ardour/smf_source.h"
51 #include "ardour/region_factory.h"
52 #include "ardour/source_factory.h"
53 #include "ardour/session.h"
54 #include "ardour/session_directory.h"
56 #include "ardour_ui.h"
58 #include "gui_thread.h"
63 #include "gain_meter.h"
64 #include "main_clock.h"
65 #include "public_editor.h"
67 #include "sfdb_freesound_mootcher.h"
71 using namespace ARDOUR;
75 using namespace Gtkmm2ext;
76 using namespace Editing;
80 string SoundFileBrowser::persistent_folder;
81 typedef TreeView::Selection::ListHandle_Path ListPath;
84 string2importmode (string str)
86 if (str == _("as new tracks")) {
88 } else if (str == _("to selected tracks")) {
90 } else if (str == _("to region list")) {
91 return ImportAsRegion;
92 } else if (str == _("as new tape tracks")) {
93 return ImportAsTapeTrack;
96 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
102 importmode2string (ImportMode mode)
106 return _("as new tracks");
108 return _("to selected tracks");
110 return _("to region list");
111 case ImportAsTapeTrack:
112 return _("as new tape tracks");
115 return _("as new tracks");
118 SoundFileBox::SoundFileBox (bool persistent)
120 length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
121 timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
123 autoplay_btn (_("Auto-play"))
126 set_name (X_("SoundFileBox"));
127 set_size_request (300, -1);
129 preview_label.set_markup (_("<b>Sound File Information</b>"));
131 border_frame.set_label_widget (preview_label);
132 border_frame.add (main_box);
134 pack_start (border_frame, true, true);
135 set_border_width (6);
137 main_box.set_border_width (6);
139 length.set_text (_("Length:"));
140 length.set_alignment (1, 0.5);
141 timecode.set_text (_("Timestamp:"));
142 timecode.set_alignment (1, 0.5);
143 format.set_text (_("Format:"));
144 format.set_alignment (1, 0.5);
145 channels.set_text (_("Channels:"));
146 channels.set_alignment (1, 0.5);
147 samplerate.set_text (_("Sample rate:"));
148 samplerate.set_alignment (1, 0.5);
150 preview_label.set_max_width_chars (50);
151 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
153 format_text.set_max_width_chars (20);
154 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
155 format_text.set_alignment (0, 1);
157 table.set_col_spacings (6);
158 table.set_homogeneous (false);
159 table.set_row_spacings (6);
161 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
162 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
163 table.attach (format, 0, 1, 2, 4, FILL, FILL);
164 table.attach (length, 0, 1, 4, 5, FILL, FILL);
165 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
167 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
168 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
169 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
170 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
171 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
173 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
174 timecode_clock.set_mode (AudioClock::Timecode);
176 main_box.pack_start (table, false, false);
178 tags_entry.set_editable (true);
179 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
180 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
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);
187 main_box.pack_start (bottom_box, false, false);
189 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
190 // play_btn.set_label (_("Play"));
192 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
193 // stop_btn.set_label (_("Stop"));
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);
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));
204 channels_value.set_alignment (0.0f, 0.5f);
205 samplerate_value.set_alignment (0.0f, 0.5f);
209 SoundFileBox::set_session(Session* s)
211 SessionHandlePtr::set_session (s);
213 length_clock.set_session (s);
214 timecode_clock.set_session (s);
217 play_btn.set_sensitive (false);
218 stop_btn.set_sensitive (false);
223 SoundFileBox::setup_labels (const string& filename)
226 // save existing tags
234 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
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 ("");
242 length_clock.set (0);
243 timecode_clock.set (0);
245 tags_entry.set_sensitive (false);
246 play_btn.set_sensitive (false);
251 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
252 std::string n = sf_info.format_name;
253 if (n.substr (0, 8) == X_("Format: ")) {
256 format_text.set_text (n);
257 channels_value.set_text (to_string (sf_info.channels, std::dec));
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");
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");
271 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
272 double src_coef = (double) nfr / sf_info.samplerate;
274 length_clock.set (sf_info.length * src_coef + 0.5, true);
275 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
277 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
279 vector<string> tags = Library->get_tags (string ("//") + filename);
281 stringstream tag_string;
282 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
283 if (i != tags.begin()) {
288 tags_entry.get_buffer()->set_text (tag_string.str());
290 tags_entry.set_sensitive (true);
292 play_btn.set_sensitive (true);
299 SoundFileBox::autoplay() const
301 return autoplay_btn.get_active();
305 SoundFileBox::audition_oneshot()
312 SoundFileBox::audition ()
318 if (SMFSource::safe_midi_file_extension (path)) {
319 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
323 _session->cancel_audition();
325 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
326 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
330 boost::shared_ptr<Region> r;
332 boost::shared_ptr<AudioFileSource> afs;
333 bool old_sbp = AudioSource::get_build_peakfiles ();
335 /* don't even think of building peakfiles for these files */
337 AudioSource::set_build_peakfiles (false);
339 for (int n = 0; n < sf_info.channels; ++n) {
341 afs = boost::dynamic_pointer_cast<AudioFileSource> (
342 SourceFactory::createExternal (DataType::AUDIO, *_session,
344 Source::Flag (0), false));
346 srclist.push_back(afs);
348 } catch (failed_constructor& err) {
349 error << _("Could not access soundfile: ") << path << endmsg;
350 AudioSource::set_build_peakfiles (old_sbp);
355 AudioSource::set_build_peakfiles (old_sbp);
357 if (srclist.empty()) {
361 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
362 string rname = region_name_from_path (afs->path(), false);
366 plist.add (ARDOUR::Properties::start, 0);
367 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
368 plist.add (ARDOUR::Properties::name, rname);
369 plist.add (ARDOUR::Properties::layer, 0);
371 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
373 _session->audition_region(r);
377 SoundFileBox::stop_audition ()
380 _session->cancel_audition();
385 SoundFileBox::tags_entry_left (GdkEventFocus *)
392 SoundFileBox::tags_changed ()
394 string tag_string = tags_entry.get_buffer()->get_text ();
396 if (tag_string.empty()) {
402 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
403 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
411 SoundFileBox::save_tags (const vector<string>& tags)
413 Library->set_tags (string ("//") + path, tags);
414 Library->save_changes ();
417 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
418 : ArdourWindow (title)
419 , found_list (ListStore::create(found_list_columns))
420 , freesound_list (ListStore::create(freesound_list_columns))
421 , chooser (FILE_CHOOSER_ACTION_OPEN)
422 , preview (persistent)
423 , found_search_btn (_("Search"))
424 , found_list_view (found_list)
425 , freesound_search_btn (_("Search"))
426 , freesound_list_view (freesound_list)
427 , resetting_ourselves (false)
431 , ok_button (Stock::OK)
432 , cancel_button (Stock::CANCEL)
433 , apply_button (Stock::APPLY)
438 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
439 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
440 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
441 chooser.add_shortcut_folder_uri("file:///Volumes");
444 //add the file chooser
446 chooser.set_border_width (12);
448 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
449 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
451 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
452 audio_filter.set_name (_("Audio files"));
454 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
455 midi_filter.set_name (_("MIDI files"));
457 matchall_filter.add_pattern ("*.*");
458 matchall_filter.set_name (_("All files"));
460 chooser.add_filter (audio_and_midi_filter);
461 chooser.add_filter (audio_filter);
462 chooser.add_filter (midi_filter);
463 chooser.add_filter (matchall_filter);
464 chooser.set_select_multiple (true);
465 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
466 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
469 /* some broken redraw behaviour - this is a bandaid */
470 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
473 if (!persistent_folder.empty()) {
474 chooser.set_current_folder (persistent_folder);
477 notebook.append_page (chooser, _("Browse Files"));
479 hpacker.set_spacing (6);
480 hpacker.pack_start (notebook, true, true);
481 hpacker.pack_start (preview, false, false);
483 vpacker.set_spacing (6);
484 vpacker.pack_start (hpacker, true, true);
494 hbox = manage(new HBox);
495 hbox->pack_start (found_entry);
496 hbox->pack_start (found_search_btn);
498 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
499 scroll->add(found_list_view);
500 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
502 vbox = manage(new VBox);
503 vbox->pack_start (*hbox, PACK_SHRINK);
504 vbox->pack_start (*scroll);
506 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
508 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
510 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
512 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
513 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
515 notebook.append_page (*vbox, _("Search Tags"));
517 //add freesound search
522 passbox = manage(new HBox);
523 passbox->set_spacing (6);
525 label = manage (new Label);
526 label->set_text (_("Tags:"));
527 passbox->pack_start (*label, false, false);
528 passbox->pack_start (freesound_entry, true, true);
530 label = manage (new Label);
531 label->set_text (_("Sort:"));
532 passbox->pack_start (*label, false, false);
533 passbox->pack_start (freesound_sort, false, false);
534 freesound_sort.clear_items();
536 // Order of the following must correspond with enum sortMethod
537 // in sfdb_freesound_mootcher.h
538 freesound_sort.append_text(_("None"));
539 freesound_sort.append_text(_("Longest"));
540 freesound_sort.append_text(_("Shortest"));
541 freesound_sort.append_text(_("Newest"));
542 freesound_sort.append_text(_("Oldest"));
543 freesound_sort.append_text(_("Most downloaded"));
544 freesound_sort.append_text(_("Least downloaded"));
545 freesound_sort.append_text(_("Highest rated"));
546 freesound_sort.append_text(_("Lowest rated"));
547 freesound_sort.set_active(0);
549 passbox->pack_start (freesound_search_btn, false, false);
550 passbox->pack_start (freesound_more_btn, false, false);
551 freesound_more_btn.set_label(_("More"));
552 freesound_more_btn.set_sensitive(false);
554 passbox->pack_start (freesound_similar_btn, false, false);
555 freesound_similar_btn.set_label(_("Similar"));
556 freesound_similar_btn.set_sensitive(false);
558 scroll = manage(new ScrolledWindow);
559 scroll->add(freesound_list_view);
560 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
562 vbox = manage(new VBox);
563 vbox->set_spacing (3);
564 vbox->pack_start (*passbox, PACK_SHRINK);
565 vbox->pack_start (*scroll);
567 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
568 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
569 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
570 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
571 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
572 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
573 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
574 freesound_list_view.get_column(0)->set_alignment(0.5);
575 freesound_list_view.get_column(1)->set_expand(true); // filename
576 freesound_list_view.get_column(1)->set_resizable(true); // filename
577 freesound_list_view.get_column(2)->set_alignment(0.5);
578 freesound_list_view.get_column(3)->set_alignment(0.5);
579 freesound_list_view.get_column(4)->set_alignment(0.5);
580 freesound_list_view.get_column(5)->set_alignment(0.5);
582 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
583 freesound_list_view.set_tooltip_column(1);
585 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
586 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
587 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
588 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
589 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
590 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
591 notebook.append_page (*vbox, _("Search Freesound"));
593 notebook.set_size_request (500, -1);
594 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
598 Gtk::HButtonBox* button_box = manage (new HButtonBox);
600 button_box->set_layout (BUTTONBOX_END);
601 button_box->pack_start (cancel_button, false, false);
602 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
604 button_box->pack_start (apply_button, false, false);
605 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
608 button_box->pack_start (ok_button, false, false);
609 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
611 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
612 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
613 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
615 vpacker.pack_end (*button_box, false, false);
617 set_wmclass (X_("import"), PROGRAM_NAME);
620 SoundFileBrowser::~SoundFileBrowser ()
622 persistent_folder = chooser.get_current_folder();
626 SoundFileBrowser::run ()
635 gtk_main_iteration ();
642 SoundFileBrowser::set_action_sensitive (bool yn)
644 ok_button.set_sensitive (yn);
645 apply_button.set_sensitive (yn);
649 SoundFileBrowser::do_something (int action)
656 SoundFileBrowser::on_show ()
658 ArdourWindow::on_show ();
663 SoundFileBrowser::clear_selection ()
665 chooser.unselect_all ();
666 found_list_view.get_selection()->unselect_all ();
670 SoundFileBrowser::chooser_file_activated ()
676 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
682 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
688 SoundFileBrowser::set_session (Session* s)
690 ArdourWindow::set_session (s);
691 preview.set_session (s);
696 remove_gain_meter ();
701 SoundFileBrowser::add_gain_meter ()
705 gm = new GainMeter (_session, 250);
707 boost::shared_ptr<Route> r = _session->the_auditioner ();
709 gm->set_controls (r, r->shared_peak_meter(), r->amp());
710 gm->set_fader_name (X_("AudioTrackFader"));
712 meter_packer.set_border_width (12);
713 meter_packer.pack_start (*gm, false, true);
714 hpacker.pack_end (meter_packer, false, false);
715 meter_packer.show_all ();
720 SoundFileBrowser::remove_gain_meter ()
723 meter_packer.remove (*gm);
724 hpacker.remove (meter_packer);
731 SoundFileBrowser::start_metering ()
733 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
737 SoundFileBrowser::stop_metering ()
739 metering_connection.disconnect();
743 SoundFileBrowser::meter ()
745 if (is_mapped () && _session && gm) {
746 gm->update_meters ();
751 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
753 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
757 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
759 return SMFSource::safe_midi_file_extension (filter_info.filename);
763 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
765 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
769 SoundFileBrowser::update_preview ()
771 if (preview.setup_labels (chooser.get_preview_filename())) {
772 if (preview.autoplay()) {
773 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
779 SoundFileBrowser::found_list_view_selected ()
781 if (!reset_options ()) {
782 set_action_sensitive (false);
786 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
789 TreeIter iter = found_list->get_iter(*rows.begin());
790 file = (*iter)[found_list_columns.pathname];
791 chooser.set_filename (file);
792 set_action_sensitive (true);
794 set_action_sensitive (false);
797 preview.setup_labels (file);
802 SoundFileBrowser::found_search_clicked ()
804 string tag_string = found_entry.get_text ();
808 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
809 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
813 vector<string> results;
814 Library->search_members_and (results, tags);
817 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
818 TreeModel::iterator new_row = found_list->append();
819 TreeModel::Row row = *new_row;
820 string path = Glib::filename_from_uri (string ("file:") + *i);
821 row[found_list_columns.pathname] = path;
827 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
830 Mootcher *mootcher = new Mootcher;
833 string id = (*iter)[freesound_list_columns.id];
834 string uri = (*iter)[freesound_list_columns.uri];
835 string ofn = (*iter)[freesound_list_columns.filename];
837 if (mootcher->checkAudioFile(ofn, id)) {
838 // file already exists, no need to download it again
839 file = mootcher->audioFileName;
841 (*iter)[freesound_list_columns.started] = false;
844 if (!(*iter)[freesound_list_columns.started]) {
845 // start downloading the sound file
846 (*iter)[freesound_list_columns.started] = true;
847 mootcher->fetchAudioFile(ofn, id, uri, this);
853 SoundFileBrowser::freesound_list_view_selected ()
856 if (!reset_options ()) {
857 set_action_sensitive (false);
860 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
861 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
862 file = freesound_get_audio_file (freesound_list->get_iter(*i));
865 switch (rows.size()) {
868 freesound_similar_btn.set_sensitive(false);
869 set_action_sensitive (false);
872 // exactly one item selected
874 // file exists on disk already
875 chooser.set_filename (file);
876 preview.setup_labels (file);
877 set_action_sensitive (true);
879 freesound_similar_btn.set_sensitive(true);
882 // multiple items selected
883 preview.setup_labels ("");
884 freesound_similar_btn.set_sensitive(false);
892 SoundFileBrowser::refresh_display(std::string ID, std::string file)
894 // called when the mootcher has finished downloading a file
895 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
896 if (rows.size() == 1) {
897 // there's a single item selected in the freesound list
898 //XXX make a function to be used to construct the actual file name both here and in the mootcher
899 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
900 std::string selected_ID = (*row)[freesound_list_columns.id];
901 if (ID == selected_ID) {
902 // the selected item in the freesound list is the item that has just finished downloading
903 chooser.set_filename(file);
904 preview.setup_labels (file);
905 set_action_sensitive (true);
911 SoundFileBrowser::freesound_search_clicked ()
914 freesound_list->clear();
920 SoundFileBrowser::freesound_more_clicked ()
925 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
926 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
930 SoundFileBrowser::freesound_similar_clicked ()
932 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
933 if (rows.size() == 1) {
936 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
937 id = (*iter)[freesound_list_columns.id];
938 freesound_list->clear();
940 GdkCursor *prev_cursor;
941 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
942 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
945 std::string theString = mootcher.searchSimilar(id);
947 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
948 handle_freesound_results(theString);
953 SoundFileBrowser::freesound_search()
957 string search_string = freesound_entry.get_text ();
958 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
960 GdkCursor *prev_cursor;
961 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
962 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
965 std::string theString = mootcher.searchText(
969 "", // OSX eats anything incl mp3
971 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
976 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
977 handle_freesound_results(theString);
981 SoundFileBrowser::handle_freesound_results(std::string theString) {
983 doc.read_buffer( theString );
984 XMLNode *root = doc.root();
987 error << "no root XML node!" << endmsg;
991 if ( strcmp(root->name().c_str(), "response") != 0) {
992 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
996 // find out how many pages are available to search
997 int freesound_n_pages = 1;
998 XMLNode *res = root->child("num_pages");
1000 string result = res->child("text")->content();
1001 freesound_n_pages = atoi(result);
1004 int more_pages = freesound_n_pages - freesound_page;
1006 if (more_pages > 0) {
1007 freesound_more_btn.set_sensitive(true);
1008 freesound_more_btn.set_tooltip_text(string_compose(P_(
1009 "%1 more page of 100 results available",
1010 "%1 more pages of 100 results available",
1011 more_pages), more_pages));
1013 freesound_more_btn.set_sensitive(false);
1014 freesound_more_btn.set_tooltip_text(_("No more results available"));
1017 XMLNode *sounds_root = root->child("sounds");
1019 error << "no child node \"sounds\" found!" << endmsg;
1023 XMLNodeList sounds = sounds_root->children();
1024 if (sounds.size() == 0) {
1029 XMLNodeConstIterator niter;
1031 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1033 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1034 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1038 // node->dump(cerr, "node:");
1041 XMLNode *id_node = node->child ("id");
1042 XMLNode *uri_node = node->child ("serve");
1043 XMLNode *ofn_node = node->child ("original_filename");
1044 XMLNode *dur_node = node->child ("duration");
1045 XMLNode *siz_node = node->child ("filesize");
1046 XMLNode *srt_node = node->child ("samplerate");
1047 XMLNode *lic_node = node->child ("license");
1049 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1051 std::string id = id_node->child("text")->content();
1052 std::string uri = uri_node->child("text")->content();
1053 std::string ofn = ofn_node->child("text")->content();
1054 std::string dur = dur_node->child("text")->content();
1055 std::string siz = siz_node->child("text")->content();
1056 std::string srt = srt_node->child("text")->content();
1057 std::string lic = lic_node->child("text")->content();
1060 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1062 double duration_seconds = atof(dur);
1064 char duration_hhmmss[16];
1065 if (duration_seconds >= 99 * 60 * 60) {
1066 strcpy(duration_hhmmss, ">99h");
1068 s = modf(duration_seconds/60, &m) * 60;
1069 m = modf(m/60, &h) * 60;
1070 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1075 double size_bytes = atof(siz);
1077 if (size_bytes < 1000) {
1078 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1079 } else if (size_bytes < 1000000 ) {
1080 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1081 } else if (size_bytes < 10000000) {
1082 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1083 } else if (size_bytes < 1000000000) {
1084 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1086 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1089 /* see http://www.freesound.org/help/faq/#licenses */
1090 char shortlicense[64];
1091 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1092 sprintf(shortlicense, "CC-BY-NC");
1093 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1094 sprintf(shortlicense, "CC-BY");
1095 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1096 sprintf(shortlicense, "sampling+");
1097 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1098 sprintf(shortlicense, "PD");
1100 snprintf(shortlicense, 64, "%s", lic.c_str());
1101 shortlicense[63]= '\0';
1104 TreeModel::iterator new_row = freesound_list->append();
1105 TreeModel::Row row = *new_row;
1107 row[freesound_list_columns.id ] = id;
1108 row[freesound_list_columns.uri ] = uri;
1109 row[freesound_list_columns.filename] = ofn;
1110 row[freesound_list_columns.duration] = duration_hhmmss;
1111 row[freesound_list_columns.filesize] = bsize;
1112 row[freesound_list_columns.smplrate] = srt;
1113 row[freesound_list_columns.license ] = shortlicense;
1120 SoundFileBrowser::get_paths ()
1122 vector<string> results;
1124 int n = notebook.get_current_page ();
1127 vector<string> filenames = chooser.get_filenames();
1128 vector<string>::iterator i;
1130 for (i = filenames.begin(); i != filenames.end(); ++i) {
1132 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1133 results.push_back (*i);
1137 } else if (n == 1) {
1139 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1140 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1141 TreeIter iter = found_list->get_iter(*i);
1142 string str = (*iter)[found_list_columns.pathname];
1144 results.push_back (str);
1147 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1148 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1149 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1151 results.push_back (str);
1160 SoundFileOmega::reset_options_noret ()
1162 if (!resetting_ourselves) {
1163 (void) reset_options ();
1168 SoundFileOmega::reset_options ()
1170 vector<string> paths = get_paths ();
1172 if (paths.empty()) {
1174 channel_combo.set_sensitive (false);
1175 action_combo.set_sensitive (false);
1176 where_combo.set_sensitive (false);
1177 copy_files_btn.set_active (true);
1178 copy_files_btn.set_sensitive (false);
1184 channel_combo.set_sensitive (true);
1185 action_combo.set_sensitive (true);
1186 where_combo.set_sensitive (true);
1188 /* if we get through this function successfully, this may be
1189 reset at the end, once we know if we can use hard links
1190 to do embedding (or if we are importing a MIDI file).
1193 if (Config->get_only_copy_imported_files()) {
1194 copy_files_btn.set_sensitive (false);
1196 copy_files_btn.set_sensitive (false);
1202 bool selection_includes_multichannel;
1203 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1206 /* See if we are thinking about importing any MIDI files */
1207 vector<string>::iterator i = paths.begin ();
1208 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1211 bool const have_a_midi_file = (i != paths.end ());
1213 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1214 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1218 string existing_choice;
1219 vector<string> action_strings;
1221 resetting_ourselves = true;
1223 if (chooser.get_filter() == &audio_filter) {
1227 if (selected_audio_track_cnt > 0) {
1228 if (channel_combo.get_active_text().length()) {
1229 ImportDisposition id = get_channel_disposition();
1232 case Editing::ImportDistinctFiles:
1233 if (selected_audio_track_cnt == paths.size()) {
1234 action_strings.push_back (importmode2string (ImportToTrack));
1238 case Editing::ImportDistinctChannels:
1239 /* XXX it would be nice to allow channel-per-selected track
1240 but its too hard we don't want to deal with all the
1241 different per-file + per-track channel configurations.
1246 action_strings.push_back (importmode2string (ImportToTrack));
1256 if (selected_midi_track_cnt > 0) {
1257 action_strings.push_back (importmode2string (ImportToTrack));
1261 action_strings.push_back (importmode2string (ImportAsTrack));
1262 action_strings.push_back (importmode2string (ImportAsRegion));
1263 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1265 existing_choice = action_combo.get_active_text();
1267 set_popdown_strings (action_combo, action_strings);
1269 /* preserve any existing choice, if possible */
1272 if (existing_choice.length()) {
1273 vector<string>::iterator x;
1274 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1275 if (*x == existing_choice) {
1276 action_combo.set_active_text (existing_choice);
1280 if (x == action_strings.end()) {
1281 action_combo.set_active_text (action_strings.front());
1284 action_combo.set_active_text (action_strings.front());
1287 resetting_ourselves = false;
1289 if ((mode = get_mode()) == ImportAsRegion) {
1290 where_combo.set_sensitive (false);
1292 where_combo.set_sensitive (true);
1295 vector<string> channel_strings;
1297 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1298 channel_strings.push_back (_("one track per file"));
1300 if (selection_includes_multichannel) {
1301 channel_strings.push_back (_("one track per channel"));
1304 if (paths.size() > 1) {
1305 /* tape tracks are a single region per track, so we cannot
1306 sequence multiple files.
1308 if (mode != ImportAsTapeTrack) {
1309 channel_strings.push_back (_("sequence files"));
1312 channel_strings.push_back (_("all files in one track"));
1313 channel_strings.push_back (_("merge files"));
1319 channel_strings.push_back (_("one region per file"));
1321 if (selection_includes_multichannel) {
1322 channel_strings.push_back (_("one region per channel"));
1325 if (paths.size() > 1) {
1327 channel_strings.push_back (_("all files in one region"));
1332 resetting_ourselves = true;
1334 existing_choice = channel_combo.get_active_text();
1336 set_popdown_strings (channel_combo, channel_strings);
1338 /* preserve any existing choice, if possible */
1340 if (existing_choice.length()) {
1341 vector<string>::iterator x;
1342 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1343 if (*x == existing_choice) {
1344 channel_combo.set_active_text (existing_choice);
1348 if (x == channel_strings.end()) {
1349 channel_combo.set_active_text (channel_strings.front());
1352 channel_combo.set_active_text (channel_strings.front());
1355 resetting_ourselves = false;
1358 src_combo.set_sensitive (true);
1360 src_combo.set_sensitive (false);
1363 /* We must copy MIDI files or those from Freesound
1364 * or any file if we are under nsm control */
1365 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1367 if (Config->get_only_copy_imported_files()) {
1369 if (selection_can_be_embedded_with_links && !must_copy) {
1370 copy_files_btn.set_sensitive (true);
1373 copy_files_btn.set_active (true);
1375 copy_files_btn.set_sensitive (false);
1381 copy_files_btn.set_active (true);
1383 copy_files_btn.set_sensitive (!must_copy);
1391 SoundFileOmega::bad_file_message()
1393 MessageDialog msg (*this,
1394 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1399 resetting_ourselves = true;
1400 chooser.unselect_uri (chooser.get_preview_uri());
1401 resetting_ourselves = false;
1407 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1416 multichannel = false;
1418 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1420 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1421 if (info.channels > 1) {
1422 multichannel = true;
1427 if (sz != info.length) {
1432 if (info.samplerate != _session->frame_rate()) {
1436 } else if (SMFSource::safe_midi_file_extension (*i)) {
1440 if (reader.num_tracks() > 1) {
1441 multichannel = true; // "channel" == track here...
1444 /* XXX we need err = true handling here in case
1445 we can't check the file
1458 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1460 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1463 if (mkdir (tmpdir.c_str(), 0744)) {
1464 if (errno != EEXIST) {
1469 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1471 char tmpc[MAXPATHLEN+1];
1473 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1477 if (link ((*i).c_str(), tmpc)) {
1487 rmdir (tmpdir.c_str());
1491 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1492 : SoundFileBrowser (title, s, false)
1494 chooser.set_select_multiple (false);
1495 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1496 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1500 SoundFileChooser::on_hide ()
1502 ArdourWindow::on_hide();
1506 _session->cancel_audition();
1511 SoundFileChooser::get_filename ()
1513 vector<string> paths;
1515 paths = get_paths ();
1517 if (paths.empty()) {
1521 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1525 return paths.front();
1528 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1529 uint32_t selected_audio_tracks,
1530 uint32_t selected_midi_tracks,
1532 Editing::ImportMode mode_hint)
1533 : SoundFileBrowser (title, s, persistent)
1534 , copy_files_btn ( _("Copy files to session"))
1535 , selected_audio_track_cnt (selected_audio_tracks)
1536 , selected_midi_track_cnt (selected_midi_tracks)
1542 set_size_request (-1, 450);
1544 block_two.set_border_width (12);
1545 block_three.set_border_width (12);
1546 block_four.set_border_width (12);
1548 options.set_spacing (12);
1551 str.push_back (_("file timestamp"));
1552 str.push_back (_("edit point"));
1553 str.push_back (_("playhead"));
1554 str.push_back (_("session start"));
1555 set_popdown_strings (where_combo, str);
1556 where_combo.set_active_text (str.front());
1558 Label* l = manage (new Label);
1559 l->set_markup (_("<b>Add files as ...</b>"));
1561 vbox = manage (new VBox);
1562 vbox->set_border_width (12);
1563 vbox->set_spacing (6);
1564 vbox->pack_start (*l, false, false);
1565 vbox->pack_start (action_combo, false, false);
1566 hbox = manage (new HBox);
1567 hbox->pack_start (*vbox, false, false);
1568 options.pack_start (*hbox, false, false);
1570 /* dummy entry for action combo so that it doesn't look odd if we
1571 come up with no tracks selected.
1575 str.push_back (importmode2string (mode_hint));
1576 set_popdown_strings (action_combo, str);
1577 action_combo.set_active_text (str.front());
1578 action_combo.set_sensitive (false);
1580 l = manage (new Label);
1581 l->set_markup (_("<b>Insert at</b>"));
1583 vbox = manage (new VBox);
1584 vbox->set_border_width (12);
1585 vbox->set_spacing (6);
1586 vbox->pack_start (*l, false, false);
1587 vbox->pack_start (where_combo, false, false);
1588 hbox = manage (new HBox);
1589 hbox->pack_start (*vbox, false, false);
1590 options.pack_start (*hbox, false, false);
1593 l = manage (new Label);
1594 l->set_markup (_("<b>Mapping</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 (channel_combo, false, false);
1601 hbox = manage (new HBox);
1602 hbox->pack_start (*vbox, false, false);
1603 options.pack_start (*hbox, false, false);
1606 str.push_back (_("one track per file"));
1607 set_popdown_strings (channel_combo, str);
1608 channel_combo.set_active_text (str.front());
1609 channel_combo.set_sensitive (false);
1611 l = manage (new Label);
1612 l->set_markup (_("<b>Conversion quality</b>"));
1614 vbox = manage (new VBox);
1615 vbox->set_border_width (12);
1616 vbox->set_spacing (6);
1617 vbox->pack_start (*l, false, false);
1618 vbox->pack_start (src_combo, false, false);
1619 hbox = manage (new HBox);
1620 hbox->pack_start (*vbox, false, false);
1621 options.pack_start (*hbox, false, false);
1624 str.push_back (_("Best"));
1625 str.push_back (_("Good"));
1626 str.push_back (_("Quick"));
1627 str.push_back (_("Fast"));
1628 str.push_back (_("Fastest"));
1630 set_popdown_strings (src_combo, str);
1631 src_combo.set_active_text (str.front());
1632 src_combo.set_sensitive (false);
1636 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1637 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1639 copy_files_btn.set_active (true);
1641 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1644 copy_label->set_size_request (175, -1);
1645 copy_label->set_line_wrap (true);
1648 block_four.pack_start (copy_files_btn, false, false);
1650 options.pack_start (block_four, false, false);
1652 vpacker.pack_start (options, false, false);
1654 /* setup disposition map */
1656 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1657 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1658 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1659 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1661 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1662 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1663 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1664 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1666 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1668 /* set size requests for a couple of combos to allow them to display the longest text
1669 they will ever be asked to display. This prevents them being resized when the user
1670 selects a file to import, which in turn prevents the size of the dialog from jumping
1674 t.push_back (_("one track per file"));
1675 t.push_back (_("one track per channel"));
1676 t.push_back (_("sequence files"));
1677 t.push_back (_("all files in one region"));
1678 set_popdown_strings (channel_combo, t);
1681 t.push_back (importmode2string (ImportAsTrack));
1682 t.push_back (importmode2string (ImportToTrack));
1683 t.push_back (importmode2string (ImportAsRegion));
1684 t.push_back (importmode2string (ImportAsTapeTrack));
1685 set_popdown_strings (action_combo, t);
1689 SoundFileOmega::set_mode (ImportMode mode)
1691 action_combo.set_active_text (importmode2string (mode));
1695 SoundFileOmega::get_mode () const
1697 return string2importmode (action_combo.get_active_text());
1701 SoundFileOmega::on_hide ()
1703 ArdourWindow::on_hide();
1705 _session->cancel_audition();
1710 SoundFileOmega::get_position() const
1712 string str = where_combo.get_active_text();
1714 if (str == _("file timestamp")) {
1715 return ImportAtTimestamp;
1716 } else if (str == _("edit point")) {
1717 return ImportAtEditPoint;
1718 } else if (str == _("playhead")) {
1719 return ImportAtPlayhead;
1721 return ImportAtStart;
1726 SoundFileOmega::get_src_quality() const
1728 string str = src_combo.get_active_text();
1730 if (str == _("Best")) {
1732 } else if (str == _("Good")) {
1734 } else if (str == _("Quick")) {
1736 } else if (str == _("Fast")) {
1744 SoundFileOmega::get_channel_disposition () const
1746 /* we use a map here because the channel combo can contain different strings
1747 depending on the state of the other combos. the map contains all possible strings
1748 and the ImportDisposition enum that corresponds to it.
1751 string str = channel_combo.get_active_text();
1752 DispositionMap::const_iterator x = disposition_map.find (str);
1754 if (x == disposition_map.end()) {
1755 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1763 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1765 selected_audio_track_cnt = selected_audio_tracks;
1766 selected_midi_track_cnt = selected_midi_tracks;
1768 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1769 chooser.set_filter (midi_filter);
1770 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1771 chooser.set_filter (audio_filter);
1773 chooser.set_filter (audio_and_midi_filter);
1780 SoundFileOmega::file_selection_changed ()
1782 if (resetting_ourselves) {
1786 if (!reset_options ()) {
1787 set_action_sensitive (false);
1789 if (chooser.get_filenames().size() > 0) {
1790 set_action_sensitive (true);
1792 set_action_sensitive (false);
1798 SoundFileOmega::do_something (int action)
1800 SoundFileBrowser::do_something (action);
1802 if (action == RESPONSE_CANCEL) {
1809 vector<string> paths = get_paths ();
1810 ImportPosition pos = get_position ();
1811 ImportMode mode = get_mode ();
1812 ImportDisposition chns = get_channel_disposition ();
1816 case ImportAtEditPoint:
1817 where = PublicEditor::instance().get_preferred_edit_position ();
1819 case ImportAtTimestamp:
1822 case ImportAtPlayhead:
1823 where = _session->transport_frame();
1826 where = _session->current_start_frame();
1830 SrcQuality quality = get_src_quality();
1832 if (copy_files_btn.get_active()) {
1833 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1835 PublicEditor::instance().do_embed (paths, chns, mode, where);
1838 if (action == RESPONSE_OK) {