2 Copyright (C) 2005-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
30 #include <sys/param.h>
32 #include <gtkmm/box.h>
33 #include <gtkmm/stock.h>
35 #include <glib/gstdio.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/convert.h"
39 #include "pbd/tokenizer.h"
40 #include "pbd/enumwriter.h"
41 #include "pbd/pthread_utils.h"
42 #include "pbd/xml++.h"
44 #include <gtkmm2ext/utils.h>
46 #include "evoral/SMF.hpp"
48 #include "ardour/audio_library.h"
49 #include "ardour/auditioner.h"
50 #include "ardour/audioregion.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/smf_source.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/source_factory.h"
55 #include "ardour/session.h"
56 #include "ardour/session_directory.h"
58 #include "ardour_ui.h"
60 #include "gui_thread.h"
65 #include "gain_meter.h"
66 #include "main_clock.h"
67 #include "public_editor.h"
69 #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,
346 Source::Flag (0), false));
348 srclist.push_back(afs);
350 } catch (failed_constructor& err) {
351 error << _("Could not access soundfile: ") << path << endmsg;
352 AudioSource::set_build_peakfiles (old_sbp);
357 AudioSource::set_build_peakfiles (old_sbp);
359 if (srclist.empty()) {
363 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
364 string rname = region_name_from_path (afs->path(), false);
368 plist.add (ARDOUR::Properties::start, 0);
369 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
370 plist.add (ARDOUR::Properties::name, rname);
371 plist.add (ARDOUR::Properties::layer, 0);
373 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
375 _session->audition_region(r);
379 SoundFileBox::stop_audition ()
382 _session->cancel_audition();
387 SoundFileBox::tags_entry_left (GdkEventFocus *)
394 SoundFileBox::tags_changed ()
396 string tag_string = tags_entry.get_buffer()->get_text ();
398 if (tag_string.empty()) {
404 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
405 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
413 SoundFileBox::save_tags (const vector<string>& tags)
415 Library->set_tags (string ("//") + path, tags);
416 Library->save_changes ();
419 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
420 : ArdourWindow (title)
421 , found_list (ListStore::create(found_list_columns))
422 , freesound_list (ListStore::create(freesound_list_columns))
423 , chooser (FILE_CHOOSER_ACTION_OPEN)
424 , preview (persistent)
425 , found_search_btn (_("Search"))
426 , found_list_view (found_list)
427 , freesound_search_btn (_("Search"))
428 , freesound_list_view (freesound_list)
429 , resetting_ourselves (false)
433 , ok_button (Stock::OK)
434 , cancel_button (Stock::CANCEL)
435 , apply_button (Stock::APPLY)
440 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
441 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
442 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
443 chooser.add_shortcut_folder_uri("file:///Volumes");
446 //add the file chooser
448 chooser.set_border_width (12);
450 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
451 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
453 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
454 audio_filter.set_name (_("Audio files"));
456 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
457 midi_filter.set_name (_("MIDI files"));
459 matchall_filter.add_pattern ("*.*");
460 matchall_filter.set_name (_("All files"));
462 chooser.add_filter (audio_and_midi_filter);
463 chooser.add_filter (audio_filter);
464 chooser.add_filter (midi_filter);
465 chooser.add_filter (matchall_filter);
466 chooser.set_select_multiple (true);
467 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
468 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
471 /* some broken redraw behaviour - this is a bandaid */
472 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
475 if (!persistent_folder.empty()) {
476 chooser.set_current_folder (persistent_folder);
479 notebook.append_page (chooser, _("Browse Files"));
481 hpacker.set_spacing (6);
482 hpacker.pack_start (notebook, true, true);
483 hpacker.pack_start (preview, false, false);
485 vpacker.set_spacing (6);
486 vpacker.pack_start (hpacker, true, true);
496 hbox = manage(new HBox);
497 hbox->pack_start (found_entry);
498 hbox->pack_start (found_search_btn);
500 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
501 scroll->add(found_list_view);
502 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
504 vbox = manage(new VBox);
505 vbox->pack_start (*hbox, PACK_SHRINK);
506 vbox->pack_start (*scroll);
508 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
510 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
512 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
514 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
515 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
517 notebook.append_page (*vbox, _("Search Tags"));
519 //add freesound search
524 passbox = manage(new HBox);
525 passbox->set_spacing (6);
527 label = manage (new Label);
528 label->set_text (_("Tags:"));
529 passbox->pack_start (*label, false, false);
530 passbox->pack_start (freesound_entry, true, true);
532 label = manage (new Label);
533 label->set_text (_("Sort:"));
534 passbox->pack_start (*label, false, false);
535 passbox->pack_start (freesound_sort, false, false);
536 freesound_sort.clear_items();
538 // Order of the following must correspond with enum sortMethod
539 // in sfdb_freesound_mootcher.h
540 freesound_sort.append_text(_("None"));
541 freesound_sort.append_text(_("Longest"));
542 freesound_sort.append_text(_("Shortest"));
543 freesound_sort.append_text(_("Newest"));
544 freesound_sort.append_text(_("Oldest"));
545 freesound_sort.append_text(_("Most downloaded"));
546 freesound_sort.append_text(_("Least downloaded"));
547 freesound_sort.append_text(_("Highest rated"));
548 freesound_sort.append_text(_("Lowest rated"));
549 freesound_sort.set_active(0);
551 passbox->pack_start (freesound_search_btn, false, false);
552 passbox->pack_start (freesound_more_btn, false, false);
553 freesound_more_btn.set_label(_("More"));
554 freesound_more_btn.set_sensitive(false);
556 passbox->pack_start (freesound_similar_btn, false, false);
557 freesound_similar_btn.set_label(_("Similar"));
558 freesound_similar_btn.set_sensitive(false);
560 scroll = manage(new ScrolledWindow);
561 scroll->add(freesound_list_view);
562 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
564 vbox = manage(new VBox);
565 vbox->set_spacing (3);
566 vbox->pack_start (*passbox, PACK_SHRINK);
567 vbox->pack_start (*scroll);
569 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
570 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
571 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
572 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
573 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
574 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
575 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
576 freesound_list_view.get_column(0)->set_alignment(0.5);
577 freesound_list_view.get_column(1)->set_expand(true); // filename
578 freesound_list_view.get_column(1)->set_resizable(true); // filename
579 freesound_list_view.get_column(2)->set_alignment(0.5);
580 freesound_list_view.get_column(3)->set_alignment(0.5);
581 freesound_list_view.get_column(4)->set_alignment(0.5);
582 freesound_list_view.get_column(5)->set_alignment(0.5);
584 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
585 freesound_list_view.set_tooltip_column(1);
587 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
588 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
589 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
590 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
591 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
592 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
593 notebook.append_page (*vbox, _("Search Freesound"));
595 notebook.set_size_request (500, -1);
596 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
600 Gtk::HButtonBox* button_box = manage (new HButtonBox);
602 button_box->set_layout (BUTTONBOX_END);
603 button_box->pack_start (cancel_button, false, false);
604 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
606 button_box->pack_start (apply_button, false, false);
607 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
610 button_box->pack_start (ok_button, false, false);
611 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
613 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
614 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
615 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
617 vpacker.pack_end (*button_box, false, false);
619 set_wmclass (X_("import"), PROGRAM_NAME);
622 SoundFileBrowser::~SoundFileBrowser ()
624 persistent_folder = chooser.get_current_folder();
628 SoundFileBrowser::run ()
637 gtk_main_iteration ();
644 SoundFileBrowser::set_action_sensitive (bool yn)
646 ok_button.set_sensitive (yn);
647 apply_button.set_sensitive (yn);
651 SoundFileBrowser::do_something (int action)
658 SoundFileBrowser::on_show ()
660 ArdourWindow::on_show ();
665 SoundFileBrowser::clear_selection ()
667 chooser.unselect_all ();
668 found_list_view.get_selection()->unselect_all ();
672 SoundFileBrowser::chooser_file_activated ()
678 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
684 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
690 SoundFileBrowser::set_session (Session* s)
692 ArdourWindow::set_session (s);
693 preview.set_session (s);
698 remove_gain_meter ();
703 SoundFileBrowser::add_gain_meter ()
707 gm = new GainMeter (_session, 250);
709 boost::shared_ptr<Route> r = _session->the_auditioner ();
711 gm->set_controls (r, r->shared_peak_meter(), r->amp());
712 gm->set_fader_name (X_("AudioTrackFader"));
714 meter_packer.set_border_width (12);
715 meter_packer.pack_start (*gm, false, true);
716 hpacker.pack_end (meter_packer, false, false);
717 meter_packer.show_all ();
722 SoundFileBrowser::remove_gain_meter ()
725 meter_packer.remove (*gm);
726 hpacker.remove (meter_packer);
733 SoundFileBrowser::start_metering ()
735 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
739 SoundFileBrowser::stop_metering ()
741 metering_connection.disconnect();
745 SoundFileBrowser::meter ()
747 if (is_mapped () && _session && gm) {
748 gm->update_meters ();
753 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
755 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
759 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
761 return SMFSource::safe_midi_file_extension (filter_info.filename);
765 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
767 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
771 SoundFileBrowser::update_preview ()
773 if (preview.setup_labels (chooser.get_preview_filename())) {
774 if (preview.autoplay()) {
775 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
781 SoundFileBrowser::found_list_view_selected ()
783 if (!reset_options ()) {
784 set_action_sensitive (false);
788 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
791 TreeIter iter = found_list->get_iter(*rows.begin());
792 file = (*iter)[found_list_columns.pathname];
793 chooser.set_filename (file);
794 set_action_sensitive (true);
796 set_action_sensitive (false);
799 preview.setup_labels (file);
804 SoundFileBrowser::found_search_clicked ()
806 string tag_string = found_entry.get_text ();
810 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
811 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
815 vector<string> results;
816 Library->search_members_and (results, tags);
819 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
820 TreeModel::iterator new_row = found_list->append();
821 TreeModel::Row row = *new_row;
822 string path = Glib::filename_from_uri (string ("file:") + *i);
823 row[found_list_columns.pathname] = path;
829 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
832 Mootcher *mootcher = new Mootcher;
835 string id = (*iter)[freesound_list_columns.id];
836 string uri = (*iter)[freesound_list_columns.uri];
837 string ofn = (*iter)[freesound_list_columns.filename];
839 if (mootcher->checkAudioFile(ofn, id)) {
840 // file already exists, no need to download it again
841 file = mootcher->audioFileName;
843 (*iter)[freesound_list_columns.started] = false;
846 if (!(*iter)[freesound_list_columns.started]) {
847 // start downloading the sound file
848 (*iter)[freesound_list_columns.started] = true;
849 mootcher->fetchAudioFile(ofn, id, uri, this);
855 SoundFileBrowser::freesound_list_view_selected ()
858 if (!reset_options ()) {
859 set_action_sensitive (false);
862 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
863 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
864 file = freesound_get_audio_file (freesound_list->get_iter(*i));
867 switch (rows.size()) {
870 freesound_similar_btn.set_sensitive(false);
871 set_action_sensitive (false);
874 // exactly one item selected
876 // file exists on disk already
877 chooser.set_filename (file);
878 preview.setup_labels (file);
879 set_action_sensitive (true);
881 freesound_similar_btn.set_sensitive(true);
884 // multiple items selected
885 preview.setup_labels ("");
886 freesound_similar_btn.set_sensitive(false);
894 SoundFileBrowser::refresh_display(std::string ID, std::string file)
896 // called when the mootcher has finished downloading a file
897 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
898 if (rows.size() == 1) {
899 // there's a single item selected in the freesound list
900 //XXX make a function to be used to construct the actual file name both here and in the mootcher
901 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
902 std::string selected_ID = (*row)[freesound_list_columns.id];
903 if (ID == selected_ID) {
904 // the selected item in the freesound list is the item that has just finished downloading
905 chooser.set_filename(file);
906 preview.setup_labels (file);
907 set_action_sensitive (true);
913 SoundFileBrowser::freesound_search_clicked ()
916 freesound_list->clear();
922 SoundFileBrowser::freesound_more_clicked ()
927 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
928 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
932 SoundFileBrowser::freesound_similar_clicked ()
934 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
935 if (rows.size() == 1) {
938 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
939 id = (*iter)[freesound_list_columns.id];
940 freesound_list->clear();
942 GdkCursor *prev_cursor;
943 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
944 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
947 std::string theString = mootcher.searchSimilar(id);
949 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
950 handle_freesound_results(theString);
955 SoundFileBrowser::freesound_search()
959 string search_string = freesound_entry.get_text ();
960 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
962 GdkCursor *prev_cursor;
963 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
964 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
967 std::string theString = mootcher.searchText(
971 "", // OSX eats anything incl mp3
973 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
978 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
979 handle_freesound_results(theString);
983 SoundFileBrowser::handle_freesound_results(std::string theString) {
985 doc.read_buffer( theString );
986 XMLNode *root = doc.root();
989 error << "no root XML node!" << endmsg;
993 if ( strcmp(root->name().c_str(), "response") != 0) {
994 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
998 // find out how many pages are available to search
999 int freesound_n_pages = 1;
1000 XMLNode *res = root->child("num_pages");
1002 string result = res->child("text")->content();
1003 freesound_n_pages = atoi(result);
1006 int more_pages = freesound_n_pages - freesound_page;
1008 if (more_pages > 0) {
1009 freesound_more_btn.set_sensitive(true);
1010 freesound_more_btn.set_tooltip_text(string_compose(P_(
1011 "%1 more page of 100 results available",
1012 "%1 more pages of 100 results available",
1013 more_pages), more_pages));
1015 freesound_more_btn.set_sensitive(false);
1016 freesound_more_btn.set_tooltip_text(_("No more results available"));
1019 XMLNode *sounds_root = root->child("sounds");
1021 error << "no child node \"sounds\" found!" << endmsg;
1025 XMLNodeList sounds = sounds_root->children();
1026 if (sounds.size() == 0) {
1031 XMLNodeConstIterator niter;
1033 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1035 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1036 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1040 // node->dump(cerr, "node:");
1043 XMLNode *id_node = node->child ("id");
1044 XMLNode *uri_node = node->child ("serve");
1045 XMLNode *ofn_node = node->child ("original_filename");
1046 XMLNode *dur_node = node->child ("duration");
1047 XMLNode *siz_node = node->child ("filesize");
1048 XMLNode *srt_node = node->child ("samplerate");
1049 XMLNode *lic_node = node->child ("license");
1051 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1053 std::string id = id_node->child("text")->content();
1054 std::string uri = uri_node->child("text")->content();
1055 std::string ofn = ofn_node->child("text")->content();
1056 std::string dur = dur_node->child("text")->content();
1057 std::string siz = siz_node->child("text")->content();
1058 std::string srt = srt_node->child("text")->content();
1059 std::string lic = lic_node->child("text")->content();
1062 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1064 double duration_seconds = atof(dur);
1066 char duration_hhmmss[16];
1067 if (duration_seconds >= 99 * 60 * 60) {
1068 strcpy(duration_hhmmss, ">99h");
1070 s = modf(duration_seconds/60, &m) * 60;
1071 m = modf(m/60, &h) * 60;
1072 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1077 double size_bytes = atof(siz);
1079 if (size_bytes < 1000) {
1080 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1081 } else if (size_bytes < 1000000 ) {
1082 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1083 } else if (size_bytes < 10000000) {
1084 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1085 } else if (size_bytes < 1000000000) {
1086 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1088 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1091 /* see http://www.freesound.org/help/faq/#licenses */
1092 char shortlicense[64];
1093 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1094 sprintf(shortlicense, "CC-BY-NC");
1095 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1096 sprintf(shortlicense, "CC-BY");
1097 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1098 sprintf(shortlicense, "sampling+");
1099 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1100 sprintf(shortlicense, "PD");
1102 snprintf(shortlicense, 64, "%s", lic.c_str());
1103 shortlicense[63]= '\0';
1106 TreeModel::iterator new_row = freesound_list->append();
1107 TreeModel::Row row = *new_row;
1109 row[freesound_list_columns.id ] = id;
1110 row[freesound_list_columns.uri ] = uri;
1111 row[freesound_list_columns.filename] = ofn;
1112 row[freesound_list_columns.duration] = duration_hhmmss;
1113 row[freesound_list_columns.filesize] = bsize;
1114 row[freesound_list_columns.smplrate] = srt;
1115 row[freesound_list_columns.license ] = shortlicense;
1122 SoundFileBrowser::get_paths ()
1124 vector<string> results;
1126 int n = notebook.get_current_page ();
1129 vector<string> filenames = chooser.get_filenames();
1130 vector<string>::iterator i;
1132 for (i = filenames.begin(); i != filenames.end(); ++i) {
1134 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1135 results.push_back (*i);
1139 } else if (n == 1) {
1141 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1142 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1143 TreeIter iter = found_list->get_iter(*i);
1144 string str = (*iter)[found_list_columns.pathname];
1146 results.push_back (str);
1149 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1150 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1151 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1153 results.push_back (str);
1162 SoundFileOmega::reset_options_noret ()
1164 if (!resetting_ourselves) {
1165 (void) reset_options ();
1170 SoundFileOmega::reset_options ()
1172 vector<string> paths = get_paths ();
1174 if (paths.empty()) {
1176 channel_combo.set_sensitive (false);
1177 action_combo.set_sensitive (false);
1178 where_combo.set_sensitive (false);
1179 copy_files_btn.set_active (true);
1180 copy_files_btn.set_sensitive (false);
1186 channel_combo.set_sensitive (true);
1187 action_combo.set_sensitive (true);
1188 where_combo.set_sensitive (true);
1190 /* if we get through this function successfully, this may be
1191 reset at the end, once we know if we can use hard links
1192 to do embedding (or if we are importing a MIDI file).
1195 if (Config->get_only_copy_imported_files()) {
1196 copy_files_btn.set_sensitive (false);
1198 copy_files_btn.set_sensitive (false);
1204 bool selection_includes_multichannel;
1205 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1208 /* See if we are thinking about importing any MIDI files */
1209 vector<string>::iterator i = paths.begin ();
1210 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1213 bool const have_a_midi_file = (i != paths.end ());
1215 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1216 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1220 string existing_choice;
1221 vector<string> action_strings;
1223 resetting_ourselves = true;
1225 if (chooser.get_filter() == &audio_filter) {
1229 if (selected_audio_track_cnt > 0) {
1230 if (channel_combo.get_active_text().length()) {
1231 ImportDisposition id = get_channel_disposition();
1234 case Editing::ImportDistinctFiles:
1235 if (selected_audio_track_cnt == paths.size()) {
1236 action_strings.push_back (importmode2string (ImportToTrack));
1240 case Editing::ImportDistinctChannels:
1241 /* XXX it would be nice to allow channel-per-selected track
1242 but its too hard we don't want to deal with all the
1243 different per-file + per-track channel configurations.
1248 action_strings.push_back (importmode2string (ImportToTrack));
1258 if (selected_midi_track_cnt > 0) {
1259 action_strings.push_back (importmode2string (ImportToTrack));
1263 action_strings.push_back (importmode2string (ImportAsTrack));
1264 action_strings.push_back (importmode2string (ImportAsRegion));
1265 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1267 existing_choice = action_combo.get_active_text();
1269 set_popdown_strings (action_combo, action_strings);
1271 /* preserve any existing choice, if possible */
1274 if (existing_choice.length()) {
1275 vector<string>::iterator x;
1276 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1277 if (*x == existing_choice) {
1278 action_combo.set_active_text (existing_choice);
1282 if (x == action_strings.end()) {
1283 action_combo.set_active_text (action_strings.front());
1286 action_combo.set_active_text (action_strings.front());
1289 resetting_ourselves = false;
1291 if ((mode = get_mode()) == ImportAsRegion) {
1292 where_combo.set_sensitive (false);
1294 where_combo.set_sensitive (true);
1297 vector<string> channel_strings;
1299 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1300 channel_strings.push_back (_("one track per file"));
1302 if (selection_includes_multichannel) {
1303 channel_strings.push_back (_("one track per channel"));
1306 if (paths.size() > 1) {
1307 /* tape tracks are a single region per track, so we cannot
1308 sequence multiple files.
1310 if (mode != ImportAsTapeTrack) {
1311 channel_strings.push_back (_("sequence files"));
1314 channel_strings.push_back (_("all files in one track"));
1315 channel_strings.push_back (_("merge files"));
1321 channel_strings.push_back (_("one region per file"));
1323 if (selection_includes_multichannel) {
1324 channel_strings.push_back (_("one region per channel"));
1327 if (paths.size() > 1) {
1329 channel_strings.push_back (_("all files in one region"));
1334 resetting_ourselves = true;
1336 existing_choice = channel_combo.get_active_text();
1338 set_popdown_strings (channel_combo, channel_strings);
1340 /* preserve any existing choice, if possible */
1342 if (existing_choice.length()) {
1343 vector<string>::iterator x;
1344 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1345 if (*x == existing_choice) {
1346 channel_combo.set_active_text (existing_choice);
1350 if (x == channel_strings.end()) {
1351 channel_combo.set_active_text (channel_strings.front());
1354 channel_combo.set_active_text (channel_strings.front());
1357 resetting_ourselves = false;
1360 src_combo.set_sensitive (true);
1362 src_combo.set_sensitive (false);
1365 /* We must copy MIDI files or those from Freesound
1366 * or any file if we are under nsm control */
1367 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1369 if (Config->get_only_copy_imported_files()) {
1371 if (selection_can_be_embedded_with_links && !must_copy) {
1372 copy_files_btn.set_sensitive (true);
1375 copy_files_btn.set_active (true);
1377 copy_files_btn.set_sensitive (false);
1383 copy_files_btn.set_active (true);
1385 copy_files_btn.set_sensitive (!must_copy);
1393 SoundFileOmega::bad_file_message()
1395 MessageDialog msg (*this,
1396 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1401 resetting_ourselves = true;
1402 chooser.unselect_uri (chooser.get_preview_uri());
1403 resetting_ourselves = false;
1409 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1418 multichannel = false;
1420 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1422 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1423 if (info.channels > 1) {
1424 multichannel = true;
1429 if (sz != info.length) {
1434 if (info.samplerate != _session->frame_rate()) {
1438 } else if (SMFSource::safe_midi_file_extension (*i)) {
1442 if (reader.num_tracks() > 1) {
1443 multichannel = true; // "channel" == track here...
1446 /* XXX we need err = true handling here in case
1447 we can't check the file
1460 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1465 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1468 if (mkdir (tmpdir.c_str(), 0744)) {
1469 if (errno != EEXIST) {
1474 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1476 char tmpc[MAXPATHLEN+1];
1478 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1482 if (link ((*i).c_str(), tmpc)) {
1492 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) {