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)
1469 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1472 if (mkdir (tmpdir.c_str(), 0744)) {
1473 if (errno != EEXIST) {
1478 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1480 char tmpc[MAXPATHLEN+1];
1482 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1486 if (link ((*i).c_str(), tmpc)) {
1496 rmdir (tmpdir.c_str());
1501 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1502 : SoundFileBrowser (title, s, false)
1504 chooser.set_select_multiple (false);
1505 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1506 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1510 SoundFileChooser::on_hide ()
1512 ArdourWindow::on_hide();
1516 _session->cancel_audition();
1521 SoundFileChooser::get_filename ()
1523 vector<string> paths;
1525 paths = get_paths ();
1527 if (paths.empty()) {
1531 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1535 return paths.front();
1538 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1539 uint32_t selected_audio_tracks,
1540 uint32_t selected_midi_tracks,
1542 Editing::ImportMode mode_hint)
1543 : SoundFileBrowser (title, s, persistent)
1544 , copy_files_btn ( _("Copy files to session"))
1545 , selected_audio_track_cnt (selected_audio_tracks)
1546 , selected_midi_track_cnt (selected_midi_tracks)
1552 set_size_request (-1, 450);
1554 block_two.set_border_width (12);
1555 block_three.set_border_width (12);
1556 block_four.set_border_width (12);
1558 options.set_spacing (12);
1561 str.push_back (_("file timestamp"));
1562 str.push_back (_("edit point"));
1563 str.push_back (_("playhead"));
1564 str.push_back (_("session start"));
1565 set_popdown_strings (where_combo, str);
1566 where_combo.set_active_text (str.front());
1568 Label* l = manage (new Label);
1569 l->set_markup (_("<b>Add files as ...</b>"));
1571 vbox = manage (new VBox);
1572 vbox->set_border_width (12);
1573 vbox->set_spacing (6);
1574 vbox->pack_start (*l, false, false);
1575 vbox->pack_start (action_combo, false, false);
1576 hbox = manage (new HBox);
1577 hbox->pack_start (*vbox, false, false);
1578 options.pack_start (*hbox, false, false);
1580 /* dummy entry for action combo so that it doesn't look odd if we
1581 come up with no tracks selected.
1585 str.push_back (importmode2string (mode_hint));
1586 set_popdown_strings (action_combo, str);
1587 action_combo.set_active_text (str.front());
1588 action_combo.set_sensitive (false);
1590 l = manage (new Label);
1591 l->set_markup (_("<b>Insert at</b>"));
1593 vbox = manage (new VBox);
1594 vbox->set_border_width (12);
1595 vbox->set_spacing (6);
1596 vbox->pack_start (*l, false, false);
1597 vbox->pack_start (where_combo, false, false);
1598 hbox = manage (new HBox);
1599 hbox->pack_start (*vbox, false, false);
1600 options.pack_start (*hbox, false, false);
1603 l = manage (new Label);
1604 l->set_markup (_("<b>Mapping</b>"));
1606 vbox = manage (new VBox);
1607 vbox->set_border_width (12);
1608 vbox->set_spacing (6);
1609 vbox->pack_start (*l, false, false);
1610 vbox->pack_start (channel_combo, false, false);
1611 hbox = manage (new HBox);
1612 hbox->pack_start (*vbox, false, false);
1613 options.pack_start (*hbox, false, false);
1616 str.push_back (_("one track per file"));
1617 set_popdown_strings (channel_combo, str);
1618 channel_combo.set_active_text (str.front());
1619 channel_combo.set_sensitive (false);
1621 l = manage (new Label);
1622 l->set_markup (_("<b>Conversion quality</b>"));
1624 vbox = manage (new VBox);
1625 vbox->set_border_width (12);
1626 vbox->set_spacing (6);
1627 vbox->pack_start (*l, false, false);
1628 vbox->pack_start (src_combo, false, false);
1629 hbox = manage (new HBox);
1630 hbox->pack_start (*vbox, false, false);
1631 options.pack_start (*hbox, false, false);
1634 str.push_back (_("Best"));
1635 str.push_back (_("Good"));
1636 str.push_back (_("Quick"));
1637 str.push_back (_("Fast"));
1638 str.push_back (_("Fastest"));
1640 set_popdown_strings (src_combo, str);
1641 src_combo.set_active_text (str.front());
1642 src_combo.set_sensitive (false);
1646 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1647 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1649 copy_files_btn.set_active (true);
1651 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1654 copy_label->set_size_request (175, -1);
1655 copy_label->set_line_wrap (true);
1658 block_four.pack_start (copy_files_btn, false, false);
1660 options.pack_start (block_four, false, false);
1662 vpacker.pack_start (options, false, false);
1664 /* setup disposition map */
1666 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1667 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1668 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1669 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1671 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1672 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1673 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1674 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1676 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1678 /* set size requests for a couple of combos to allow them to display the longest text
1679 they will ever be asked to display. This prevents them being resized when the user
1680 selects a file to import, which in turn prevents the size of the dialog from jumping
1684 t.push_back (_("one track per file"));
1685 t.push_back (_("one track per channel"));
1686 t.push_back (_("sequence files"));
1687 t.push_back (_("all files in one region"));
1688 set_popdown_strings (channel_combo, t);
1691 t.push_back (importmode2string (ImportAsTrack));
1692 t.push_back (importmode2string (ImportToTrack));
1693 t.push_back (importmode2string (ImportAsRegion));
1694 t.push_back (importmode2string (ImportAsTapeTrack));
1695 set_popdown_strings (action_combo, t);
1699 SoundFileOmega::set_mode (ImportMode mode)
1701 action_combo.set_active_text (importmode2string (mode));
1705 SoundFileOmega::get_mode () const
1707 return string2importmode (action_combo.get_active_text());
1711 SoundFileOmega::on_hide ()
1713 ArdourWindow::on_hide();
1715 _session->cancel_audition();
1720 SoundFileOmega::get_position() const
1722 string str = where_combo.get_active_text();
1724 if (str == _("file timestamp")) {
1725 return ImportAtTimestamp;
1726 } else if (str == _("edit point")) {
1727 return ImportAtEditPoint;
1728 } else if (str == _("playhead")) {
1729 return ImportAtPlayhead;
1731 return ImportAtStart;
1736 SoundFileOmega::get_src_quality() const
1738 string str = src_combo.get_active_text();
1740 if (str == _("Best")) {
1742 } else if (str == _("Good")) {
1744 } else if (str == _("Quick")) {
1746 } else if (str == _("Fast")) {
1754 SoundFileOmega::get_channel_disposition () const
1756 /* we use a map here because the channel combo can contain different strings
1757 depending on the state of the other combos. the map contains all possible strings
1758 and the ImportDisposition enum that corresponds to it.
1761 string str = channel_combo.get_active_text();
1762 DispositionMap::const_iterator x = disposition_map.find (str);
1764 if (x == disposition_map.end()) {
1765 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1773 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1775 selected_audio_track_cnt = selected_audio_tracks;
1776 selected_midi_track_cnt = selected_midi_tracks;
1778 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1779 chooser.set_filter (midi_filter);
1780 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1781 chooser.set_filter (audio_filter);
1783 chooser.set_filter (audio_and_midi_filter);
1790 SoundFileOmega::file_selection_changed ()
1792 if (resetting_ourselves) {
1796 if (!reset_options ()) {
1797 set_action_sensitive (false);
1799 if (chooser.get_filenames().size() > 0) {
1800 set_action_sensitive (true);
1802 set_action_sensitive (false);
1808 SoundFileOmega::do_something (int action)
1810 SoundFileBrowser::do_something (action);
1812 if (action == RESPONSE_CANCEL) {
1819 vector<string> paths = get_paths ();
1820 ImportPosition pos = get_position ();
1821 ImportMode mode = get_mode ();
1822 ImportDisposition chns = get_channel_disposition ();
1826 case ImportAtEditPoint:
1827 where = PublicEditor::instance().get_preferred_edit_position ();
1829 case ImportAtTimestamp:
1832 case ImportAtPlayhead:
1833 where = _session->transport_frame();
1836 where = _session->current_start_frame();
1840 SrcQuality quality = get_src_quality();
1842 if (copy_files_btn.get_active()) {
1843 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1845 PublicEditor::instance().do_embed (paths, chns, mode, where);
1848 if (action == RESPONSE_OK) {