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,
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"));
521 //add freesound search
526 passbox = manage(new HBox);
527 passbox->set_spacing (6);
529 label = manage (new Label);
530 label->set_text (_("Tags:"));
531 passbox->pack_start (*label, false, false);
532 passbox->pack_start (freesound_entry, true, true);
534 label = manage (new Label);
535 label->set_text (_("Sort:"));
536 passbox->pack_start (*label, false, false);
537 passbox->pack_start (freesound_sort, false, false);
538 freesound_sort.clear_items();
540 // Order of the following must correspond with enum sortMethod
541 // in sfdb_freesound_mootcher.h
542 freesound_sort.append_text(_("None"));
543 freesound_sort.append_text(_("Longest"));
544 freesound_sort.append_text(_("Shortest"));
545 freesound_sort.append_text(_("Newest"));
546 freesound_sort.append_text(_("Oldest"));
547 freesound_sort.append_text(_("Most downloaded"));
548 freesound_sort.append_text(_("Least downloaded"));
549 freesound_sort.append_text(_("Highest rated"));
550 freesound_sort.append_text(_("Lowest rated"));
551 freesound_sort.set_active(0);
553 passbox->pack_start (freesound_search_btn, false, false);
554 passbox->pack_start (freesound_more_btn, false, false);
555 freesound_more_btn.set_label(_("More"));
556 freesound_more_btn.set_sensitive(false);
558 passbox->pack_start (freesound_similar_btn, false, false);
559 freesound_similar_btn.set_label(_("Similar"));
560 freesound_similar_btn.set_sensitive(false);
562 scroll = manage(new ScrolledWindow);
563 scroll->add(freesound_list_view);
564 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
566 vbox = manage(new VBox);
567 vbox->set_spacing (3);
568 vbox->pack_start (*passbox, PACK_SHRINK);
569 vbox->pack_start (*scroll);
571 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
572 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
573 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
574 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
575 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
576 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
577 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
578 freesound_list_view.get_column(0)->set_alignment(0.5);
579 freesound_list_view.get_column(1)->set_expand(true); // filename
580 freesound_list_view.get_column(1)->set_resizable(true); // filename
581 freesound_list_view.get_column(2)->set_alignment(0.5);
582 freesound_list_view.get_column(3)->set_alignment(0.5);
583 freesound_list_view.get_column(4)->set_alignment(0.5);
584 freesound_list_view.get_column(5)->set_alignment(0.5);
586 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
587 freesound_list_view.set_tooltip_column(1);
589 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
590 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
591 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
592 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
593 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
594 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
595 notebook.append_page (*vbox, _("Search Freesound"));
598 notebook.set_size_request (500, -1);
599 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
603 Gtk::HButtonBox* button_box = manage (new HButtonBox);
605 button_box->set_layout (BUTTONBOX_END);
606 button_box->pack_start (cancel_button, false, false);
607 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
609 button_box->pack_start (apply_button, false, false);
610 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
613 button_box->pack_start (ok_button, false, false);
614 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
616 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
617 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
618 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
620 vpacker.pack_end (*button_box, false, false);
622 set_wmclass (X_("import"), PROGRAM_NAME);
625 SoundFileBrowser::~SoundFileBrowser ()
627 persistent_folder = chooser.get_current_folder();
631 SoundFileBrowser::run ()
640 gtk_main_iteration ();
647 SoundFileBrowser::set_action_sensitive (bool yn)
649 ok_button.set_sensitive (yn);
650 apply_button.set_sensitive (yn);
654 SoundFileBrowser::do_something (int action)
661 SoundFileBrowser::on_show ()
663 ArdourWindow::on_show ();
668 SoundFileBrowser::clear_selection ()
670 chooser.unselect_all ();
671 found_list_view.get_selection()->unselect_all ();
675 SoundFileBrowser::chooser_file_activated ()
681 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
687 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
693 SoundFileBrowser::set_session (Session* s)
695 ArdourWindow::set_session (s);
696 preview.set_session (s);
701 remove_gain_meter ();
706 SoundFileBrowser::add_gain_meter ()
710 gm = new GainMeter (_session, 250);
712 boost::shared_ptr<Route> r = _session->the_auditioner ();
714 gm->set_controls (r, r->shared_peak_meter(), r->amp());
715 gm->set_fader_name (X_("AudioTrackFader"));
717 meter_packer.set_border_width (12);
718 meter_packer.pack_start (*gm, false, true);
719 hpacker.pack_end (meter_packer, false, false);
720 meter_packer.show_all ();
725 SoundFileBrowser::remove_gain_meter ()
728 meter_packer.remove (*gm);
729 hpacker.remove (meter_packer);
736 SoundFileBrowser::start_metering ()
738 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
742 SoundFileBrowser::stop_metering ()
744 metering_connection.disconnect();
748 SoundFileBrowser::meter ()
750 if (is_mapped () && _session && gm) {
751 gm->update_meters ();
756 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
758 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
762 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
764 return SMFSource::safe_midi_file_extension (filter_info.filename);
768 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
770 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
774 SoundFileBrowser::update_preview ()
776 if (preview.setup_labels (chooser.get_preview_filename())) {
777 if (preview.autoplay()) {
778 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
784 SoundFileBrowser::found_list_view_selected ()
786 if (!reset_options ()) {
787 set_action_sensitive (false);
791 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
794 TreeIter iter = found_list->get_iter(*rows.begin());
795 file = (*iter)[found_list_columns.pathname];
796 chooser.set_filename (file);
797 set_action_sensitive (true);
799 set_action_sensitive (false);
802 preview.setup_labels (file);
807 SoundFileBrowser::found_search_clicked ()
809 string tag_string = found_entry.get_text ();
813 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
814 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
818 vector<string> results;
819 Library->search_members_and (results, tags);
822 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
823 TreeModel::iterator new_row = found_list->append();
824 TreeModel::Row row = *new_row;
825 string path = Glib::filename_from_uri (string ("file:") + *i);
826 row[found_list_columns.pathname] = path;
832 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
835 Mootcher *mootcher = new Mootcher;
838 string id = (*iter)[freesound_list_columns.id];
839 string uri = (*iter)[freesound_list_columns.uri];
840 string ofn = (*iter)[freesound_list_columns.filename];
842 if (mootcher->checkAudioFile(ofn, id)) {
843 // file already exists, no need to download it again
844 file = mootcher->audioFileName;
846 (*iter)[freesound_list_columns.started] = false;
849 if (!(*iter)[freesound_list_columns.started]) {
850 // start downloading the sound file
851 (*iter)[freesound_list_columns.started] = true;
852 mootcher->fetchAudioFile(ofn, id, uri, this);
858 SoundFileBrowser::freesound_list_view_selected ()
861 if (!reset_options ()) {
862 set_action_sensitive (false);
865 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
866 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
867 file = freesound_get_audio_file (freesound_list->get_iter(*i));
870 switch (rows.size()) {
873 freesound_similar_btn.set_sensitive(false);
874 set_action_sensitive (false);
877 // exactly one item selected
879 // file exists on disk already
880 chooser.set_filename (file);
881 preview.setup_labels (file);
882 set_action_sensitive (true);
884 freesound_similar_btn.set_sensitive(true);
887 // multiple items selected
888 preview.setup_labels ("");
889 freesound_similar_btn.set_sensitive(false);
897 SoundFileBrowser::refresh_display(std::string ID, std::string file)
899 // called when the mootcher has finished downloading a file
900 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
901 if (rows.size() == 1) {
902 // there's a single item selected in the freesound list
903 //XXX make a function to be used to construct the actual file name both here and in the mootcher
904 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
905 std::string selected_ID = (*row)[freesound_list_columns.id];
906 if (ID == selected_ID) {
907 // the selected item in the freesound list is the item that has just finished downloading
908 chooser.set_filename(file);
909 preview.setup_labels (file);
910 set_action_sensitive (true);
916 SoundFileBrowser::freesound_search_clicked ()
919 freesound_list->clear();
925 SoundFileBrowser::freesound_more_clicked ()
930 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
931 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
935 SoundFileBrowser::freesound_similar_clicked ()
937 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
938 if (rows.size() == 1) {
941 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
942 id = (*iter)[freesound_list_columns.id];
943 freesound_list->clear();
945 GdkCursor *prev_cursor;
946 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
947 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
950 std::string theString = mootcher.searchSimilar(id);
952 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
953 handle_freesound_results(theString);
958 SoundFileBrowser::freesound_search()
962 string search_string = freesound_entry.get_text ();
963 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
965 GdkCursor *prev_cursor;
966 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
967 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
970 std::string theString = mootcher.searchText(
974 "", // OSX eats anything incl mp3
976 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
981 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
982 handle_freesound_results(theString);
986 SoundFileBrowser::handle_freesound_results(std::string theString) {
988 doc.read_buffer( theString );
989 XMLNode *root = doc.root();
992 error << "no root XML node!" << endmsg;
996 if ( strcmp(root->name().c_str(), "response") != 0) {
997 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1001 // find out how many pages are available to search
1002 int freesound_n_pages = 1;
1003 XMLNode *res = root->child("num_pages");
1005 string result = res->child("text")->content();
1006 freesound_n_pages = atoi(result);
1009 int more_pages = freesound_n_pages - freesound_page;
1011 if (more_pages > 0) {
1012 freesound_more_btn.set_sensitive(true);
1013 freesound_more_btn.set_tooltip_text(string_compose(P_(
1014 "%1 more page of 100 results available",
1015 "%1 more pages of 100 results available",
1016 more_pages), more_pages));
1018 freesound_more_btn.set_sensitive(false);
1019 freesound_more_btn.set_tooltip_text(_("No more results available"));
1022 XMLNode *sounds_root = root->child("sounds");
1024 error << "no child node \"sounds\" found!" << endmsg;
1028 XMLNodeList sounds = sounds_root->children();
1029 if (sounds.size() == 0) {
1034 XMLNodeConstIterator niter;
1036 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1038 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1039 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1043 // node->dump(cerr, "node:");
1046 XMLNode *id_node = node->child ("id");
1047 XMLNode *uri_node = node->child ("serve");
1048 XMLNode *ofn_node = node->child ("original_filename");
1049 XMLNode *dur_node = node->child ("duration");
1050 XMLNode *siz_node = node->child ("filesize");
1051 XMLNode *srt_node = node->child ("samplerate");
1052 XMLNode *lic_node = node->child ("license");
1054 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1056 std::string id = id_node->child("text")->content();
1057 std::string uri = uri_node->child("text")->content();
1058 std::string ofn = ofn_node->child("text")->content();
1059 std::string dur = dur_node->child("text")->content();
1060 std::string siz = siz_node->child("text")->content();
1061 std::string srt = srt_node->child("text")->content();
1062 std::string lic = lic_node->child("text")->content();
1065 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1067 double duration_seconds = atof(dur);
1069 char duration_hhmmss[16];
1070 if (duration_seconds >= 99 * 60 * 60) {
1071 strcpy(duration_hhmmss, ">99h");
1073 s = modf(duration_seconds/60, &m) * 60;
1074 m = modf(m/60, &h) * 60;
1075 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1080 double size_bytes = atof(siz);
1082 if (size_bytes < 1000) {
1083 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1084 } else if (size_bytes < 1000000 ) {
1085 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1086 } else if (size_bytes < 10000000) {
1087 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1088 } else if (size_bytes < 1000000000) {
1089 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1091 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1094 /* see http://www.freesound.org/help/faq/#licenses */
1095 char shortlicense[64];
1096 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1097 sprintf(shortlicense, "CC-BY-NC");
1098 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1099 sprintf(shortlicense, "CC-BY");
1100 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1101 sprintf(shortlicense, "sampling+");
1102 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1103 sprintf(shortlicense, "PD");
1105 snprintf(shortlicense, 64, "%s", lic.c_str());
1106 shortlicense[63]= '\0';
1109 TreeModel::iterator new_row = freesound_list->append();
1110 TreeModel::Row row = *new_row;
1112 row[freesound_list_columns.id ] = id;
1113 row[freesound_list_columns.uri ] = uri;
1114 row[freesound_list_columns.filename] = ofn;
1115 row[freesound_list_columns.duration] = duration_hhmmss;
1116 row[freesound_list_columns.filesize] = bsize;
1117 row[freesound_list_columns.smplrate] = srt;
1118 row[freesound_list_columns.license ] = shortlicense;
1125 SoundFileBrowser::get_paths ()
1127 vector<string> results;
1129 int n = notebook.get_current_page ();
1132 vector<string> filenames = chooser.get_filenames();
1133 vector<string>::iterator i;
1135 for (i = filenames.begin(); i != filenames.end(); ++i) {
1137 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1138 results.push_back (*i);
1142 } else if (n == 1) {
1144 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1145 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1146 TreeIter iter = found_list->get_iter(*i);
1147 string str = (*iter)[found_list_columns.pathname];
1149 results.push_back (str);
1153 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1154 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1155 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1157 results.push_back (str);
1167 SoundFileOmega::reset_options_noret ()
1169 if (!resetting_ourselves) {
1170 (void) reset_options ();
1175 SoundFileOmega::reset_options ()
1177 vector<string> paths = get_paths ();
1179 if (paths.empty()) {
1181 channel_combo.set_sensitive (false);
1182 action_combo.set_sensitive (false);
1183 where_combo.set_sensitive (false);
1184 copy_files_btn.set_active (true);
1185 copy_files_btn.set_sensitive (false);
1191 channel_combo.set_sensitive (true);
1192 action_combo.set_sensitive (true);
1193 where_combo.set_sensitive (true);
1195 /* if we get through this function successfully, this may be
1196 reset at the end, once we know if we can use hard links
1197 to do embedding (or if we are importing a MIDI file).
1200 if (Config->get_only_copy_imported_files()) {
1201 copy_files_btn.set_sensitive (false);
1203 copy_files_btn.set_sensitive (false);
1209 bool selection_includes_multichannel;
1210 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1213 /* See if we are thinking about importing any MIDI files */
1214 vector<string>::iterator i = paths.begin ();
1215 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1218 bool const have_a_midi_file = (i != paths.end ());
1220 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1221 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1225 string existing_choice;
1226 vector<string> action_strings;
1228 resetting_ourselves = true;
1230 if (chooser.get_filter() == &audio_filter) {
1234 if (selected_audio_track_cnt > 0) {
1235 if (channel_combo.get_active_text().length()) {
1236 ImportDisposition id = get_channel_disposition();
1239 case Editing::ImportDistinctFiles:
1240 if (selected_audio_track_cnt == paths.size()) {
1241 action_strings.push_back (importmode2string (ImportToTrack));
1245 case Editing::ImportDistinctChannels:
1246 /* XXX it would be nice to allow channel-per-selected track
1247 but its too hard we don't want to deal with all the
1248 different per-file + per-track channel configurations.
1253 action_strings.push_back (importmode2string (ImportToTrack));
1263 if (selected_midi_track_cnt > 0) {
1264 action_strings.push_back (importmode2string (ImportToTrack));
1268 action_strings.push_back (importmode2string (ImportAsTrack));
1269 action_strings.push_back (importmode2string (ImportAsRegion));
1270 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1272 existing_choice = action_combo.get_active_text();
1274 set_popdown_strings (action_combo, action_strings);
1276 /* preserve any existing choice, if possible */
1279 if (existing_choice.length()) {
1280 vector<string>::iterator x;
1281 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1282 if (*x == existing_choice) {
1283 action_combo.set_active_text (existing_choice);
1287 if (x == action_strings.end()) {
1288 action_combo.set_active_text (action_strings.front());
1291 action_combo.set_active_text (action_strings.front());
1294 resetting_ourselves = false;
1296 if ((mode = get_mode()) == ImportAsRegion) {
1297 where_combo.set_sensitive (false);
1299 where_combo.set_sensitive (true);
1302 vector<string> channel_strings;
1304 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1305 channel_strings.push_back (_("one track per file"));
1307 if (selection_includes_multichannel) {
1308 channel_strings.push_back (_("one track per channel"));
1311 if (paths.size() > 1) {
1312 /* tape tracks are a single region per track, so we cannot
1313 sequence multiple files.
1315 if (mode != ImportAsTapeTrack) {
1316 channel_strings.push_back (_("sequence files"));
1319 channel_strings.push_back (_("all files in one track"));
1320 channel_strings.push_back (_("merge files"));
1326 channel_strings.push_back (_("one region per file"));
1328 if (selection_includes_multichannel) {
1329 channel_strings.push_back (_("one region per channel"));
1332 if (paths.size() > 1) {
1334 channel_strings.push_back (_("all files in one region"));
1339 resetting_ourselves = true;
1341 existing_choice = channel_combo.get_active_text();
1343 set_popdown_strings (channel_combo, channel_strings);
1345 /* preserve any existing choice, if possible */
1347 if (existing_choice.length()) {
1348 vector<string>::iterator x;
1349 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1350 if (*x == existing_choice) {
1351 channel_combo.set_active_text (existing_choice);
1355 if (x == channel_strings.end()) {
1356 channel_combo.set_active_text (channel_strings.front());
1359 channel_combo.set_active_text (channel_strings.front());
1362 resetting_ourselves = false;
1365 src_combo.set_sensitive (true);
1367 src_combo.set_sensitive (false);
1370 /* We must copy MIDI files or those from Freesound
1371 * or any file if we are under nsm control */
1372 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1374 if (Config->get_only_copy_imported_files()) {
1376 if (selection_can_be_embedded_with_links && !must_copy) {
1377 copy_files_btn.set_sensitive (true);
1380 copy_files_btn.set_active (true);
1382 copy_files_btn.set_sensitive (false);
1388 copy_files_btn.set_active (true);
1390 copy_files_btn.set_sensitive (!must_copy);
1398 SoundFileOmega::bad_file_message()
1400 MessageDialog msg (*this,
1401 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1406 resetting_ourselves = true;
1407 chooser.unselect_uri (chooser.get_preview_uri());
1408 resetting_ourselves = false;
1414 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1423 multichannel = false;
1425 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1427 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1428 if (info.channels > 1) {
1429 multichannel = true;
1434 if (sz != info.length) {
1439 if (info.samplerate != _session->frame_rate()) {
1443 } else if (SMFSource::safe_midi_file_extension (*i)) {
1447 if (reader.num_tracks() > 1) {
1448 multichannel = true; // "channel" == track here...
1451 /* XXX we need err = true handling here in case
1452 we can't check the file
1465 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1467 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1470 if (mkdir (tmpdir.c_str(), 0744)) {
1471 if (errno != EEXIST) {
1476 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1478 char tmpc[MAXPATHLEN+1];
1480 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1484 if (link ((*i).c_str(), tmpc)) {
1494 rmdir (tmpdir.c_str());
1498 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1499 : SoundFileBrowser (title, s, false)
1501 chooser.set_select_multiple (false);
1502 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1503 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1507 SoundFileChooser::on_hide ()
1509 ArdourWindow::on_hide();
1513 _session->cancel_audition();
1518 SoundFileChooser::get_filename ()
1520 vector<string> paths;
1522 paths = get_paths ();
1524 if (paths.empty()) {
1528 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1532 return paths.front();
1535 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1536 uint32_t selected_audio_tracks,
1537 uint32_t selected_midi_tracks,
1539 Editing::ImportMode mode_hint)
1540 : SoundFileBrowser (title, s, persistent)
1541 , copy_files_btn ( _("Copy files to session"))
1542 , selected_audio_track_cnt (selected_audio_tracks)
1543 , selected_midi_track_cnt (selected_midi_tracks)
1549 set_size_request (-1, 450);
1551 block_two.set_border_width (12);
1552 block_three.set_border_width (12);
1553 block_four.set_border_width (12);
1555 options.set_spacing (12);
1558 str.push_back (_("file timestamp"));
1559 str.push_back (_("edit point"));
1560 str.push_back (_("playhead"));
1561 str.push_back (_("session start"));
1562 set_popdown_strings (where_combo, str);
1563 where_combo.set_active_text (str.front());
1565 Label* l = manage (new Label);
1566 l->set_markup (_("<b>Add files as ...</b>"));
1568 vbox = manage (new VBox);
1569 vbox->set_border_width (12);
1570 vbox->set_spacing (6);
1571 vbox->pack_start (*l, false, false);
1572 vbox->pack_start (action_combo, false, false);
1573 hbox = manage (new HBox);
1574 hbox->pack_start (*vbox, false, false);
1575 options.pack_start (*hbox, false, false);
1577 /* dummy entry for action combo so that it doesn't look odd if we
1578 come up with no tracks selected.
1582 str.push_back (importmode2string (mode_hint));
1583 set_popdown_strings (action_combo, str);
1584 action_combo.set_active_text (str.front());
1585 action_combo.set_sensitive (false);
1587 l = manage (new Label);
1588 l->set_markup (_("<b>Insert at</b>"));
1590 vbox = manage (new VBox);
1591 vbox->set_border_width (12);
1592 vbox->set_spacing (6);
1593 vbox->pack_start (*l, false, false);
1594 vbox->pack_start (where_combo, false, false);
1595 hbox = manage (new HBox);
1596 hbox->pack_start (*vbox, false, false);
1597 options.pack_start (*hbox, false, false);
1600 l = manage (new Label);
1601 l->set_markup (_("<b>Mapping</b>"));
1603 vbox = manage (new VBox);
1604 vbox->set_border_width (12);
1605 vbox->set_spacing (6);
1606 vbox->pack_start (*l, false, false);
1607 vbox->pack_start (channel_combo, false, false);
1608 hbox = manage (new HBox);
1609 hbox->pack_start (*vbox, false, false);
1610 options.pack_start (*hbox, false, false);
1613 str.push_back (_("one track per file"));
1614 set_popdown_strings (channel_combo, str);
1615 channel_combo.set_active_text (str.front());
1616 channel_combo.set_sensitive (false);
1618 l = manage (new Label);
1619 l->set_markup (_("<b>Conversion quality</b>"));
1621 vbox = manage (new VBox);
1622 vbox->set_border_width (12);
1623 vbox->set_spacing (6);
1624 vbox->pack_start (*l, false, false);
1625 vbox->pack_start (src_combo, false, false);
1626 hbox = manage (new HBox);
1627 hbox->pack_start (*vbox, false, false);
1628 options.pack_start (*hbox, false, false);
1631 str.push_back (_("Best"));
1632 str.push_back (_("Good"));
1633 str.push_back (_("Quick"));
1634 str.push_back (_("Fast"));
1635 str.push_back (_("Fastest"));
1637 set_popdown_strings (src_combo, str);
1638 src_combo.set_active_text (str.front());
1639 src_combo.set_sensitive (false);
1643 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1644 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1646 copy_files_btn.set_active (true);
1648 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1651 copy_label->set_size_request (175, -1);
1652 copy_label->set_line_wrap (true);
1655 block_four.pack_start (copy_files_btn, false, false);
1657 options.pack_start (block_four, false, false);
1659 vpacker.pack_start (options, false, false);
1661 /* setup disposition map */
1663 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1664 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1665 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1666 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1668 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1669 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1670 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1671 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1673 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1675 /* set size requests for a couple of combos to allow them to display the longest text
1676 they will ever be asked to display. This prevents them being resized when the user
1677 selects a file to import, which in turn prevents the size of the dialog from jumping
1681 t.push_back (_("one track per file"));
1682 t.push_back (_("one track per channel"));
1683 t.push_back (_("sequence files"));
1684 t.push_back (_("all files in one region"));
1685 set_popdown_strings (channel_combo, t);
1688 t.push_back (importmode2string (ImportAsTrack));
1689 t.push_back (importmode2string (ImportToTrack));
1690 t.push_back (importmode2string (ImportAsRegion));
1691 t.push_back (importmode2string (ImportAsTapeTrack));
1692 set_popdown_strings (action_combo, t);
1696 SoundFileOmega::set_mode (ImportMode mode)
1698 action_combo.set_active_text (importmode2string (mode));
1702 SoundFileOmega::get_mode () const
1704 return string2importmode (action_combo.get_active_text());
1708 SoundFileOmega::on_hide ()
1710 ArdourWindow::on_hide();
1712 _session->cancel_audition();
1717 SoundFileOmega::get_position() const
1719 string str = where_combo.get_active_text();
1721 if (str == _("file timestamp")) {
1722 return ImportAtTimestamp;
1723 } else if (str == _("edit point")) {
1724 return ImportAtEditPoint;
1725 } else if (str == _("playhead")) {
1726 return ImportAtPlayhead;
1728 return ImportAtStart;
1733 SoundFileOmega::get_src_quality() const
1735 string str = src_combo.get_active_text();
1737 if (str == _("Best")) {
1739 } else if (str == _("Good")) {
1741 } else if (str == _("Quick")) {
1743 } else if (str == _("Fast")) {
1751 SoundFileOmega::get_channel_disposition () const
1753 /* we use a map here because the channel combo can contain different strings
1754 depending on the state of the other combos. the map contains all possible strings
1755 and the ImportDisposition enum that corresponds to it.
1758 string str = channel_combo.get_active_text();
1759 DispositionMap::const_iterator x = disposition_map.find (str);
1761 if (x == disposition_map.end()) {
1762 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1770 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1772 selected_audio_track_cnt = selected_audio_tracks;
1773 selected_midi_track_cnt = selected_midi_tracks;
1775 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1776 chooser.set_filter (midi_filter);
1777 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1778 chooser.set_filter (audio_filter);
1780 chooser.set_filter (audio_and_midi_filter);
1787 SoundFileOmega::file_selection_changed ()
1789 if (resetting_ourselves) {
1793 if (!reset_options ()) {
1794 set_action_sensitive (false);
1796 if (chooser.get_filenames().size() > 0) {
1797 set_action_sensitive (true);
1799 set_action_sensitive (false);
1805 SoundFileOmega::do_something (int action)
1807 SoundFileBrowser::do_something (action);
1809 if (action == RESPONSE_CANCEL) {
1816 vector<string> paths = get_paths ();
1817 ImportPosition pos = get_position ();
1818 ImportMode mode = get_mode ();
1819 ImportDisposition chns = get_channel_disposition ();
1823 case ImportAtEditPoint:
1824 where = PublicEditor::instance().get_preferred_edit_position ();
1826 case ImportAtTimestamp:
1829 case ImportAtPlayhead:
1830 where = _session->transport_frame();
1833 where = _session->current_start_frame();
1837 SrcQuality quality = get_src_quality();
1839 if (copy_files_btn.get_active()) {
1840 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1842 PublicEditor::instance().do_embed (paths, chns, mode, where);
1845 if (action == RESPONSE_OK) {