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"
68 #include "sfdb_freesound_mootcher.h"
73 using namespace ARDOUR;
77 using namespace Gtkmm2ext;
78 using namespace Editing;
82 string SoundFileBrowser::persistent_folder;
83 typedef TreeView::Selection::ListHandle_Path ListPath;
86 string2importmode (string str)
88 if (str == _("as new tracks")) {
90 } else if (str == _("to selected tracks")) {
92 } else if (str == _("to region list")) {
93 return ImportAsRegion;
94 } else if (str == _("as new tape tracks")) {
95 return ImportAsTapeTrack;
98 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
100 return ImportAsTrack;
104 importmode2string (ImportMode mode)
108 return _("as new tracks");
110 return _("to selected tracks");
112 return _("to region list");
113 case ImportAsTapeTrack:
114 return _("as new tape tracks");
117 return _("as new tracks");
120 SoundFileBox::SoundFileBox (bool persistent)
122 length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
123 timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
125 autoplay_btn (_("Auto-play"))
128 set_name (X_("SoundFileBox"));
129 set_size_request (300, -1);
131 preview_label.set_markup (_("<b>Sound File Information</b>"));
133 border_frame.set_label_widget (preview_label);
134 border_frame.add (main_box);
136 pack_start (border_frame, true, true);
137 set_border_width (6);
139 main_box.set_border_width (6);
141 length.set_text (_("Length:"));
142 length.set_alignment (1, 0.5);
143 timecode.set_text (_("Timestamp:"));
144 timecode.set_alignment (1, 0.5);
145 format.set_text (_("Format:"));
146 format.set_alignment (1, 0.5);
147 channels.set_text (_("Channels:"));
148 channels.set_alignment (1, 0.5);
149 samplerate.set_text (_("Sample rate:"));
150 samplerate.set_alignment (1, 0.5);
152 preview_label.set_max_width_chars (50);
153 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
155 format_text.set_max_width_chars (20);
156 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
157 format_text.set_alignment (0, 1);
159 table.set_col_spacings (6);
160 table.set_homogeneous (false);
161 table.set_row_spacings (6);
163 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
164 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
165 table.attach (format, 0, 1, 2, 4, FILL, FILL);
166 table.attach (length, 0, 1, 4, 5, FILL, FILL);
167 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
169 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
170 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
171 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
172 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
173 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
175 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
176 timecode_clock.set_mode (AudioClock::Timecode);
178 main_box.pack_start (table, false, false);
180 tags_entry.set_editable (true);
181 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
182 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
184 Label* label = manage (new Label (_("Tags:")));
185 label->set_alignment (0.0f, 0.5f);
186 main_box.pack_start (*label, false, false);
187 main_box.pack_start (tags_entry, true, true);
189 main_box.pack_start (bottom_box, false, false);
191 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
192 // play_btn.set_label (_("Play"));
194 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
195 // stop_btn.set_label (_("Stop"));
197 bottom_box.set_homogeneous (false);
198 bottom_box.set_spacing (6);
199 bottom_box.pack_start(play_btn, true, true);
200 bottom_box.pack_start(stop_btn, true, true);
201 bottom_box.pack_start(autoplay_btn, false, false);
203 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
204 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
206 channels_value.set_alignment (0.0f, 0.5f);
207 samplerate_value.set_alignment (0.0f, 0.5f);
211 SoundFileBox::set_session(Session* s)
213 SessionHandlePtr::set_session (s);
215 length_clock.set_session (s);
216 timecode_clock.set_session (s);
219 play_btn.set_sensitive (false);
220 stop_btn.set_sensitive (false);
225 SoundFileBox::setup_labels (const string& filename)
228 // save existing tags
236 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
238 preview_label.set_markup (_("<b>Sound File Information</b>"));
239 format_text.set_text ("");
240 channels_value.set_text ("");
241 samplerate_value.set_text ("");
242 tags_entry.get_buffer()->set_text ("");
244 length_clock.set (0);
245 timecode_clock.set (0);
247 tags_entry.set_sensitive (false);
248 play_btn.set_sensitive (false);
253 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
254 std::string n = sf_info.format_name;
255 if (n.substr (0, 8) == X_("Format: ")) {
258 format_text.set_text (n);
259 channels_value.set_text (to_string (sf_info.channels, std::dec));
261 if (_session && sf_info.samplerate != _session->frame_rate()) {
262 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
263 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
264 samplerate_value.set_name ("NewSessionSR1Label");
265 samplerate.set_name ("NewSessionSR1Label");
267 samplerate.set_text (_("Sample rate:"));
268 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
269 samplerate_value.set_name ("NewSessionSR2Label");
270 samplerate.set_name ("NewSessionSR2Label");
273 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
274 double src_coef = (double) nfr / sf_info.samplerate;
276 length_clock.set (sf_info.length * src_coef + 0.5, true);
277 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
279 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
281 vector<string> tags = Library->get_tags (string ("//") + filename);
283 stringstream tag_string;
284 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
285 if (i != tags.begin()) {
290 tags_entry.get_buffer()->set_text (tag_string.str());
292 tags_entry.set_sensitive (true);
294 play_btn.set_sensitive (true);
301 SoundFileBox::autoplay() const
303 return autoplay_btn.get_active();
307 SoundFileBox::audition_oneshot()
314 SoundFileBox::audition ()
320 if (SMFSource::safe_midi_file_extension (path)) {
321 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
325 _session->cancel_audition();
327 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
328 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
332 boost::shared_ptr<Region> r;
334 boost::shared_ptr<AudioFileSource> afs;
335 bool old_sbp = AudioSource::get_build_peakfiles ();
337 /* don't even think of building peakfiles for these files */
339 AudioSource::set_build_peakfiles (false);
341 for (int n = 0; n < sf_info.channels; ++n) {
343 afs = boost::dynamic_pointer_cast<AudioFileSource> (
344 SourceFactory::createExternal (DataType::AUDIO, *_session,
345 path, n, Source::Flag (0), false));
347 srclist.push_back(afs);
349 } catch (failed_constructor& err) {
350 error << _("Could not access soundfile: ") << path << endmsg;
351 AudioSource::set_build_peakfiles (old_sbp);
356 AudioSource::set_build_peakfiles (old_sbp);
358 if (srclist.empty()) {
362 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
363 string rname = region_name_from_path (afs->path(), false);
367 plist.add (ARDOUR::Properties::start, 0);
368 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
369 plist.add (ARDOUR::Properties::name, rname);
370 plist.add (ARDOUR::Properties::layer, 0);
372 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
374 _session->audition_region(r);
378 SoundFileBox::stop_audition ()
381 _session->cancel_audition();
386 SoundFileBox::tags_entry_left (GdkEventFocus *)
393 SoundFileBox::tags_changed ()
395 string tag_string = tags_entry.get_buffer()->get_text ();
397 if (tag_string.empty()) {
403 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
404 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
412 SoundFileBox::save_tags (const vector<string>& tags)
414 Library->set_tags (string ("//") + path, tags);
415 Library->save_changes ();
418 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
419 : ArdourWindow (title)
420 , found_list (ListStore::create(found_list_columns))
421 , freesound_list (ListStore::create(freesound_list_columns))
422 , chooser (FILE_CHOOSER_ACTION_OPEN)
423 , preview (persistent)
424 , found_search_btn (_("Search"))
425 , found_list_view (found_list)
426 , freesound_search_btn (_("Search"))
427 , freesound_list_view (freesound_list)
428 , resetting_ourselves (false)
432 , ok_button (Stock::OK)
433 , cancel_button (Stock::CANCEL)
434 , apply_button (Stock::APPLY)
439 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
440 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
441 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
442 chooser.add_shortcut_folder_uri("file:///Volumes");
445 //add the file chooser
447 chooser.set_border_width (12);
449 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
450 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
452 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
453 audio_filter.set_name (_("Audio files"));
455 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
456 midi_filter.set_name (_("MIDI files"));
458 matchall_filter.add_pattern ("*.*");
459 matchall_filter.set_name (_("All files"));
461 chooser.add_filter (audio_and_midi_filter);
462 chooser.add_filter (audio_filter);
463 chooser.add_filter (midi_filter);
464 chooser.add_filter (matchall_filter);
465 chooser.set_select_multiple (true);
466 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
467 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
470 /* some broken redraw behaviour - this is a bandaid */
471 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
474 if (!persistent_folder.empty()) {
475 chooser.set_current_folder (persistent_folder);
478 notebook.append_page (chooser, _("Browse Files"));
480 hpacker.set_spacing (6);
481 hpacker.pack_start (notebook, true, true);
482 hpacker.pack_start (preview, false, false);
484 vpacker.set_spacing (6);
485 vpacker.pack_start (hpacker, true, true);
495 hbox = manage(new HBox);
496 hbox->pack_start (found_entry);
497 hbox->pack_start (found_search_btn);
499 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
500 scroll->add(found_list_view);
501 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
503 vbox = manage(new VBox);
504 vbox->pack_start (*hbox, PACK_SHRINK);
505 vbox->pack_start (*scroll);
507 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
509 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
511 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
513 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
514 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
516 notebook.append_page (*vbox, _("Search Tags"));
520 //add freesound search
525 passbox = manage(new HBox);
526 passbox->set_spacing (6);
528 label = manage (new Label);
529 label->set_text (_("Tags:"));
530 passbox->pack_start (*label, false, false);
531 passbox->pack_start (freesound_entry, true, true);
533 label = manage (new Label);
534 label->set_text (_("Sort:"));
535 passbox->pack_start (*label, false, false);
536 passbox->pack_start (freesound_sort, false, false);
537 freesound_sort.clear_items();
539 // Order of the following must correspond with enum sortMethod
540 // in sfdb_freesound_mootcher.h
541 freesound_sort.append_text(_("None"));
542 freesound_sort.append_text(_("Longest"));
543 freesound_sort.append_text(_("Shortest"));
544 freesound_sort.append_text(_("Newest"));
545 freesound_sort.append_text(_("Oldest"));
546 freesound_sort.append_text(_("Most downloaded"));
547 freesound_sort.append_text(_("Least downloaded"));
548 freesound_sort.append_text(_("Highest rated"));
549 freesound_sort.append_text(_("Lowest rated"));
550 freesound_sort.set_active(0);
552 passbox->pack_start (freesound_search_btn, false, false);
553 passbox->pack_start (freesound_more_btn, false, false);
554 freesound_more_btn.set_label(_("More"));
555 freesound_more_btn.set_sensitive(false);
557 passbox->pack_start (freesound_similar_btn, false, false);
558 freesound_similar_btn.set_label(_("Similar"));
559 freesound_similar_btn.set_sensitive(false);
561 scroll = manage(new ScrolledWindow);
562 scroll->add(freesound_list_view);
563 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
565 vbox = manage(new VBox);
566 vbox->set_spacing (3);
567 vbox->pack_start (*passbox, PACK_SHRINK);
568 vbox->pack_start (*scroll);
570 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
571 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
572 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
573 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
574 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
575 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
576 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
577 freesound_list_view.get_column(0)->set_alignment(0.5);
578 freesound_list_view.get_column(1)->set_expand(true); // filename
579 freesound_list_view.get_column(1)->set_resizable(true); // filename
580 freesound_list_view.get_column(2)->set_alignment(0.5);
581 freesound_list_view.get_column(3)->set_alignment(0.5);
582 freesound_list_view.get_column(4)->set_alignment(0.5);
583 freesound_list_view.get_column(5)->set_alignment(0.5);
585 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
586 freesound_list_view.set_tooltip_column(1);
588 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
589 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
590 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
591 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
592 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
593 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
594 notebook.append_page (*vbox, _("Search Freesound"));
597 notebook.set_size_request (500, -1);
598 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
602 Gtk::HButtonBox* button_box = manage (new HButtonBox);
604 button_box->set_layout (BUTTONBOX_END);
605 button_box->pack_start (cancel_button, false, false);
606 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
608 button_box->pack_start (apply_button, false, false);
609 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
612 button_box->pack_start (ok_button, false, false);
613 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
615 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
616 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
617 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
619 vpacker.pack_end (*button_box, false, false);
621 set_wmclass (X_("import"), PROGRAM_NAME);
624 SoundFileBrowser::~SoundFileBrowser ()
626 persistent_folder = chooser.get_current_folder();
630 SoundFileBrowser::run ()
639 gtk_main_iteration ();
646 SoundFileBrowser::set_action_sensitive (bool yn)
648 ok_button.set_sensitive (yn);
649 apply_button.set_sensitive (yn);
653 SoundFileBrowser::do_something (int action)
660 SoundFileBrowser::on_show ()
662 ArdourWindow::on_show ();
667 SoundFileBrowser::clear_selection ()
669 chooser.unselect_all ();
670 found_list_view.get_selection()->unselect_all ();
674 SoundFileBrowser::chooser_file_activated ()
680 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
686 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
692 SoundFileBrowser::set_session (Session* s)
694 ArdourWindow::set_session (s);
695 preview.set_session (s);
700 remove_gain_meter ();
705 SoundFileBrowser::add_gain_meter ()
709 gm = new GainMeter (_session, 250);
711 boost::shared_ptr<Route> r = _session->the_auditioner ();
713 gm->set_controls (r, r->shared_peak_meter(), r->amp());
714 gm->set_fader_name (X_("AudioTrackFader"));
716 meter_packer.set_border_width (12);
717 meter_packer.pack_start (*gm, false, true);
718 hpacker.pack_end (meter_packer, false, false);
719 meter_packer.show_all ();
724 SoundFileBrowser::remove_gain_meter ()
727 meter_packer.remove (*gm);
728 hpacker.remove (meter_packer);
735 SoundFileBrowser::start_metering ()
737 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
741 SoundFileBrowser::stop_metering ()
743 metering_connection.disconnect();
747 SoundFileBrowser::meter ()
749 if (is_mapped () && _session && gm) {
750 gm->update_meters ();
755 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
757 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
761 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
763 return SMFSource::safe_midi_file_extension (filter_info.filename);
767 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
769 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
773 SoundFileBrowser::update_preview ()
775 if (preview.setup_labels (chooser.get_preview_filename())) {
776 if (preview.autoplay()) {
777 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
783 SoundFileBrowser::found_list_view_selected ()
785 if (!reset_options ()) {
786 set_action_sensitive (false);
790 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
793 TreeIter iter = found_list->get_iter(*rows.begin());
794 file = (*iter)[found_list_columns.pathname];
795 chooser.set_filename (file);
796 set_action_sensitive (true);
798 set_action_sensitive (false);
801 preview.setup_labels (file);
806 SoundFileBrowser::found_search_clicked ()
808 string tag_string = found_entry.get_text ();
812 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
813 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
817 vector<string> results;
818 Library->search_members_and (results, tags);
821 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
822 TreeModel::iterator new_row = found_list->append();
823 TreeModel::Row row = *new_row;
824 string path = Glib::filename_from_uri (string ("file:") + *i);
825 row[found_list_columns.pathname] = path;
831 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
834 Mootcher *mootcher = new Mootcher;
837 string id = (*iter)[freesound_list_columns.id];
838 string uri = (*iter)[freesound_list_columns.uri];
839 string ofn = (*iter)[freesound_list_columns.filename];
841 if (mootcher->checkAudioFile(ofn, id)) {
842 // file already exists, no need to download it again
843 file = mootcher->audioFileName;
845 (*iter)[freesound_list_columns.started] = false;
848 if (!(*iter)[freesound_list_columns.started]) {
849 // start downloading the sound file
850 (*iter)[freesound_list_columns.started] = true;
851 mootcher->fetchAudioFile(ofn, id, uri, this);
857 SoundFileBrowser::freesound_list_view_selected ()
860 if (!reset_options ()) {
861 set_action_sensitive (false);
864 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
865 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
866 file = freesound_get_audio_file (freesound_list->get_iter(*i));
869 switch (rows.size()) {
872 freesound_similar_btn.set_sensitive(false);
873 set_action_sensitive (false);
876 // exactly one item selected
878 // file exists on disk already
879 chooser.set_filename (file);
880 preview.setup_labels (file);
881 set_action_sensitive (true);
883 freesound_similar_btn.set_sensitive(true);
886 // multiple items selected
887 preview.setup_labels ("");
888 freesound_similar_btn.set_sensitive(false);
896 SoundFileBrowser::refresh_display(std::string ID, std::string file)
898 // called when the mootcher has finished downloading a file
899 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
900 if (rows.size() == 1) {
901 // there's a single item selected in the freesound list
902 //XXX make a function to be used to construct the actual file name both here and in the mootcher
903 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
904 std::string selected_ID = (*row)[freesound_list_columns.id];
905 if (ID == selected_ID) {
906 // the selected item in the freesound list is the item that has just finished downloading
907 chooser.set_filename(file);
908 preview.setup_labels (file);
909 set_action_sensitive (true);
915 SoundFileBrowser::freesound_search_clicked ()
918 freesound_list->clear();
924 SoundFileBrowser::freesound_more_clicked ()
929 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
930 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
934 SoundFileBrowser::freesound_similar_clicked ()
936 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
937 if (rows.size() == 1) {
940 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
941 id = (*iter)[freesound_list_columns.id];
942 freesound_list->clear();
944 GdkCursor *prev_cursor;
945 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
946 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
949 std::string theString = mootcher.searchSimilar(id);
951 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
952 handle_freesound_results(theString);
957 SoundFileBrowser::freesound_search()
961 string search_string = freesound_entry.get_text ();
962 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
964 GdkCursor *prev_cursor;
965 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
966 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
969 std::string theString = mootcher.searchText(
973 "", // OSX eats anything incl mp3
975 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
980 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
981 handle_freesound_results(theString);
985 SoundFileBrowser::handle_freesound_results(std::string theString) {
987 doc.read_buffer( theString );
988 XMLNode *root = doc.root();
991 error << "no root XML node!" << endmsg;
995 if ( strcmp(root->name().c_str(), "response") != 0) {
996 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1000 // find out how many pages are available to search
1001 int freesound_n_pages = 1;
1002 XMLNode *res = root->child("num_pages");
1004 string result = res->child("text")->content();
1005 freesound_n_pages = atoi(result);
1008 int more_pages = freesound_n_pages - freesound_page;
1010 if (more_pages > 0) {
1011 freesound_more_btn.set_sensitive(true);
1012 freesound_more_btn.set_tooltip_text(string_compose(P_(
1013 "%1 more page of 100 results available",
1014 "%1 more pages of 100 results available",
1015 more_pages), more_pages));
1017 freesound_more_btn.set_sensitive(false);
1018 freesound_more_btn.set_tooltip_text(_("No more results available"));
1021 XMLNode *sounds_root = root->child("sounds");
1023 error << "no child node \"sounds\" found!" << endmsg;
1027 XMLNodeList sounds = sounds_root->children();
1028 if (sounds.size() == 0) {
1033 XMLNodeConstIterator niter;
1035 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1037 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1038 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1042 // node->dump(cerr, "node:");
1045 XMLNode *id_node = node->child ("id");
1046 XMLNode *uri_node = node->child ("serve");
1047 XMLNode *ofn_node = node->child ("original_filename");
1048 XMLNode *dur_node = node->child ("duration");
1049 XMLNode *siz_node = node->child ("filesize");
1050 XMLNode *srt_node = node->child ("samplerate");
1051 XMLNode *lic_node = node->child ("license");
1053 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1055 std::string id = id_node->child("text")->content();
1056 std::string uri = uri_node->child("text")->content();
1057 std::string ofn = ofn_node->child("text")->content();
1058 std::string dur = dur_node->child("text")->content();
1059 std::string siz = siz_node->child("text")->content();
1060 std::string srt = srt_node->child("text")->content();
1061 std::string lic = lic_node->child("text")->content();
1064 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1066 double duration_seconds = atof(dur);
1068 char duration_hhmmss[16];
1069 if (duration_seconds >= 99 * 60 * 60) {
1070 strcpy(duration_hhmmss, ">99h");
1072 s = modf(duration_seconds/60, &m) * 60;
1073 m = modf(m/60, &h) * 60;
1074 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1079 double size_bytes = atof(siz);
1081 if (size_bytes < 1000) {
1082 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1083 } else if (size_bytes < 1000000 ) {
1084 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1085 } else if (size_bytes < 10000000) {
1086 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1087 } else if (size_bytes < 1000000000) {
1088 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1090 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1093 /* see http://www.freesound.org/help/faq/#licenses */
1094 char shortlicense[64];
1095 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1096 sprintf(shortlicense, "CC-BY-NC");
1097 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1098 sprintf(shortlicense, "CC-BY");
1099 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1100 sprintf(shortlicense, "sampling+");
1101 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1102 sprintf(shortlicense, "PD");
1104 snprintf(shortlicense, 64, "%s", lic.c_str());
1105 shortlicense[63]= '\0';
1108 TreeModel::iterator new_row = freesound_list->append();
1109 TreeModel::Row row = *new_row;
1111 row[freesound_list_columns.id ] = id;
1112 row[freesound_list_columns.uri ] = uri;
1113 row[freesound_list_columns.filename] = ofn;
1114 row[freesound_list_columns.duration] = duration_hhmmss;
1115 row[freesound_list_columns.filesize] = bsize;
1116 row[freesound_list_columns.smplrate] = srt;
1117 row[freesound_list_columns.license ] = shortlicense;
1124 SoundFileBrowser::get_paths ()
1126 vector<string> results;
1128 int n = notebook.get_current_page ();
1131 vector<string> filenames = chooser.get_filenames();
1132 vector<string>::iterator i;
1134 for (i = filenames.begin(); i != filenames.end(); ++i) {
1136 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1137 results.push_back (*i);
1141 } else if (n == 1) {
1143 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1144 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1145 TreeIter iter = found_list->get_iter(*i);
1146 string str = (*iter)[found_list_columns.pathname];
1148 results.push_back (str);
1152 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1153 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1154 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1156 results.push_back (str);
1166 SoundFileOmega::reset_options_noret ()
1168 if (!resetting_ourselves) {
1169 (void) reset_options ();
1174 SoundFileOmega::reset_options ()
1176 vector<string> paths = get_paths ();
1178 if (paths.empty()) {
1180 channel_combo.set_sensitive (false);
1181 action_combo.set_sensitive (false);
1182 where_combo.set_sensitive (false);
1183 copy_files_btn.set_active (true);
1184 copy_files_btn.set_sensitive (false);
1190 channel_combo.set_sensitive (true);
1191 action_combo.set_sensitive (true);
1192 where_combo.set_sensitive (true);
1194 /* if we get through this function successfully, this may be
1195 reset at the end, once we know if we can use hard links
1196 to do embedding (or if we are importing a MIDI file).
1199 if (Config->get_only_copy_imported_files()) {
1200 copy_files_btn.set_sensitive (false);
1202 copy_files_btn.set_sensitive (false);
1208 bool selection_includes_multichannel;
1209 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1212 /* See if we are thinking about importing any MIDI files */
1213 vector<string>::iterator i = paths.begin ();
1214 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1217 bool const have_a_midi_file = (i != paths.end ());
1219 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1220 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1224 string existing_choice;
1225 vector<string> action_strings;
1227 resetting_ourselves = true;
1229 if (chooser.get_filter() == &audio_filter) {
1233 if (selected_audio_track_cnt > 0) {
1234 if (channel_combo.get_active_text().length()) {
1235 ImportDisposition id = get_channel_disposition();
1238 case Editing::ImportDistinctFiles:
1239 if (selected_audio_track_cnt == paths.size()) {
1240 action_strings.push_back (importmode2string (ImportToTrack));
1244 case Editing::ImportDistinctChannels:
1245 /* XXX it would be nice to allow channel-per-selected track
1246 but its too hard we don't want to deal with all the
1247 different per-file + per-track channel configurations.
1252 action_strings.push_back (importmode2string (ImportToTrack));
1262 if (selected_midi_track_cnt > 0) {
1263 action_strings.push_back (importmode2string (ImportToTrack));
1267 action_strings.push_back (importmode2string (ImportAsTrack));
1268 action_strings.push_back (importmode2string (ImportAsRegion));
1269 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1271 existing_choice = action_combo.get_active_text();
1273 set_popdown_strings (action_combo, action_strings);
1275 /* preserve any existing choice, if possible */
1278 if (existing_choice.length()) {
1279 vector<string>::iterator x;
1280 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1281 if (*x == existing_choice) {
1282 action_combo.set_active_text (existing_choice);
1286 if (x == action_strings.end()) {
1287 action_combo.set_active_text (action_strings.front());
1290 action_combo.set_active_text (action_strings.front());
1293 resetting_ourselves = false;
1295 if ((mode = get_mode()) == ImportAsRegion) {
1296 where_combo.set_sensitive (false);
1298 where_combo.set_sensitive (true);
1301 vector<string> channel_strings;
1303 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1304 channel_strings.push_back (_("one track per file"));
1306 if (selection_includes_multichannel) {
1307 channel_strings.push_back (_("one track per channel"));
1310 if (paths.size() > 1) {
1311 /* tape tracks are a single region per track, so we cannot
1312 sequence multiple files.
1314 if (mode != ImportAsTapeTrack) {
1315 channel_strings.push_back (_("sequence files"));
1318 channel_strings.push_back (_("all files in one track"));
1319 channel_strings.push_back (_("merge files"));
1325 channel_strings.push_back (_("one region per file"));
1327 if (selection_includes_multichannel) {
1328 channel_strings.push_back (_("one region per channel"));
1331 if (paths.size() > 1) {
1333 channel_strings.push_back (_("all files in one region"));
1338 resetting_ourselves = true;
1340 existing_choice = channel_combo.get_active_text();
1342 set_popdown_strings (channel_combo, channel_strings);
1344 /* preserve any existing choice, if possible */
1346 if (existing_choice.length()) {
1347 vector<string>::iterator x;
1348 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1349 if (*x == existing_choice) {
1350 channel_combo.set_active_text (existing_choice);
1354 if (x == channel_strings.end()) {
1355 channel_combo.set_active_text (channel_strings.front());
1358 channel_combo.set_active_text (channel_strings.front());
1361 resetting_ourselves = false;
1364 src_combo.set_sensitive (true);
1366 src_combo.set_sensitive (false);
1369 /* We must copy MIDI files or those from Freesound
1370 * or any file if we are under nsm control */
1371 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1373 if (Config->get_only_copy_imported_files()) {
1375 if (selection_can_be_embedded_with_links && !must_copy) {
1376 copy_files_btn.set_sensitive (true);
1379 copy_files_btn.set_active (true);
1381 copy_files_btn.set_sensitive (false);
1387 copy_files_btn.set_active (true);
1389 copy_files_btn.set_sensitive (!must_copy);
1397 SoundFileOmega::bad_file_message()
1399 MessageDialog msg (*this,
1400 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1405 resetting_ourselves = true;
1406 chooser.unselect_uri (chooser.get_preview_uri());
1407 resetting_ourselves = false;
1413 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1422 multichannel = false;
1424 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1426 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1427 if (info.channels > 1) {
1428 multichannel = true;
1433 if (sz != info.length) {
1438 if (info.samplerate != _session->frame_rate()) {
1442 } else if (SMFSource::safe_midi_file_extension (*i)) {
1446 if (reader.num_tracks() > 1) {
1447 multichannel = true; // "channel" == track here...
1450 /* XXX we need err = true handling here in case
1451 we can't check the file
1464 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1466 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1469 if (mkdir (tmpdir.c_str(), 0744)) {
1470 if (errno != EEXIST) {
1475 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1477 char tmpc[MAXPATHLEN+1];
1479 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1483 if (link ((*i).c_str(), tmpc)) {
1493 rmdir (tmpdir.c_str());
1497 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1498 : SoundFileBrowser (title, s, false)
1500 chooser.set_select_multiple (false);
1501 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1502 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1506 SoundFileChooser::on_hide ()
1508 ArdourWindow::on_hide();
1512 _session->cancel_audition();
1517 SoundFileChooser::get_filename ()
1519 vector<string> paths;
1521 paths = get_paths ();
1523 if (paths.empty()) {
1527 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1531 return paths.front();
1534 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1535 uint32_t selected_audio_tracks,
1536 uint32_t selected_midi_tracks,
1538 Editing::ImportMode mode_hint)
1539 : SoundFileBrowser (title, s, persistent)
1540 , copy_files_btn ( _("Copy files to session"))
1541 , selected_audio_track_cnt (selected_audio_tracks)
1542 , selected_midi_track_cnt (selected_midi_tracks)
1548 set_size_request (-1, 450);
1550 block_two.set_border_width (12);
1551 block_three.set_border_width (12);
1552 block_four.set_border_width (12);
1554 options.set_spacing (12);
1557 str.push_back (_("file timestamp"));
1558 str.push_back (_("edit point"));
1559 str.push_back (_("playhead"));
1560 str.push_back (_("session start"));
1561 set_popdown_strings (where_combo, str);
1562 where_combo.set_active_text (str.front());
1564 Label* l = manage (new Label);
1565 l->set_markup (_("<b>Add files as ...</b>"));
1567 vbox = manage (new VBox);
1568 vbox->set_border_width (12);
1569 vbox->set_spacing (6);
1570 vbox->pack_start (*l, false, false);
1571 vbox->pack_start (action_combo, false, false);
1572 hbox = manage (new HBox);
1573 hbox->pack_start (*vbox, false, false);
1574 options.pack_start (*hbox, false, false);
1576 /* dummy entry for action combo so that it doesn't look odd if we
1577 come up with no tracks selected.
1581 str.push_back (importmode2string (mode_hint));
1582 set_popdown_strings (action_combo, str);
1583 action_combo.set_active_text (str.front());
1584 action_combo.set_sensitive (false);
1586 l = manage (new Label);
1587 l->set_markup (_("<b>Insert at</b>"));
1589 vbox = manage (new VBox);
1590 vbox->set_border_width (12);
1591 vbox->set_spacing (6);
1592 vbox->pack_start (*l, false, false);
1593 vbox->pack_start (where_combo, false, false);
1594 hbox = manage (new HBox);
1595 hbox->pack_start (*vbox, false, false);
1596 options.pack_start (*hbox, false, false);
1599 l = manage (new Label);
1600 l->set_markup (_("<b>Mapping</b>"));
1602 vbox = manage (new VBox);
1603 vbox->set_border_width (12);
1604 vbox->set_spacing (6);
1605 vbox->pack_start (*l, false, false);
1606 vbox->pack_start (channel_combo, false, false);
1607 hbox = manage (new HBox);
1608 hbox->pack_start (*vbox, false, false);
1609 options.pack_start (*hbox, false, false);
1612 str.push_back (_("one track per file"));
1613 set_popdown_strings (channel_combo, str);
1614 channel_combo.set_active_text (str.front());
1615 channel_combo.set_sensitive (false);
1617 l = manage (new Label);
1618 l->set_markup (_("<b>Conversion quality</b>"));
1620 vbox = manage (new VBox);
1621 vbox->set_border_width (12);
1622 vbox->set_spacing (6);
1623 vbox->pack_start (*l, false, false);
1624 vbox->pack_start (src_combo, false, false);
1625 hbox = manage (new HBox);
1626 hbox->pack_start (*vbox, false, false);
1627 options.pack_start (*hbox, false, false);
1630 str.push_back (_("Best"));
1631 str.push_back (_("Good"));
1632 str.push_back (_("Quick"));
1633 str.push_back (_("Fast"));
1634 str.push_back (_("Fastest"));
1636 set_popdown_strings (src_combo, str);
1637 src_combo.set_active_text (str.front());
1638 src_combo.set_sensitive (false);
1642 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1643 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1645 copy_files_btn.set_active (true);
1647 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1650 copy_label->set_size_request (175, -1);
1651 copy_label->set_line_wrap (true);
1654 block_four.pack_start (copy_files_btn, false, false);
1656 options.pack_start (block_four, false, false);
1658 vpacker.pack_start (options, false, false);
1660 /* setup disposition map */
1662 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1663 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1664 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1665 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1667 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1668 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1669 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1670 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1672 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1674 /* set size requests for a couple of combos to allow them to display the longest text
1675 they will ever be asked to display. This prevents them being resized when the user
1676 selects a file to import, which in turn prevents the size of the dialog from jumping
1680 t.push_back (_("one track per file"));
1681 t.push_back (_("one track per channel"));
1682 t.push_back (_("sequence files"));
1683 t.push_back (_("all files in one region"));
1684 set_popdown_strings (channel_combo, t);
1687 t.push_back (importmode2string (ImportAsTrack));
1688 t.push_back (importmode2string (ImportToTrack));
1689 t.push_back (importmode2string (ImportAsRegion));
1690 t.push_back (importmode2string (ImportAsTapeTrack));
1691 set_popdown_strings (action_combo, t);
1695 SoundFileOmega::set_mode (ImportMode mode)
1697 action_combo.set_active_text (importmode2string (mode));
1701 SoundFileOmega::get_mode () const
1703 return string2importmode (action_combo.get_active_text());
1707 SoundFileOmega::on_hide ()
1709 ArdourWindow::on_hide();
1711 _session->cancel_audition();
1716 SoundFileOmega::get_position() const
1718 string str = where_combo.get_active_text();
1720 if (str == _("file timestamp")) {
1721 return ImportAtTimestamp;
1722 } else if (str == _("edit point")) {
1723 return ImportAtEditPoint;
1724 } else if (str == _("playhead")) {
1725 return ImportAtPlayhead;
1727 return ImportAtStart;
1732 SoundFileOmega::get_src_quality() const
1734 string str = src_combo.get_active_text();
1736 if (str == _("Best")) {
1738 } else if (str == _("Good")) {
1740 } else if (str == _("Quick")) {
1742 } else if (str == _("Fast")) {
1750 SoundFileOmega::get_channel_disposition () const
1752 /* we use a map here because the channel combo can contain different strings
1753 depending on the state of the other combos. the map contains all possible strings
1754 and the ImportDisposition enum that corresponds to it.
1757 string str = channel_combo.get_active_text();
1758 DispositionMap::const_iterator x = disposition_map.find (str);
1760 if (x == disposition_map.end()) {
1761 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1769 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1771 selected_audio_track_cnt = selected_audio_tracks;
1772 selected_midi_track_cnt = selected_midi_tracks;
1774 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1775 chooser.set_filter (midi_filter);
1776 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1777 chooser.set_filter (audio_filter);
1779 chooser.set_filter (audio_and_midi_filter);
1786 SoundFileOmega::file_selection_changed ()
1788 if (resetting_ourselves) {
1792 if (!reset_options ()) {
1793 set_action_sensitive (false);
1795 if (chooser.get_filenames().size() > 0) {
1796 set_action_sensitive (true);
1798 set_action_sensitive (false);
1804 SoundFileOmega::do_something (int action)
1806 SoundFileBrowser::do_something (action);
1808 if (action == RESPONSE_CANCEL) {
1815 vector<string> paths = get_paths ();
1816 ImportPosition pos = get_position ();
1817 ImportMode mode = get_mode ();
1818 ImportDisposition chns = get_channel_disposition ();
1822 case ImportAtEditPoint:
1823 where = PublicEditor::instance().get_preferred_edit_position ();
1825 case ImportAtTimestamp:
1828 case ImportAtPlayhead:
1829 where = _session->transport_frame();
1832 where = _session->current_start_frame();
1836 SrcQuality quality = get_src_quality();
1838 if (copy_files_btn.get_active()) {
1839 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1841 PublicEditor::instance().do_embed (paths, chns, mode, where);
1844 if (action == RESPONSE_OK) {