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"
70 #include "sfdb_freesound_mootcher.h"
75 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
80 using namespace Editing;
84 string SoundFileBrowser::persistent_folder;
85 typedef TreeView::Selection::ListHandle_Path ListPath;
88 string2importmode (string str)
90 if (str == _("as new tracks")) {
92 } else if (str == _("to selected tracks")) {
94 } else if (str == _("to region list")) {
95 return ImportAsRegion;
96 } else if (str == _("as new tape tracks")) {
97 return ImportAsTapeTrack;
100 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
102 return ImportAsTrack;
106 importmode2string (ImportMode mode)
110 return _("as new tracks");
112 return _("to selected tracks");
114 return _("to region list");
115 case ImportAsTapeTrack:
116 return _("as new tape tracks");
119 return _("as new tracks");
122 SoundFileBox::SoundFileBox (bool persistent)
124 length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
125 timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
127 autoplay_btn (_("Auto-play"))
130 set_name (X_("SoundFileBox"));
131 set_size_request (300, -1);
133 preview_label.set_markup (_("<b>Sound File Information</b>"));
135 border_frame.set_label_widget (preview_label);
136 border_frame.add (main_box);
138 pack_start (border_frame, true, true);
139 set_border_width (6);
141 main_box.set_border_width (6);
143 length.set_text (_("Length:"));
144 length.set_alignment (1, 0.5);
145 timecode.set_text (_("Timestamp:"));
146 timecode.set_alignment (1, 0.5);
147 format.set_text (_("Format:"));
148 format.set_alignment (1, 0.5);
149 channels.set_text (_("Channels:"));
150 channels.set_alignment (1, 0.5);
151 samplerate.set_text (_("Sample rate:"));
152 samplerate.set_alignment (1, 0.5);
154 preview_label.set_max_width_chars (50);
155 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
157 format_text.set_max_width_chars (20);
158 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
159 format_text.set_alignment (0, 1);
161 table.set_col_spacings (6);
162 table.set_homogeneous (false);
163 table.set_row_spacings (6);
165 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
166 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
167 table.attach (format, 0, 1, 2, 4, FILL, FILL);
168 table.attach (length, 0, 1, 4, 5, FILL, FILL);
169 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
171 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
172 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
173 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
174 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
175 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
177 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
178 timecode_clock.set_mode (AudioClock::Timecode);
180 main_box.pack_start (table, false, false);
182 tags_entry.set_editable (true);
183 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
184 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
186 Label* label = manage (new Label (_("Tags:")));
187 label->set_alignment (0.0f, 0.5f);
188 main_box.pack_start (*label, false, false);
189 main_box.pack_start (tags_entry, true, true);
191 main_box.pack_start (bottom_box, false, false);
193 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
194 // play_btn.set_label (_("Play"));
196 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
197 // stop_btn.set_label (_("Stop"));
199 bottom_box.set_homogeneous (false);
200 bottom_box.set_spacing (6);
201 bottom_box.pack_start(play_btn, true, true);
202 bottom_box.pack_start(stop_btn, true, true);
203 bottom_box.pack_start(autoplay_btn, false, false);
205 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
206 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
208 channels_value.set_alignment (0.0f, 0.5f);
209 samplerate_value.set_alignment (0.0f, 0.5f);
213 SoundFileBox::set_session(Session* s)
215 SessionHandlePtr::set_session (s);
217 length_clock.set_session (s);
218 timecode_clock.set_session (s);
221 play_btn.set_sensitive (false);
222 stop_btn.set_sensitive (false);
227 SoundFileBox::setup_labels (const string& filename)
230 // save existing tags
238 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
240 preview_label.set_markup (_("<b>Sound File Information</b>"));
241 format_text.set_text ("");
242 channels_value.set_text ("");
243 samplerate_value.set_text ("");
244 tags_entry.get_buffer()->set_text ("");
246 length_clock.set (0);
247 timecode_clock.set (0);
249 tags_entry.set_sensitive (false);
250 play_btn.set_sensitive (false);
255 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
256 std::string n = sf_info.format_name;
257 if (n.substr (0, 8) == X_("Format: ")) {
260 format_text.set_text (n);
261 channels_value.set_text (to_string (sf_info.channels, std::dec));
263 if (_session && sf_info.samplerate != _session->frame_rate()) {
264 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
265 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
266 samplerate_value.set_name ("NewSessionSR1Label");
267 samplerate.set_name ("NewSessionSR1Label");
269 samplerate.set_text (_("Sample rate:"));
270 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
271 samplerate_value.set_name ("NewSessionSR2Label");
272 samplerate.set_name ("NewSessionSR2Label");
275 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
276 double src_coef = (double) nfr / sf_info.samplerate;
278 length_clock.set (sf_info.length * src_coef + 0.5, true);
279 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
281 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
283 vector<string> tags = Library->get_tags (string ("//") + filename);
285 stringstream tag_string;
286 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
287 if (i != tags.begin()) {
292 tags_entry.get_buffer()->set_text (tag_string.str());
294 tags_entry.set_sensitive (true);
296 play_btn.set_sensitive (true);
303 SoundFileBox::autoplay() const
305 return autoplay_btn.get_active();
309 SoundFileBox::audition_oneshot()
316 SoundFileBox::audition ()
322 if (SMFSource::safe_midi_file_extension (path)) {
323 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
327 _session->cancel_audition();
329 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
330 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
334 boost::shared_ptr<Region> r;
336 boost::shared_ptr<AudioFileSource> afs;
337 bool old_sbp = AudioSource::get_build_peakfiles ();
339 /* don't even think of building peakfiles for these files */
341 AudioSource::set_build_peakfiles (false);
343 for (int n = 0; n < sf_info.channels; ++n) {
345 afs = boost::dynamic_pointer_cast<AudioFileSource> (
346 SourceFactory::createExternal (DataType::AUDIO, *_session,
347 path, n, Source::Flag (0), false));
349 srclist.push_back(afs);
351 } catch (failed_constructor& err) {
352 error << _("Could not access soundfile: ") << path << endmsg;
353 AudioSource::set_build_peakfiles (old_sbp);
358 AudioSource::set_build_peakfiles (old_sbp);
360 if (srclist.empty()) {
364 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
365 string rname = region_name_from_path (afs->path(), false);
369 plist.add (ARDOUR::Properties::start, 0);
370 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
371 plist.add (ARDOUR::Properties::name, rname);
372 plist.add (ARDOUR::Properties::layer, 0);
374 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
376 _session->audition_region(r);
380 SoundFileBox::stop_audition ()
383 _session->cancel_audition();
388 SoundFileBox::tags_entry_left (GdkEventFocus *)
395 SoundFileBox::tags_changed ()
397 string tag_string = tags_entry.get_buffer()->get_text ();
399 if (tag_string.empty()) {
405 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
406 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
414 SoundFileBox::save_tags (const vector<string>& tags)
416 Library->set_tags (string ("//") + path, tags);
417 Library->save_changes ();
420 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
421 : ArdourWindow (title)
422 , found_list (ListStore::create(found_list_columns))
423 , freesound_list (ListStore::create(freesound_list_columns))
424 , chooser (FILE_CHOOSER_ACTION_OPEN)
425 , preview (persistent)
426 , found_search_btn (_("Search"))
427 , found_list_view (found_list)
428 , freesound_search_btn (_("Search"))
429 , freesound_list_view (freesound_list)
430 , resetting_ourselves (false)
434 , ok_button (Stock::OK)
435 , cancel_button (Stock::CANCEL)
436 , apply_button (Stock::APPLY)
441 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
442 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
443 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
444 chooser.add_shortcut_folder_uri("file:///Volumes");
447 //add the file chooser
449 chooser.set_border_width (12);
451 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
452 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
454 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
455 audio_filter.set_name (_("Audio files"));
457 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
458 midi_filter.set_name (_("MIDI files"));
460 matchall_filter.add_pattern ("*.*");
461 matchall_filter.set_name (_("All files"));
463 chooser.add_filter (audio_and_midi_filter);
464 chooser.add_filter (audio_filter);
465 chooser.add_filter (midi_filter);
466 chooser.add_filter (matchall_filter);
467 chooser.set_select_multiple (true);
468 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
469 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
472 /* some broken redraw behaviour - this is a bandaid */
473 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
476 if (!persistent_folder.empty()) {
477 chooser.set_current_folder (persistent_folder);
480 notebook.append_page (chooser, _("Browse Files"));
482 hpacker.set_spacing (6);
483 hpacker.pack_start (notebook, true, true);
484 hpacker.pack_start (preview, false, false);
486 vpacker.set_spacing (6);
487 vpacker.pack_start (hpacker, true, true);
497 hbox = manage(new HBox);
498 hbox->pack_start (found_entry);
499 hbox->pack_start (found_search_btn);
501 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
502 scroll->add(found_list_view);
503 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
505 vbox = manage(new VBox);
506 vbox->pack_start (*hbox, PACK_SHRINK);
507 vbox->pack_start (*scroll);
509 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
511 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
513 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
515 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
516 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
518 notebook.append_page (*vbox, _("Search Tags"));
522 //add freesound search
527 passbox = manage(new HBox);
528 passbox->set_spacing (6);
530 label = manage (new Label);
531 label->set_text (_("Tags:"));
532 passbox->pack_start (*label, false, false);
533 passbox->pack_start (freesound_entry, true, true);
535 label = manage (new Label);
536 label->set_text (_("Sort:"));
537 passbox->pack_start (*label, false, false);
538 passbox->pack_start (freesound_sort, false, false);
539 freesound_sort.clear_items();
541 // Order of the following must correspond with enum sortMethod
542 // in sfdb_freesound_mootcher.h
543 freesound_sort.append_text(_("None"));
544 freesound_sort.append_text(_("Longest"));
545 freesound_sort.append_text(_("Shortest"));
546 freesound_sort.append_text(_("Newest"));
547 freesound_sort.append_text(_("Oldest"));
548 freesound_sort.append_text(_("Most downloaded"));
549 freesound_sort.append_text(_("Least downloaded"));
550 freesound_sort.append_text(_("Highest rated"));
551 freesound_sort.append_text(_("Lowest rated"));
552 freesound_sort.set_active(0);
554 passbox->pack_start (freesound_search_btn, false, false);
555 passbox->pack_start (freesound_more_btn, false, false);
556 freesound_more_btn.set_label(_("More"));
557 freesound_more_btn.set_sensitive(false);
559 passbox->pack_start (freesound_similar_btn, false, false);
560 freesound_similar_btn.set_label(_("Similar"));
561 freesound_similar_btn.set_sensitive(false);
563 scroll = manage(new ScrolledWindow);
564 scroll->add(freesound_list_view);
565 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
567 vbox = manage(new VBox);
568 vbox->set_spacing (3);
569 vbox->pack_start (*passbox, PACK_SHRINK);
570 vbox->pack_start (*scroll);
572 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
573 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
574 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
575 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
576 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
577 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
578 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
579 freesound_list_view.get_column(0)->set_alignment(0.5);
580 freesound_list_view.get_column(1)->set_expand(true); // filename
581 freesound_list_view.get_column(1)->set_resizable(true); // filename
582 freesound_list_view.get_column(2)->set_alignment(0.5);
583 freesound_list_view.get_column(3)->set_alignment(0.5);
584 freesound_list_view.get_column(4)->set_alignment(0.5);
585 freesound_list_view.get_column(5)->set_alignment(0.5);
587 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
588 freesound_list_view.set_tooltip_column(1);
590 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
591 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
592 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
593 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
594 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
595 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
596 notebook.append_page (*vbox, _("Search Freesound"));
599 notebook.set_size_request (500, -1);
600 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
604 Gtk::HButtonBox* button_box = manage (new HButtonBox);
606 button_box->set_layout (BUTTONBOX_END);
607 button_box->pack_start (cancel_button, false, false);
608 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
610 button_box->pack_start (apply_button, false, false);
611 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
614 button_box->pack_start (ok_button, false, false);
615 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
617 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
618 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
619 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
621 vpacker.pack_end (*button_box, false, false);
623 set_wmclass (X_("import"), PROGRAM_NAME);
626 SoundFileBrowser::~SoundFileBrowser ()
628 persistent_folder = chooser.get_current_folder();
632 SoundFileBrowser::run ()
641 gtk_main_iteration ();
648 SoundFileBrowser::set_action_sensitive (bool yn)
650 ok_button.set_sensitive (yn);
651 apply_button.set_sensitive (yn);
655 SoundFileBrowser::do_something (int action)
662 SoundFileBrowser::on_show ()
664 ArdourWindow::on_show ();
669 SoundFileBrowser::clear_selection ()
671 chooser.unselect_all ();
672 found_list_view.get_selection()->unselect_all ();
676 SoundFileBrowser::chooser_file_activated ()
682 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
688 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
694 SoundFileBrowser::set_session (Session* s)
696 ArdourWindow::set_session (s);
697 preview.set_session (s);
702 remove_gain_meter ();
707 SoundFileBrowser::add_gain_meter ()
711 gm = new GainMeter (_session, 250);
713 boost::shared_ptr<Route> r = _session->the_auditioner ();
715 gm->set_controls (r, r->shared_peak_meter(), r->amp());
716 gm->set_fader_name (X_("AudioTrackFader"));
718 meter_packer.set_border_width (12);
719 meter_packer.pack_start (*gm, false, true);
720 hpacker.pack_end (meter_packer, false, false);
721 meter_packer.show_all ();
726 SoundFileBrowser::remove_gain_meter ()
729 meter_packer.remove (*gm);
730 hpacker.remove (meter_packer);
737 SoundFileBrowser::start_metering ()
739 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
743 SoundFileBrowser::stop_metering ()
745 metering_connection.disconnect();
749 SoundFileBrowser::meter ()
751 if (is_mapped () && _session && gm) {
752 gm->update_meters ();
757 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
759 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
763 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
765 return SMFSource::safe_midi_file_extension (filter_info.filename);
769 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
771 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
775 SoundFileBrowser::update_preview ()
777 if (preview.setup_labels (chooser.get_preview_filename())) {
778 if (preview.autoplay()) {
779 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
785 SoundFileBrowser::found_list_view_selected ()
787 if (!reset_options ()) {
788 set_action_sensitive (false);
792 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
795 TreeIter iter = found_list->get_iter(*rows.begin());
796 file = (*iter)[found_list_columns.pathname];
797 chooser.set_filename (file);
798 set_action_sensitive (true);
800 set_action_sensitive (false);
803 preview.setup_labels (file);
808 SoundFileBrowser::found_search_clicked ()
810 string tag_string = found_entry.get_text ();
814 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
815 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
819 vector<string> results;
820 Library->search_members_and (results, tags);
823 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
824 TreeModel::iterator new_row = found_list->append();
825 TreeModel::Row row = *new_row;
826 string path = Glib::filename_from_uri (string ("file:") + *i);
827 row[found_list_columns.pathname] = path;
833 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
836 Mootcher *mootcher = new Mootcher;
839 string id = (*iter)[freesound_list_columns.id];
840 string uri = (*iter)[freesound_list_columns.uri];
841 string ofn = (*iter)[freesound_list_columns.filename];
843 if (mootcher->checkAudioFile(ofn, id)) {
844 // file already exists, no need to download it again
845 file = mootcher->audioFileName;
847 (*iter)[freesound_list_columns.started] = false;
850 if (!(*iter)[freesound_list_columns.started]) {
851 // start downloading the sound file
852 (*iter)[freesound_list_columns.started] = true;
853 mootcher->fetchAudioFile(ofn, id, uri, this);
859 SoundFileBrowser::freesound_list_view_selected ()
862 if (!reset_options ()) {
863 set_action_sensitive (false);
866 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
867 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
868 file = freesound_get_audio_file (freesound_list->get_iter(*i));
871 switch (rows.size()) {
874 freesound_similar_btn.set_sensitive(false);
875 set_action_sensitive (false);
878 // exactly one item selected
880 // file exists on disk already
881 chooser.set_filename (file);
882 preview.setup_labels (file);
883 set_action_sensitive (true);
885 freesound_similar_btn.set_sensitive(true);
888 // multiple items selected
889 preview.setup_labels ("");
890 freesound_similar_btn.set_sensitive(false);
898 SoundFileBrowser::refresh_display(std::string ID, std::string file)
900 // called when the mootcher has finished downloading a file
901 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
902 if (rows.size() == 1) {
903 // there's a single item selected in the freesound list
904 //XXX make a function to be used to construct the actual file name both here and in the mootcher
905 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
906 std::string selected_ID = (*row)[freesound_list_columns.id];
907 if (ID == selected_ID) {
908 // the selected item in the freesound list is the item that has just finished downloading
909 chooser.set_filename(file);
910 preview.setup_labels (file);
911 set_action_sensitive (true);
917 SoundFileBrowser::freesound_search_clicked ()
920 freesound_list->clear();
926 SoundFileBrowser::freesound_more_clicked ()
931 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
932 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
936 SoundFileBrowser::freesound_similar_clicked ()
938 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
939 if (rows.size() == 1) {
942 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
943 id = (*iter)[freesound_list_columns.id];
944 freesound_list->clear();
946 GdkCursor *prev_cursor;
947 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
948 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
951 std::string theString = mootcher.searchSimilar(id);
953 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
954 handle_freesound_results(theString);
959 SoundFileBrowser::freesound_search()
963 string search_string = freesound_entry.get_text ();
964 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
966 GdkCursor *prev_cursor;
967 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
968 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
971 std::string theString = mootcher.searchText(
975 "", // OSX eats anything incl mp3
977 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
982 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
983 handle_freesound_results(theString);
987 SoundFileBrowser::handle_freesound_results(std::string theString) {
989 doc.read_buffer( theString );
990 XMLNode *root = doc.root();
993 error << "no root XML node!" << endmsg;
997 if ( strcmp(root->name().c_str(), "response") != 0) {
998 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1002 // find out how many pages are available to search
1003 int freesound_n_pages = 1;
1004 XMLNode *res = root->child("num_pages");
1006 string result = res->child("text")->content();
1007 freesound_n_pages = atoi(result);
1010 int more_pages = freesound_n_pages - freesound_page;
1012 if (more_pages > 0) {
1013 freesound_more_btn.set_sensitive(true);
1014 freesound_more_btn.set_tooltip_text(string_compose(P_(
1015 "%1 more page of 100 results available",
1016 "%1 more pages of 100 results available",
1017 more_pages), more_pages));
1019 freesound_more_btn.set_sensitive(false);
1020 freesound_more_btn.set_tooltip_text(_("No more results available"));
1023 XMLNode *sounds_root = root->child("sounds");
1025 error << "no child node \"sounds\" found!" << endmsg;
1029 XMLNodeList sounds = sounds_root->children();
1030 if (sounds.size() == 0) {
1035 XMLNodeConstIterator niter;
1037 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1039 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1040 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1044 // node->dump(cerr, "node:");
1047 XMLNode *id_node = node->child ("id");
1048 XMLNode *uri_node = node->child ("serve");
1049 XMLNode *ofn_node = node->child ("original_filename");
1050 XMLNode *dur_node = node->child ("duration");
1051 XMLNode *siz_node = node->child ("filesize");
1052 XMLNode *srt_node = node->child ("samplerate");
1053 XMLNode *lic_node = node->child ("license");
1055 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1057 std::string id = id_node->child("text")->content();
1058 std::string uri = uri_node->child("text")->content();
1059 std::string ofn = ofn_node->child("text")->content();
1060 std::string dur = dur_node->child("text")->content();
1061 std::string siz = siz_node->child("text")->content();
1062 std::string srt = srt_node->child("text")->content();
1063 std::string lic = lic_node->child("text")->content();
1066 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1068 double duration_seconds = atof(dur);
1070 char duration_hhmmss[16];
1071 if (duration_seconds >= 99 * 60 * 60) {
1072 strcpy(duration_hhmmss, ">99h");
1074 s = modf(duration_seconds/60, &m) * 60;
1075 m = modf(m/60, &h) * 60;
1076 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1081 double size_bytes = atof(siz);
1083 if (size_bytes < 1000) {
1084 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1085 } else if (size_bytes < 1000000 ) {
1086 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1087 } else if (size_bytes < 10000000) {
1088 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1089 } else if (size_bytes < 1000000000) {
1090 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1092 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1095 /* see http://www.freesound.org/help/faq/#licenses */
1096 char shortlicense[64];
1097 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1098 sprintf(shortlicense, "CC-BY-NC");
1099 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1100 sprintf(shortlicense, "CC-BY");
1101 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1102 sprintf(shortlicense, "sampling+");
1103 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1104 sprintf(shortlicense, "PD");
1106 snprintf(shortlicense, 64, "%s", lic.c_str());
1107 shortlicense[63]= '\0';
1110 TreeModel::iterator new_row = freesound_list->append();
1111 TreeModel::Row row = *new_row;
1113 row[freesound_list_columns.id ] = id;
1114 row[freesound_list_columns.uri ] = uri;
1115 row[freesound_list_columns.filename] = ofn;
1116 row[freesound_list_columns.duration] = duration_hhmmss;
1117 row[freesound_list_columns.filesize] = bsize;
1118 row[freesound_list_columns.smplrate] = srt;
1119 row[freesound_list_columns.license ] = shortlicense;
1126 SoundFileBrowser::get_paths ()
1128 vector<string> results;
1130 int n = notebook.get_current_page ();
1133 vector<string> filenames = chooser.get_filenames();
1134 vector<string>::iterator i;
1136 for (i = filenames.begin(); i != filenames.end(); ++i) {
1138 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1139 results.push_back (*i);
1143 } else if (n == 1) {
1145 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1146 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1147 TreeIter iter = found_list->get_iter(*i);
1148 string str = (*iter)[found_list_columns.pathname];
1150 results.push_back (str);
1154 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1155 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1156 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1158 results.push_back (str);
1168 SoundFileOmega::reset_options_noret ()
1170 if (!resetting_ourselves) {
1171 (void) reset_options ();
1176 SoundFileOmega::reset_options ()
1178 vector<string> paths = get_paths ();
1180 if (paths.empty()) {
1182 channel_combo.set_sensitive (false);
1183 action_combo.set_sensitive (false);
1184 where_combo.set_sensitive (false);
1185 copy_files_btn.set_active (true);
1186 copy_files_btn.set_sensitive (false);
1192 channel_combo.set_sensitive (true);
1193 action_combo.set_sensitive (true);
1194 where_combo.set_sensitive (true);
1196 /* if we get through this function successfully, this may be
1197 reset at the end, once we know if we can use hard links
1198 to do embedding (or if we are importing a MIDI file).
1201 if (Config->get_only_copy_imported_files()) {
1202 copy_files_btn.set_sensitive (false);
1204 copy_files_btn.set_sensitive (false);
1210 bool selection_includes_multichannel;
1211 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1214 /* See if we are thinking about importing any MIDI files */
1215 vector<string>::iterator i = paths.begin ();
1216 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1219 bool const have_a_midi_file = (i != paths.end ());
1221 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1222 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1226 string existing_choice;
1227 vector<string> action_strings;
1229 resetting_ourselves = true;
1231 if (chooser.get_filter() == &audio_filter) {
1235 if (selected_audio_track_cnt > 0) {
1236 if (channel_combo.get_active_text().length()) {
1237 ImportDisposition id = get_channel_disposition();
1240 case Editing::ImportDistinctFiles:
1241 if (selected_audio_track_cnt == paths.size()) {
1242 action_strings.push_back (importmode2string (ImportToTrack));
1246 case Editing::ImportDistinctChannels:
1247 /* XXX it would be nice to allow channel-per-selected track
1248 but its too hard we don't want to deal with all the
1249 different per-file + per-track channel configurations.
1254 action_strings.push_back (importmode2string (ImportToTrack));
1264 if (selected_midi_track_cnt > 0) {
1265 action_strings.push_back (importmode2string (ImportToTrack));
1269 action_strings.push_back (importmode2string (ImportAsTrack));
1270 action_strings.push_back (importmode2string (ImportAsRegion));
1271 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1273 existing_choice = action_combo.get_active_text();
1275 set_popdown_strings (action_combo, action_strings);
1277 /* preserve any existing choice, if possible */
1280 if (existing_choice.length()) {
1281 vector<string>::iterator x;
1282 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1283 if (*x == existing_choice) {
1284 action_combo.set_active_text (existing_choice);
1288 if (x == action_strings.end()) {
1289 action_combo.set_active_text (action_strings.front());
1292 action_combo.set_active_text (action_strings.front());
1295 resetting_ourselves = false;
1297 if ((mode = get_mode()) == ImportAsRegion) {
1298 where_combo.set_sensitive (false);
1300 where_combo.set_sensitive (true);
1303 vector<string> channel_strings;
1305 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1306 channel_strings.push_back (_("one track per file"));
1308 if (selection_includes_multichannel) {
1309 channel_strings.push_back (_("one track per channel"));
1312 if (paths.size() > 1) {
1313 /* tape tracks are a single region per track, so we cannot
1314 sequence multiple files.
1316 if (mode != ImportAsTapeTrack) {
1317 channel_strings.push_back (_("sequence files"));
1320 channel_strings.push_back (_("all files in one track"));
1321 channel_strings.push_back (_("merge files"));
1327 channel_strings.push_back (_("one region per file"));
1329 if (selection_includes_multichannel) {
1330 channel_strings.push_back (_("one region per channel"));
1333 if (paths.size() > 1) {
1335 channel_strings.push_back (_("all files in one region"));
1340 resetting_ourselves = true;
1342 existing_choice = channel_combo.get_active_text();
1344 set_popdown_strings (channel_combo, channel_strings);
1346 /* preserve any existing choice, if possible */
1348 if (existing_choice.length()) {
1349 vector<string>::iterator x;
1350 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1351 if (*x == existing_choice) {
1352 channel_combo.set_active_text (existing_choice);
1356 if (x == channel_strings.end()) {
1357 channel_combo.set_active_text (channel_strings.front());
1360 channel_combo.set_active_text (channel_strings.front());
1363 resetting_ourselves = false;
1366 src_combo.set_sensitive (true);
1368 src_combo.set_sensitive (false);
1371 /* We must copy MIDI files or those from Freesound
1372 * or any file if we are under nsm control */
1373 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1375 if (Config->get_only_copy_imported_files()) {
1377 if (selection_can_be_embedded_with_links && !must_copy) {
1378 copy_files_btn.set_sensitive (true);
1381 copy_files_btn.set_active (true);
1383 copy_files_btn.set_sensitive (false);
1389 copy_files_btn.set_active (true);
1391 copy_files_btn.set_sensitive (!must_copy);
1399 SoundFileOmega::bad_file_message()
1401 MessageDialog msg (*this,
1402 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1407 resetting_ourselves = true;
1408 chooser.unselect_uri (chooser.get_preview_uri());
1409 resetting_ourselves = false;
1415 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1424 multichannel = false;
1426 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1428 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1429 if (info.channels > 1) {
1430 multichannel = true;
1435 if (sz != info.length) {
1440 if (info.samplerate != _session->frame_rate()) {
1444 } else if (SMFSource::safe_midi_file_extension (*i)) {
1448 if (reader.num_tracks() > 1) {
1449 multichannel = true; // "channel" == track here...
1452 /* XXX we need err = true handling here in case
1453 we can't check the file
1466 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1471 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1474 if (mkdir (tmpdir.c_str(), 0744)) {
1475 if (errno != EEXIST) {
1480 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1482 char tmpc[MAXPATHLEN+1];
1484 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1488 if (link ((*i).c_str(), tmpc)) {
1498 rmdir (tmpdir.c_str());
1503 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1504 : SoundFileBrowser (title, s, false)
1506 chooser.set_select_multiple (false);
1507 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1508 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1512 SoundFileChooser::on_hide ()
1514 ArdourWindow::on_hide();
1518 _session->cancel_audition();
1523 SoundFileChooser::get_filename ()
1525 vector<string> paths;
1527 paths = get_paths ();
1529 if (paths.empty()) {
1533 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1537 return paths.front();
1540 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1541 uint32_t selected_audio_tracks,
1542 uint32_t selected_midi_tracks,
1544 Editing::ImportMode mode_hint)
1545 : SoundFileBrowser (title, s, persistent)
1546 , copy_files_btn ( _("Copy files to session"))
1547 , selected_audio_track_cnt (selected_audio_tracks)
1548 , selected_midi_track_cnt (selected_midi_tracks)
1554 set_size_request (-1, 450);
1556 block_two.set_border_width (12);
1557 block_three.set_border_width (12);
1558 block_four.set_border_width (12);
1560 options.set_spacing (12);
1563 str.push_back (_("file timestamp"));
1564 str.push_back (_("edit point"));
1565 str.push_back (_("playhead"));
1566 str.push_back (_("session start"));
1567 set_popdown_strings (where_combo, str);
1568 where_combo.set_active_text (str.front());
1570 Label* l = manage (new Label);
1571 l->set_markup (_("<b>Add files as ...</b>"));
1573 vbox = manage (new VBox);
1574 vbox->set_border_width (12);
1575 vbox->set_spacing (6);
1576 vbox->pack_start (*l, false, false);
1577 vbox->pack_start (action_combo, false, false);
1578 hbox = manage (new HBox);
1579 hbox->pack_start (*vbox, false, false);
1580 options.pack_start (*hbox, false, false);
1582 /* dummy entry for action combo so that it doesn't look odd if we
1583 come up with no tracks selected.
1587 str.push_back (importmode2string (mode_hint));
1588 set_popdown_strings (action_combo, str);
1589 action_combo.set_active_text (str.front());
1590 action_combo.set_sensitive (false);
1592 l = manage (new Label);
1593 l->set_markup (_("<b>Insert at</b>"));
1595 vbox = manage (new VBox);
1596 vbox->set_border_width (12);
1597 vbox->set_spacing (6);
1598 vbox->pack_start (*l, false, false);
1599 vbox->pack_start (where_combo, false, false);
1600 hbox = manage (new HBox);
1601 hbox->pack_start (*vbox, false, false);
1602 options.pack_start (*hbox, false, false);
1605 l = manage (new Label);
1606 l->set_markup (_("<b>Mapping</b>"));
1608 vbox = manage (new VBox);
1609 vbox->set_border_width (12);
1610 vbox->set_spacing (6);
1611 vbox->pack_start (*l, false, false);
1612 vbox->pack_start (channel_combo, false, false);
1613 hbox = manage (new HBox);
1614 hbox->pack_start (*vbox, false, false);
1615 options.pack_start (*hbox, false, false);
1618 str.push_back (_("one track per file"));
1619 set_popdown_strings (channel_combo, str);
1620 channel_combo.set_active_text (str.front());
1621 channel_combo.set_sensitive (false);
1623 l = manage (new Label);
1624 l->set_markup (_("<b>Conversion quality</b>"));
1626 vbox = manage (new VBox);
1627 vbox->set_border_width (12);
1628 vbox->set_spacing (6);
1629 vbox->pack_start (*l, false, false);
1630 vbox->pack_start (src_combo, false, false);
1631 hbox = manage (new HBox);
1632 hbox->pack_start (*vbox, false, false);
1633 options.pack_start (*hbox, false, false);
1636 str.push_back (_("Best"));
1637 str.push_back (_("Good"));
1638 str.push_back (_("Quick"));
1639 str.push_back (_("Fast"));
1640 str.push_back (_("Fastest"));
1642 set_popdown_strings (src_combo, str);
1643 src_combo.set_active_text (str.front());
1644 src_combo.set_sensitive (false);
1648 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1649 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1651 copy_files_btn.set_active (true);
1653 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1656 copy_label->set_size_request (175, -1);
1657 copy_label->set_line_wrap (true);
1660 block_four.pack_start (copy_files_btn, false, false);
1662 options.pack_start (block_four, false, false);
1664 vpacker.pack_start (options, false, false);
1666 /* setup disposition map */
1668 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1669 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1670 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1671 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1673 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1674 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1675 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1676 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1678 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1680 /* set size requests for a couple of combos to allow them to display the longest text
1681 they will ever be asked to display. This prevents them being resized when the user
1682 selects a file to import, which in turn prevents the size of the dialog from jumping
1686 t.push_back (_("one track per file"));
1687 t.push_back (_("one track per channel"));
1688 t.push_back (_("sequence files"));
1689 t.push_back (_("all files in one region"));
1690 set_popdown_strings (channel_combo, t);
1693 t.push_back (importmode2string (ImportAsTrack));
1694 t.push_back (importmode2string (ImportToTrack));
1695 t.push_back (importmode2string (ImportAsRegion));
1696 t.push_back (importmode2string (ImportAsTapeTrack));
1697 set_popdown_strings (action_combo, t);
1701 SoundFileOmega::set_mode (ImportMode mode)
1703 action_combo.set_active_text (importmode2string (mode));
1707 SoundFileOmega::get_mode () const
1709 return string2importmode (action_combo.get_active_text());
1713 SoundFileOmega::on_hide ()
1715 ArdourWindow::on_hide();
1717 _session->cancel_audition();
1722 SoundFileOmega::get_position() const
1724 string str = where_combo.get_active_text();
1726 if (str == _("file timestamp")) {
1727 return ImportAtTimestamp;
1728 } else if (str == _("edit point")) {
1729 return ImportAtEditPoint;
1730 } else if (str == _("playhead")) {
1731 return ImportAtPlayhead;
1733 return ImportAtStart;
1738 SoundFileOmega::get_src_quality() const
1740 string str = src_combo.get_active_text();
1742 if (str == _("Best")) {
1744 } else if (str == _("Good")) {
1746 } else if (str == _("Quick")) {
1748 } else if (str == _("Fast")) {
1756 SoundFileOmega::get_channel_disposition () const
1758 /* we use a map here because the channel combo can contain different strings
1759 depending on the state of the other combos. the map contains all possible strings
1760 and the ImportDisposition enum that corresponds to it.
1763 string str = channel_combo.get_active_text();
1764 DispositionMap::const_iterator x = disposition_map.find (str);
1766 if (x == disposition_map.end()) {
1767 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1775 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1777 selected_audio_track_cnt = selected_audio_tracks;
1778 selected_midi_track_cnt = selected_midi_tracks;
1780 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1781 chooser.set_filter (midi_filter);
1782 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1783 chooser.set_filter (audio_filter);
1785 chooser.set_filter (audio_and_midi_filter);
1792 SoundFileOmega::file_selection_changed ()
1794 if (resetting_ourselves) {
1798 if (!reset_options ()) {
1799 set_action_sensitive (false);
1801 if (chooser.get_filenames().size() > 0) {
1802 set_action_sensitive (true);
1804 set_action_sensitive (false);
1810 SoundFileOmega::do_something (int action)
1812 SoundFileBrowser::do_something (action);
1814 if (action == RESPONSE_CANCEL) {
1821 vector<string> paths = get_paths ();
1822 ImportPosition pos = get_position ();
1823 ImportMode mode = get_mode ();
1824 ImportDisposition chns = get_channel_disposition ();
1828 case ImportAtEditPoint:
1829 where = PublicEditor::instance().get_preferred_edit_position ();
1831 case ImportAtTimestamp:
1834 case ImportAtPlayhead:
1835 where = _session->transport_frame();
1838 where = _session->current_start_frame();
1842 SrcQuality quality = get_src_quality();
1844 if (copy_files_btn.get_active()) {
1845 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1847 PublicEditor::instance().do_embed (paths, chns, mode, where);
1850 if (action == RESPONSE_OK) {