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"
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"
67 #include "sfdb_freesound_mootcher.h"
71 using namespace ARDOUR;
75 using namespace Gtkmm2ext;
76 using namespace Editing;
80 string SoundFileBrowser::persistent_folder;
81 typedef TreeView::Selection::ListHandle_Path ListPath;
84 string2importmode (string str)
86 if (str == _("as new tracks")) {
88 } else if (str == _("to selected tracks")) {
90 } else if (str == _("to region list")) {
91 return ImportAsRegion;
92 } else if (str == _("as new tape tracks")) {
93 return ImportAsTapeTrack;
96 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
102 importmode2string (ImportMode mode)
106 return _("as new tracks");
108 return _("to selected tracks");
110 return _("to region list");
111 case ImportAsTapeTrack:
112 return _("as new tape tracks");
115 return _("as new tracks");
118 SoundFileBox::SoundFileBox (bool persistent)
120 length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
121 timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
123 autoplay_btn (_("Auto-play")),
124 seek_slider(0,1000,1),
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 seek_slider.set_draw_value(false);
205 seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
206 seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
207 seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
208 main_box.pack_start (seek_slider, false, false);
210 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
211 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
213 stop_btn.set_sensitive (false);
215 channels_value.set_alignment (0.0f, 0.5f);
216 samplerate_value.set_alignment (0.0f, 0.5f);
220 SoundFileBox::set_session(Session* s)
222 SessionHandlePtr::set_session (s);
224 length_clock.set_session (s);
225 timecode_clock.set_session (s);
228 play_btn.set_sensitive (false);
229 stop_btn.set_sensitive (false);
230 auditioner_connections.drop_connections();
232 auditioner_connections.drop_connections();
233 _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
234 _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
239 SoundFileBox::audition_active(bool active) {
240 stop_btn.set_sensitive (active);
241 seek_slider.set_sensitive (active);
243 seek_slider.set_value(0);
248 SoundFileBox::audition_progress(ARDOUR::framecnt_t pos, ARDOUR::framecnt_t len) {
250 seek_slider.set_value( 1000.0 * pos / len);
251 seek_slider.set_sensitive (true);
256 SoundFileBox::seek_button_press(GdkEventButton*) {
258 return false; // pass on to slider
262 SoundFileBox::seek_button_release(GdkEventButton*) {
264 _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
265 seek_slider.set_sensitive (false);
266 return false; // pass on to slider
270 SoundFileBox::setup_labels (const string& filename)
273 // save existing tags
281 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
283 preview_label.set_markup (_("<b>Sound File Information</b>"));
284 format_text.set_text ("");
285 channels_value.set_text ("");
286 samplerate_value.set_text ("");
287 tags_entry.get_buffer()->set_text ("");
289 length_clock.set (0);
290 timecode_clock.set (0);
292 tags_entry.set_sensitive (false);
293 play_btn.set_sensitive (false);
298 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
299 std::string n = sf_info.format_name;
300 if (n.substr (0, 8) == X_("Format: ")) {
303 format_text.set_text (n);
304 channels_value.set_text (to_string (sf_info.channels, std::dec));
306 if (_session && sf_info.samplerate != _session->frame_rate()) {
307 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
308 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
309 samplerate_value.set_name ("NewSessionSR1Label");
310 samplerate.set_name ("NewSessionSR1Label");
312 samplerate.set_text (_("Sample rate:"));
313 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
314 samplerate_value.set_name ("NewSessionSR2Label");
315 samplerate.set_name ("NewSessionSR2Label");
318 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
319 double src_coef = (double) nfr / sf_info.samplerate;
321 length_clock.set (sf_info.length * src_coef + 0.5, true);
322 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
324 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
326 vector<string> tags = Library->get_tags (string ("//") + filename);
328 stringstream tag_string;
329 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
330 if (i != tags.begin()) {
335 tags_entry.get_buffer()->set_text (tag_string.str());
337 tags_entry.set_sensitive (true);
339 play_btn.set_sensitive (true);
346 SoundFileBox::autoplay() const
348 return autoplay_btn.get_active();
352 SoundFileBox::audition_oneshot()
359 SoundFileBox::audition ()
365 if (SMFSource::safe_midi_file_extension (path)) {
366 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
370 _session->cancel_audition();
372 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
373 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
377 boost::shared_ptr<Region> r;
379 boost::shared_ptr<AudioFileSource> afs;
380 bool old_sbp = AudioSource::get_build_peakfiles ();
382 /* don't even think of building peakfiles for these files */
384 AudioSource::set_build_peakfiles (false);
386 for (int n = 0; n < sf_info.channels; ++n) {
388 afs = boost::dynamic_pointer_cast<AudioFileSource> (
389 SourceFactory::createExternal (DataType::AUDIO, *_session,
391 Source::Flag (0), false));
393 srclist.push_back(afs);
395 } catch (failed_constructor& err) {
396 error << _("Could not access soundfile: ") << path << endmsg;
397 AudioSource::set_build_peakfiles (old_sbp);
402 AudioSource::set_build_peakfiles (old_sbp);
404 if (srclist.empty()) {
408 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
409 string rname = region_name_from_path (afs->path(), false);
413 plist.add (ARDOUR::Properties::start, 0);
414 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
415 plist.add (ARDOUR::Properties::name, rname);
416 plist.add (ARDOUR::Properties::layer, 0);
418 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
420 _session->audition_region(r);
424 SoundFileBox::stop_audition ()
427 _session->cancel_audition();
432 SoundFileBox::tags_entry_left (GdkEventFocus *)
439 SoundFileBox::tags_changed ()
441 string tag_string = tags_entry.get_buffer()->get_text ();
443 if (tag_string.empty()) {
449 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
450 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
458 SoundFileBox::save_tags (const vector<string>& tags)
460 Library->set_tags (string ("//") + path, tags);
461 Library->save_changes ();
464 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
465 : ArdourWindow (title)
466 , found_list (ListStore::create(found_list_columns))
467 , freesound_list (ListStore::create(freesound_list_columns))
468 , chooser (FILE_CHOOSER_ACTION_OPEN)
469 , preview (persistent)
470 , found_search_btn (_("Search"))
471 , found_list_view (found_list)
472 , freesound_search_btn (_("Search"))
473 , freesound_list_view (freesound_list)
474 , resetting_ourselves (false)
478 , ok_button (Stock::OK)
479 , cancel_button (Stock::CANCEL)
480 , apply_button (Stock::APPLY)
485 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
486 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
487 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
488 chooser.add_shortcut_folder_uri("file:///Volumes");
491 //add the file chooser
493 chooser.set_border_width (12);
495 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
496 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
498 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
499 audio_filter.set_name (_("Audio files"));
501 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
502 midi_filter.set_name (_("MIDI files"));
504 matchall_filter.add_pattern ("*.*");
505 matchall_filter.set_name (_("All files"));
507 chooser.add_filter (audio_and_midi_filter);
508 chooser.add_filter (audio_filter);
509 chooser.add_filter (midi_filter);
510 chooser.add_filter (matchall_filter);
511 chooser.set_select_multiple (true);
512 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
513 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
516 /* some broken redraw behaviour - this is a bandaid */
517 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
520 if (!persistent_folder.empty()) {
521 chooser.set_current_folder (persistent_folder);
524 notebook.append_page (chooser, _("Browse Files"));
526 hpacker.set_spacing (6);
527 hpacker.pack_start (notebook, true, true);
528 hpacker.pack_start (preview, false, false);
530 vpacker.set_spacing (6);
531 vpacker.pack_start (hpacker, true, true);
541 hbox = manage(new HBox);
542 hbox->pack_start (found_entry);
543 hbox->pack_start (found_search_btn);
545 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
546 scroll->add(found_list_view);
547 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
549 vbox = manage(new VBox);
550 vbox->pack_start (*hbox, PACK_SHRINK);
551 vbox->pack_start (*scroll);
553 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
555 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
557 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
559 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
560 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
562 notebook.append_page (*vbox, _("Search Tags"));
564 //add freesound search
569 passbox = manage(new HBox);
570 passbox->set_spacing (6);
572 label = manage (new Label);
573 label->set_text (_("Tags:"));
574 passbox->pack_start (*label, false, false);
575 passbox->pack_start (freesound_entry, true, true);
577 label = manage (new Label);
578 label->set_text (_("Sort:"));
579 passbox->pack_start (*label, false, false);
580 passbox->pack_start (freesound_sort, false, false);
581 freesound_sort.clear_items();
583 // Order of the following must correspond with enum sortMethod
584 // in sfdb_freesound_mootcher.h
585 freesound_sort.append_text(_("None"));
586 freesound_sort.append_text(_("Longest"));
587 freesound_sort.append_text(_("Shortest"));
588 freesound_sort.append_text(_("Newest"));
589 freesound_sort.append_text(_("Oldest"));
590 freesound_sort.append_text(_("Most downloaded"));
591 freesound_sort.append_text(_("Least downloaded"));
592 freesound_sort.append_text(_("Highest rated"));
593 freesound_sort.append_text(_("Lowest rated"));
594 freesound_sort.set_active(0);
596 passbox->pack_start (freesound_search_btn, false, false);
597 passbox->pack_start (freesound_more_btn, false, false);
598 freesound_more_btn.set_label(_("More"));
599 freesound_more_btn.set_sensitive(false);
601 passbox->pack_start (freesound_similar_btn, false, false);
602 freesound_similar_btn.set_label(_("Similar"));
603 freesound_similar_btn.set_sensitive(false);
605 scroll = manage(new ScrolledWindow);
606 scroll->add(freesound_list_view);
607 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
609 vbox = manage(new VBox);
610 vbox->set_spacing (3);
611 vbox->pack_start (*passbox, PACK_SHRINK);
612 vbox->pack_start (*scroll);
614 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
615 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
616 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
617 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
618 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
619 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
620 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
621 freesound_list_view.get_column(0)->set_alignment(0.5);
622 freesound_list_view.get_column(1)->set_expand(true); // filename
623 freesound_list_view.get_column(1)->set_resizable(true); // filename
624 freesound_list_view.get_column(2)->set_alignment(0.5);
625 freesound_list_view.get_column(3)->set_alignment(0.5);
626 freesound_list_view.get_column(4)->set_alignment(0.5);
627 freesound_list_view.get_column(5)->set_alignment(0.5);
629 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
630 freesound_list_view.set_tooltip_column(1);
632 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
633 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
634 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
635 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
636 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
637 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
638 notebook.append_page (*vbox, _("Search Freesound"));
640 notebook.set_size_request (500, -1);
641 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
645 Gtk::HButtonBox* button_box = manage (new HButtonBox);
647 button_box->set_layout (BUTTONBOX_END);
648 button_box->pack_start (cancel_button, false, false);
649 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
651 button_box->pack_start (apply_button, false, false);
652 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
655 button_box->pack_start (ok_button, false, false);
656 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
658 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
659 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
660 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
662 vpacker.pack_end (*button_box, false, false);
664 set_wmclass (X_("import"), PROGRAM_NAME);
667 SoundFileBrowser::~SoundFileBrowser ()
669 persistent_folder = chooser.get_current_folder();
673 SoundFileBrowser::run ()
682 gtk_main_iteration ();
689 SoundFileBrowser::set_action_sensitive (bool yn)
691 ok_button.set_sensitive (yn);
692 apply_button.set_sensitive (yn);
696 SoundFileBrowser::do_something (int action)
703 SoundFileBrowser::on_show ()
705 ArdourWindow::on_show ();
710 SoundFileBrowser::clear_selection ()
712 chooser.unselect_all ();
713 found_list_view.get_selection()->unselect_all ();
717 SoundFileBrowser::chooser_file_activated ()
723 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
729 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
735 SoundFileBrowser::set_session (Session* s)
737 ArdourWindow::set_session (s);
738 preview.set_session (s);
743 remove_gain_meter ();
748 SoundFileBrowser::add_gain_meter ()
752 gm = new GainMeter (_session, 250);
754 boost::shared_ptr<Route> r = _session->the_auditioner ();
756 gm->set_controls (r, r->shared_peak_meter(), r->amp());
757 gm->set_fader_name (X_("GainFader"));
759 meter_packer.set_border_width (12);
760 meter_packer.pack_start (*gm, false, true);
761 hpacker.pack_end (meter_packer, false, false);
762 meter_packer.show_all ();
767 SoundFileBrowser::remove_gain_meter ()
770 meter_packer.remove (*gm);
771 hpacker.remove (meter_packer);
778 SoundFileBrowser::start_metering ()
780 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
784 SoundFileBrowser::stop_metering ()
786 metering_connection.disconnect();
790 SoundFileBrowser::meter ()
792 if (is_mapped () && _session && gm) {
793 gm->update_meters ();
798 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
800 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
804 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
806 return SMFSource::safe_midi_file_extension (filter_info.filename);
810 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
812 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
816 SoundFileBrowser::update_preview ()
818 if (preview.setup_labels (chooser.get_preview_filename())) {
819 if (preview.autoplay()) {
820 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
826 SoundFileBrowser::found_list_view_selected ()
828 if (!reset_options ()) {
829 set_action_sensitive (false);
833 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
836 TreeIter iter = found_list->get_iter(*rows.begin());
837 file = (*iter)[found_list_columns.pathname];
838 chooser.set_filename (file);
839 set_action_sensitive (true);
841 set_action_sensitive (false);
844 preview.setup_labels (file);
849 SoundFileBrowser::found_search_clicked ()
851 string tag_string = found_entry.get_text ();
855 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
856 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
860 vector<string> results;
861 Library->search_members_and (results, tags);
864 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
865 TreeModel::iterator new_row = found_list->append();
866 TreeModel::Row row = *new_row;
867 string path = Glib::filename_from_uri (string ("file:") + *i);
868 row[found_list_columns.pathname] = path;
874 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
877 Mootcher *mootcher = new Mootcher;
880 string id = (*iter)[freesound_list_columns.id];
881 string uri = (*iter)[freesound_list_columns.uri];
882 string ofn = (*iter)[freesound_list_columns.filename];
884 if (mootcher->checkAudioFile(ofn, id)) {
885 // file already exists, no need to download it again
886 file = mootcher->audioFileName;
888 (*iter)[freesound_list_columns.started] = false;
891 if (!(*iter)[freesound_list_columns.started]) {
892 // start downloading the sound file
893 (*iter)[freesound_list_columns.started] = true;
894 mootcher->fetchAudioFile(ofn, id, uri, this);
900 SoundFileBrowser::freesound_list_view_selected ()
903 if (!reset_options ()) {
904 set_action_sensitive (false);
907 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
908 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
909 file = freesound_get_audio_file (freesound_list->get_iter(*i));
912 switch (rows.size()) {
915 freesound_similar_btn.set_sensitive(false);
916 set_action_sensitive (false);
919 // exactly one item selected
921 // file exists on disk already
922 chooser.set_filename (file);
923 preview.setup_labels (file);
924 set_action_sensitive (true);
926 freesound_similar_btn.set_sensitive(true);
929 // multiple items selected
930 preview.setup_labels ("");
931 freesound_similar_btn.set_sensitive(false);
939 SoundFileBrowser::refresh_display(std::string ID, std::string file)
941 // called when the mootcher has finished downloading a file
942 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
943 if (rows.size() == 1) {
944 // there's a single item selected in the freesound list
945 //XXX make a function to be used to construct the actual file name both here and in the mootcher
946 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
947 std::string selected_ID = (*row)[freesound_list_columns.id];
948 if (ID == selected_ID) {
949 // the selected item in the freesound list is the item that has just finished downloading
950 chooser.set_filename(file);
951 preview.setup_labels (file);
952 set_action_sensitive (true);
958 SoundFileBrowser::freesound_search_clicked ()
961 freesound_list->clear();
967 SoundFileBrowser::freesound_more_clicked ()
972 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
973 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
977 SoundFileBrowser::freesound_similar_clicked ()
979 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
980 if (rows.size() == 1) {
983 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
984 id = (*iter)[freesound_list_columns.id];
985 freesound_list->clear();
987 GdkCursor *prev_cursor;
988 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
989 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
992 std::string theString = mootcher.searchSimilar(id);
994 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
995 handle_freesound_results(theString);
1000 SoundFileBrowser::freesound_search()
1004 string search_string = freesound_entry.get_text ();
1005 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1007 GdkCursor *prev_cursor;
1008 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1009 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1012 std::string theString = mootcher.searchText(
1016 "", // OSX eats anything incl mp3
1018 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1023 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1024 handle_freesound_results(theString);
1028 SoundFileBrowser::handle_freesound_results(std::string theString) {
1030 doc.read_buffer( theString );
1031 XMLNode *root = doc.root();
1034 error << "no root XML node!" << endmsg;
1038 if ( strcmp(root->name().c_str(), "response") != 0) {
1039 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1043 // find out how many pages are available to search
1044 int freesound_n_pages = 1;
1045 XMLNode *res = root->child("num_pages");
1047 string result = res->child("text")->content();
1048 freesound_n_pages = atoi(result);
1051 int more_pages = freesound_n_pages - freesound_page;
1053 if (more_pages > 0) {
1054 freesound_more_btn.set_sensitive(true);
1055 freesound_more_btn.set_tooltip_text(string_compose(P_(
1056 "%1 more page of 100 results available",
1057 "%1 more pages of 100 results available",
1058 more_pages), more_pages));
1060 freesound_more_btn.set_sensitive(false);
1061 freesound_more_btn.set_tooltip_text(_("No more results available"));
1064 XMLNode *sounds_root = root->child("sounds");
1066 error << "no child node \"sounds\" found!" << endmsg;
1070 XMLNodeList sounds = sounds_root->children();
1071 if (sounds.size() == 0) {
1076 XMLNodeConstIterator niter;
1078 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1080 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1081 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1085 // node->dump(cerr, "node:");
1088 XMLNode *id_node = node->child ("id");
1089 XMLNode *uri_node = node->child ("serve");
1090 XMLNode *ofn_node = node->child ("original_filename");
1091 XMLNode *dur_node = node->child ("duration");
1092 XMLNode *siz_node = node->child ("filesize");
1093 XMLNode *srt_node = node->child ("samplerate");
1094 XMLNode *lic_node = node->child ("license");
1096 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1098 std::string id = id_node->child("text")->content();
1099 std::string uri = uri_node->child("text")->content();
1100 std::string ofn = ofn_node->child("text")->content();
1101 std::string dur = dur_node->child("text")->content();
1102 std::string siz = siz_node->child("text")->content();
1103 std::string srt = srt_node->child("text")->content();
1104 std::string lic = lic_node->child("text")->content();
1107 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1109 double duration_seconds = atof(dur);
1111 char duration_hhmmss[16];
1112 if (duration_seconds >= 99 * 60 * 60) {
1113 strcpy(duration_hhmmss, ">99h");
1115 s = modf(duration_seconds/60, &m) * 60;
1116 m = modf(m/60, &h) * 60;
1117 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1122 double size_bytes = atof(siz);
1124 if (size_bytes < 1000) {
1125 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1126 } else if (size_bytes < 1000000 ) {
1127 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1128 } else if (size_bytes < 10000000) {
1129 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1130 } else if (size_bytes < 1000000000) {
1131 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1133 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1136 /* see http://www.freesound.org/help/faq/#licenses */
1137 char shortlicense[64];
1138 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1139 sprintf(shortlicense, "CC-BY-NC");
1140 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1141 sprintf(shortlicense, "CC-BY");
1142 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1143 sprintf(shortlicense, "sampling+");
1144 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1145 sprintf(shortlicense, "PD");
1147 snprintf(shortlicense, 64, "%s", lic.c_str());
1148 shortlicense[63]= '\0';
1151 TreeModel::iterator new_row = freesound_list->append();
1152 TreeModel::Row row = *new_row;
1154 row[freesound_list_columns.id ] = id;
1155 row[freesound_list_columns.uri ] = uri;
1156 row[freesound_list_columns.filename] = ofn;
1157 row[freesound_list_columns.duration] = duration_hhmmss;
1158 row[freesound_list_columns.filesize] = bsize;
1159 row[freesound_list_columns.smplrate] = srt;
1160 row[freesound_list_columns.license ] = shortlicense;
1167 SoundFileBrowser::get_paths ()
1169 vector<string> results;
1171 int n = notebook.get_current_page ();
1174 vector<string> filenames = chooser.get_filenames();
1175 vector<string>::iterator i;
1177 for (i = filenames.begin(); i != filenames.end(); ++i) {
1179 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1180 results.push_back (*i);
1184 } else if (n == 1) {
1186 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1187 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1188 TreeIter iter = found_list->get_iter(*i);
1189 string str = (*iter)[found_list_columns.pathname];
1191 results.push_back (str);
1194 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1195 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1196 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1198 results.push_back (str);
1207 SoundFileOmega::reset_options_noret ()
1209 if (!resetting_ourselves) {
1210 (void) reset_options ();
1215 SoundFileOmega::reset_options ()
1217 vector<string> paths = get_paths ();
1219 if (paths.empty()) {
1221 channel_combo.set_sensitive (false);
1222 action_combo.set_sensitive (false);
1223 where_combo.set_sensitive (false);
1224 copy_files_btn.set_active (true);
1225 copy_files_btn.set_sensitive (false);
1231 channel_combo.set_sensitive (true);
1232 action_combo.set_sensitive (true);
1233 where_combo.set_sensitive (true);
1235 /* if we get through this function successfully, this may be
1236 reset at the end, once we know if we can use hard links
1237 to do embedding (or if we are importing a MIDI file).
1240 if (Config->get_only_copy_imported_files()) {
1241 copy_files_btn.set_sensitive (false);
1243 copy_files_btn.set_sensitive (false);
1249 bool selection_includes_multichannel;
1250 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1253 /* See if we are thinking about importing any MIDI files */
1254 vector<string>::iterator i = paths.begin ();
1255 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1258 bool const have_a_midi_file = (i != paths.end ());
1260 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1261 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1265 string existing_choice;
1266 vector<string> action_strings;
1268 resetting_ourselves = true;
1270 if (chooser.get_filter() == &audio_filter) {
1274 if (selected_audio_track_cnt > 0) {
1275 if (channel_combo.get_active_text().length()) {
1276 ImportDisposition id = get_channel_disposition();
1279 case Editing::ImportDistinctFiles:
1280 if (selected_audio_track_cnt == paths.size()) {
1281 action_strings.push_back (importmode2string (ImportToTrack));
1285 case Editing::ImportDistinctChannels:
1286 /* XXX it would be nice to allow channel-per-selected track
1287 but its too hard we don't want to deal with all the
1288 different per-file + per-track channel configurations.
1293 action_strings.push_back (importmode2string (ImportToTrack));
1303 if (selected_midi_track_cnt > 0) {
1304 action_strings.push_back (importmode2string (ImportToTrack));
1308 action_strings.push_back (importmode2string (ImportAsTrack));
1309 action_strings.push_back (importmode2string (ImportAsRegion));
1310 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1312 existing_choice = action_combo.get_active_text();
1314 set_popdown_strings (action_combo, action_strings);
1316 /* preserve any existing choice, if possible */
1319 if (existing_choice.length()) {
1320 vector<string>::iterator x;
1321 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1322 if (*x == existing_choice) {
1323 action_combo.set_active_text (existing_choice);
1327 if (x == action_strings.end()) {
1328 action_combo.set_active_text (action_strings.front());
1331 action_combo.set_active_text (action_strings.front());
1334 resetting_ourselves = false;
1336 if ((mode = get_mode()) == ImportAsRegion) {
1337 where_combo.set_sensitive (false);
1339 where_combo.set_sensitive (true);
1342 vector<string> channel_strings;
1344 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1345 channel_strings.push_back (_("one track per file"));
1347 if (selection_includes_multichannel) {
1348 channel_strings.push_back (_("one track per channel"));
1351 if (paths.size() > 1) {
1352 /* tape tracks are a single region per track, so we cannot
1353 sequence multiple files.
1355 if (mode != ImportAsTapeTrack) {
1356 channel_strings.push_back (_("sequence files"));
1359 channel_strings.push_back (_("all files in one track"));
1360 channel_strings.push_back (_("merge files"));
1366 channel_strings.push_back (_("one region per file"));
1368 if (selection_includes_multichannel) {
1369 channel_strings.push_back (_("one region per channel"));
1372 if (paths.size() > 1) {
1374 channel_strings.push_back (_("all files in one region"));
1379 resetting_ourselves = true;
1381 existing_choice = channel_combo.get_active_text();
1383 set_popdown_strings (channel_combo, channel_strings);
1385 /* preserve any existing choice, if possible */
1387 if (existing_choice.length()) {
1388 vector<string>::iterator x;
1389 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1390 if (*x == existing_choice) {
1391 channel_combo.set_active_text (existing_choice);
1395 if (x == channel_strings.end()) {
1396 channel_combo.set_active_text (channel_strings.front());
1399 channel_combo.set_active_text (channel_strings.front());
1402 resetting_ourselves = false;
1405 src_combo.set_sensitive (true);
1407 src_combo.set_sensitive (false);
1410 /* We must copy MIDI files or those from Freesound
1411 * or any file if we are under nsm control */
1412 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1414 if (Config->get_only_copy_imported_files()) {
1416 if (selection_can_be_embedded_with_links && !must_copy) {
1417 copy_files_btn.set_sensitive (true);
1420 copy_files_btn.set_active (true);
1422 copy_files_btn.set_sensitive (false);
1428 copy_files_btn.set_active (true);
1430 copy_files_btn.set_sensitive (!must_copy);
1438 SoundFileOmega::bad_file_message()
1440 MessageDialog msg (*this,
1441 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1446 resetting_ourselves = true;
1447 chooser.unselect_uri (chooser.get_preview_uri());
1448 resetting_ourselves = false;
1454 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1463 multichannel = false;
1465 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1467 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1468 if (info.channels > 1) {
1469 multichannel = true;
1474 if (sz != info.length) {
1479 if (info.samplerate != _session->frame_rate()) {
1483 } else if (SMFSource::safe_midi_file_extension (*i)) {
1487 if (reader.num_tracks() > 1) {
1488 multichannel = true; // "channel" == track here...
1491 /* XXX we need err = true handling here in case
1492 we can't check the file
1505 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1507 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1510 if (mkdir (tmpdir.c_str(), 0744)) {
1511 if (errno != EEXIST) {
1516 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1518 char tmpc[PATH_MAX+1];
1520 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1524 if (link ((*i).c_str(), tmpc)) {
1534 rmdir (tmpdir.c_str());
1538 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1539 : SoundFileBrowser (title, s, false)
1541 chooser.set_select_multiple (false);
1542 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1543 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1547 SoundFileChooser::on_hide ()
1549 ArdourWindow::on_hide();
1553 _session->cancel_audition();
1558 SoundFileChooser::get_filename ()
1560 vector<string> paths;
1562 paths = get_paths ();
1564 if (paths.empty()) {
1568 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1572 return paths.front();
1575 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1576 uint32_t selected_audio_tracks,
1577 uint32_t selected_midi_tracks,
1579 Editing::ImportMode mode_hint)
1580 : SoundFileBrowser (title, s, persistent)
1581 , copy_files_btn ( _("Copy files to session"))
1582 , selected_audio_track_cnt (selected_audio_tracks)
1583 , selected_midi_track_cnt (selected_midi_tracks)
1589 set_size_request (-1, 450);
1591 block_two.set_border_width (12);
1592 block_three.set_border_width (12);
1593 block_four.set_border_width (12);
1595 options.set_spacing (12);
1598 str.push_back (_("file timestamp"));
1599 str.push_back (_("edit point"));
1600 str.push_back (_("playhead"));
1601 str.push_back (_("session start"));
1602 set_popdown_strings (where_combo, str);
1603 where_combo.set_active_text (str.front());
1605 Label* l = manage (new Label);
1606 l->set_markup (_("<b>Add files as ...</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 (action_combo, false, false);
1613 hbox = manage (new HBox);
1614 hbox->pack_start (*vbox, false, false);
1615 options.pack_start (*hbox, false, false);
1617 /* dummy entry for action combo so that it doesn't look odd if we
1618 come up with no tracks selected.
1622 str.push_back (importmode2string (mode_hint));
1623 set_popdown_strings (action_combo, str);
1624 action_combo.set_active_text (str.front());
1625 action_combo.set_sensitive (false);
1627 l = manage (new Label);
1628 l->set_markup (_("<b>Insert at</b>"));
1630 vbox = manage (new VBox);
1631 vbox->set_border_width (12);
1632 vbox->set_spacing (6);
1633 vbox->pack_start (*l, false, false);
1634 vbox->pack_start (where_combo, false, false);
1635 hbox = manage (new HBox);
1636 hbox->pack_start (*vbox, false, false);
1637 options.pack_start (*hbox, false, false);
1640 l = manage (new Label);
1641 l->set_markup (_("<b>Mapping</b>"));
1643 vbox = manage (new VBox);
1644 vbox->set_border_width (12);
1645 vbox->set_spacing (6);
1646 vbox->pack_start (*l, false, false);
1647 vbox->pack_start (channel_combo, false, false);
1648 hbox = manage (new HBox);
1649 hbox->pack_start (*vbox, false, false);
1650 options.pack_start (*hbox, false, false);
1653 str.push_back (_("one track per file"));
1654 set_popdown_strings (channel_combo, str);
1655 channel_combo.set_active_text (str.front());
1656 channel_combo.set_sensitive (false);
1658 l = manage (new Label);
1659 l->set_markup (_("<b>Conversion quality</b>"));
1661 vbox = manage (new VBox);
1662 vbox->set_border_width (12);
1663 vbox->set_spacing (6);
1664 vbox->pack_start (*l, false, false);
1665 vbox->pack_start (src_combo, false, false);
1666 hbox = manage (new HBox);
1667 hbox->pack_start (*vbox, false, false);
1668 options.pack_start (*hbox, false, false);
1671 str.push_back (_("Best"));
1672 str.push_back (_("Good"));
1673 str.push_back (_("Quick"));
1674 str.push_back (_("Fast"));
1675 str.push_back (_("Fastest"));
1677 set_popdown_strings (src_combo, str);
1678 src_combo.set_active_text (str.front());
1679 src_combo.set_sensitive (false);
1683 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1684 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1686 copy_files_btn.set_active (true);
1688 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1691 copy_label->set_size_request (175, -1);
1692 copy_label->set_line_wrap (true);
1695 block_four.pack_start (copy_files_btn, false, false);
1697 options.pack_start (block_four, false, false);
1699 vpacker.pack_start (options, false, false);
1701 /* setup disposition map */
1703 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1704 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1705 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1706 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1708 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1709 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1710 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1711 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1713 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1715 /* set size requests for a couple of combos to allow them to display the longest text
1716 they will ever be asked to display. This prevents them being resized when the user
1717 selects a file to import, which in turn prevents the size of the dialog from jumping
1721 t.push_back (_("one track per file"));
1722 t.push_back (_("one track per channel"));
1723 t.push_back (_("sequence files"));
1724 t.push_back (_("all files in one region"));
1725 set_popdown_strings (channel_combo, t);
1728 t.push_back (importmode2string (ImportAsTrack));
1729 t.push_back (importmode2string (ImportToTrack));
1730 t.push_back (importmode2string (ImportAsRegion));
1731 t.push_back (importmode2string (ImportAsTapeTrack));
1732 set_popdown_strings (action_combo, t);
1736 SoundFileOmega::set_mode (ImportMode mode)
1738 action_combo.set_active_text (importmode2string (mode));
1742 SoundFileOmega::get_mode () const
1744 return string2importmode (action_combo.get_active_text());
1748 SoundFileOmega::on_hide ()
1750 ArdourWindow::on_hide();
1752 _session->cancel_audition();
1757 SoundFileOmega::get_position() const
1759 string str = where_combo.get_active_text();
1761 if (str == _("file timestamp")) {
1762 return ImportAtTimestamp;
1763 } else if (str == _("edit point")) {
1764 return ImportAtEditPoint;
1765 } else if (str == _("playhead")) {
1766 return ImportAtPlayhead;
1768 return ImportAtStart;
1773 SoundFileOmega::get_src_quality() const
1775 string str = src_combo.get_active_text();
1777 if (str == _("Best")) {
1779 } else if (str == _("Good")) {
1781 } else if (str == _("Quick")) {
1783 } else if (str == _("Fast")) {
1791 SoundFileOmega::get_channel_disposition () const
1793 /* we use a map here because the channel combo can contain different strings
1794 depending on the state of the other combos. the map contains all possible strings
1795 and the ImportDisposition enum that corresponds to it.
1798 string str = channel_combo.get_active_text();
1799 DispositionMap::const_iterator x = disposition_map.find (str);
1801 if (x == disposition_map.end()) {
1802 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1810 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1812 selected_audio_track_cnt = selected_audio_tracks;
1813 selected_midi_track_cnt = selected_midi_tracks;
1815 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1816 chooser.set_filter (midi_filter);
1817 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1818 chooser.set_filter (audio_filter);
1820 chooser.set_filter (audio_and_midi_filter);
1827 SoundFileOmega::file_selection_changed ()
1829 if (resetting_ourselves) {
1833 if (!reset_options ()) {
1834 set_action_sensitive (false);
1836 if (chooser.get_filenames().size() > 0) {
1837 set_action_sensitive (true);
1839 set_action_sensitive (false);
1845 SoundFileOmega::do_something (int action)
1847 SoundFileBrowser::do_something (action);
1849 if (action == RESPONSE_CANCEL) {
1856 vector<string> paths = get_paths ();
1857 ImportPosition pos = get_position ();
1858 ImportMode mode = get_mode ();
1859 ImportDisposition chns = get_channel_disposition ();
1863 case ImportAtEditPoint:
1864 where = PublicEditor::instance().get_preferred_edit_position ();
1866 case ImportAtTimestamp:
1869 case ImportAtPlayhead:
1870 where = _session->transport_frame();
1873 where = _session->current_start_frame();
1877 SrcQuality quality = get_src_quality();
1879 if (copy_files_btn.get_active()) {
1880 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1882 PublicEditor::instance().do_embed (paths, chns, mode, where);
1885 if (action == RESPONSE_OK) {