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>
35 #include <glib/gstdio.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/convert.h"
39 #include "pbd/tokenizer.h"
40 #include "pbd/enumwriter.h"
41 #include "pbd/pthread_utils.h"
42 #include "pbd/xml++.h"
44 #include <gtkmm2ext/utils.h>
46 #include "evoral/SMF.hpp"
48 #include "ardour/audio_library.h"
49 #include "ardour/auditioner.h"
50 #include "ardour/audioregion.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/smf_source.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/source_factory.h"
55 #include "ardour/session.h"
56 #include "ardour/session_directory.h"
58 #include "ardour_ui.h"
60 #include "gui_thread.h"
65 #include "gain_meter.h"
66 #include "main_clock.h"
67 #include "public_editor.h"
69 #include "sfdb_freesound_mootcher.h"
73 using namespace ARDOUR;
77 using namespace Gtkmm2ext;
78 using namespace Editing;
82 string SoundFileBrowser::persistent_folder;
83 typedef TreeView::Selection::ListHandle_Path ListPath;
86 string2importmode (string str)
88 if (str == _("as new tracks")) {
90 } else if (str == _("to selected tracks")) {
92 } else if (str == _("to region list")) {
93 return ImportAsRegion;
94 } else if (str == _("as new tape tracks")) {
95 return ImportAsTapeTrack;
98 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
100 return ImportAsTrack;
104 importmode2string (ImportMode mode)
108 return _("as new tracks");
110 return _("to selected tracks");
112 return _("to region list");
113 case ImportAsTapeTrack:
114 return _("as new tape tracks");
117 return _("as new tracks");
120 SoundFileBox::SoundFileBox (bool persistent)
122 length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
123 timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
125 autoplay_btn (_("Auto-play")),
126 seek_slider(0,1000,1),
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 seek_slider.set_draw_value(false);
207 seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
208 seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
209 seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
210 main_box.pack_start (seek_slider, false, false);
212 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
213 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
215 stop_btn.set_sensitive (false);
217 channels_value.set_alignment (0.0f, 0.5f);
218 samplerate_value.set_alignment (0.0f, 0.5f);
222 SoundFileBox::set_session(Session* s)
224 SessionHandlePtr::set_session (s);
226 length_clock.set_session (s);
227 timecode_clock.set_session (s);
230 play_btn.set_sensitive (false);
231 stop_btn.set_sensitive (false);
232 auditioner_connections.drop_connections();
234 auditioner_connections.drop_connections();
235 _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
236 _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
241 SoundFileBox::audition_active(bool active) {
242 stop_btn.set_sensitive (active);
243 seek_slider.set_sensitive (active);
245 seek_slider.set_value(0);
250 SoundFileBox::audition_progress(ARDOUR::framecnt_t pos, ARDOUR::framecnt_t len) {
252 seek_slider.set_value( 1000.0 * pos / len);
253 seek_slider.set_sensitive (true);
258 SoundFileBox::seek_button_press(GdkEventButton*) {
260 return false; // pass on to slider
264 SoundFileBox::seek_button_release(GdkEventButton*) {
266 _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
267 seek_slider.set_sensitive (false);
268 return false; // pass on to slider
272 SoundFileBox::setup_labels (const string& filename)
275 // save existing tags
283 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
285 preview_label.set_markup (_("<b>Sound File Information</b>"));
286 format_text.set_text ("");
287 channels_value.set_text ("");
288 samplerate_value.set_text ("");
289 tags_entry.get_buffer()->set_text ("");
291 length_clock.set (0);
292 timecode_clock.set (0);
294 tags_entry.set_sensitive (false);
295 play_btn.set_sensitive (false);
300 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
301 std::string n = sf_info.format_name;
302 if (n.substr (0, 8) == X_("Format: ")) {
305 format_text.set_text (n);
306 channels_value.set_text (to_string (sf_info.channels, std::dec));
308 if (_session && sf_info.samplerate != _session->frame_rate()) {
309 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
310 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
311 samplerate_value.set_name ("NewSessionSR1Label");
312 samplerate.set_name ("NewSessionSR1Label");
314 samplerate.set_text (_("Sample rate:"));
315 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
316 samplerate_value.set_name ("NewSessionSR2Label");
317 samplerate.set_name ("NewSessionSR2Label");
320 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
321 double src_coef = (double) nfr / sf_info.samplerate;
323 length_clock.set (sf_info.length * src_coef + 0.5, true);
324 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
326 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
328 vector<string> tags = Library->get_tags (string ("//") + filename);
330 stringstream tag_string;
331 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
332 if (i != tags.begin()) {
337 tags_entry.get_buffer()->set_text (tag_string.str());
339 tags_entry.set_sensitive (true);
341 play_btn.set_sensitive (true);
348 SoundFileBox::autoplay() const
350 return autoplay_btn.get_active();
354 SoundFileBox::audition_oneshot()
361 SoundFileBox::audition ()
367 if (SMFSource::safe_midi_file_extension (path)) {
368 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
372 _session->cancel_audition();
374 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
375 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
379 boost::shared_ptr<Region> r;
381 boost::shared_ptr<AudioFileSource> afs;
382 bool old_sbp = AudioSource::get_build_peakfiles ();
384 /* don't even think of building peakfiles for these files */
386 AudioSource::set_build_peakfiles (false);
388 for (int n = 0; n < sf_info.channels; ++n) {
390 afs = boost::dynamic_pointer_cast<AudioFileSource> (
391 SourceFactory::createExternal (DataType::AUDIO, *_session,
393 Source::Flag (0), false));
395 srclist.push_back(afs);
397 } catch (failed_constructor& err) {
398 error << _("Could not access soundfile: ") << path << endmsg;
399 AudioSource::set_build_peakfiles (old_sbp);
404 AudioSource::set_build_peakfiles (old_sbp);
406 if (srclist.empty()) {
410 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
411 string rname = region_name_from_path (afs->path(), false);
415 plist.add (ARDOUR::Properties::start, 0);
416 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
417 plist.add (ARDOUR::Properties::name, rname);
418 plist.add (ARDOUR::Properties::layer, 0);
420 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
422 _session->audition_region(r);
426 SoundFileBox::stop_audition ()
429 _session->cancel_audition();
434 SoundFileBox::tags_entry_left (GdkEventFocus *)
441 SoundFileBox::tags_changed ()
443 string tag_string = tags_entry.get_buffer()->get_text ();
445 if (tag_string.empty()) {
451 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
452 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
460 SoundFileBox::save_tags (const vector<string>& tags)
462 Library->set_tags (string ("//") + path, tags);
463 Library->save_changes ();
466 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
467 : ArdourWindow (title)
468 , found_list (ListStore::create(found_list_columns))
469 , freesound_list (ListStore::create(freesound_list_columns))
470 , chooser (FILE_CHOOSER_ACTION_OPEN)
471 , preview (persistent)
472 , found_search_btn (_("Search"))
473 , found_list_view (found_list)
474 , freesound_search_btn (_("Search"))
475 , freesound_list_view (freesound_list)
476 , resetting_ourselves (false)
480 , ok_button (Stock::OK)
481 , cancel_button (Stock::CANCEL)
482 , apply_button (Stock::APPLY)
487 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
488 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
489 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
490 chooser.add_shortcut_folder_uri("file:///Volumes");
493 //add the file chooser
495 chooser.set_border_width (12);
497 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
498 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
500 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
501 audio_filter.set_name (_("Audio files"));
503 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
504 midi_filter.set_name (_("MIDI files"));
506 matchall_filter.add_pattern ("*.*");
507 matchall_filter.set_name (_("All files"));
509 chooser.add_filter (audio_and_midi_filter);
510 chooser.add_filter (audio_filter);
511 chooser.add_filter (midi_filter);
512 chooser.add_filter (matchall_filter);
513 chooser.set_select_multiple (true);
514 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
515 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
518 /* some broken redraw behaviour - this is a bandaid */
519 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
522 if (!persistent_folder.empty()) {
523 chooser.set_current_folder (persistent_folder);
526 notebook.append_page (chooser, _("Browse Files"));
528 hpacker.set_spacing (6);
529 hpacker.pack_start (notebook, true, true);
530 hpacker.pack_start (preview, false, false);
532 vpacker.set_spacing (6);
533 vpacker.pack_start (hpacker, true, true);
543 hbox = manage(new HBox);
544 hbox->pack_start (found_entry);
545 hbox->pack_start (found_search_btn);
547 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
548 scroll->add(found_list_view);
549 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
551 vbox = manage(new VBox);
552 vbox->pack_start (*hbox, PACK_SHRINK);
553 vbox->pack_start (*scroll);
555 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
557 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
559 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
561 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
562 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
564 notebook.append_page (*vbox, _("Search Tags"));
566 //add freesound search
571 passbox = manage(new HBox);
572 passbox->set_spacing (6);
574 label = manage (new Label);
575 label->set_text (_("Tags:"));
576 passbox->pack_start (*label, false, false);
577 passbox->pack_start (freesound_entry, true, true);
579 label = manage (new Label);
580 label->set_text (_("Sort:"));
581 passbox->pack_start (*label, false, false);
582 passbox->pack_start (freesound_sort, false, false);
583 freesound_sort.clear_items();
585 // Order of the following must correspond with enum sortMethod
586 // in sfdb_freesound_mootcher.h
587 freesound_sort.append_text(_("None"));
588 freesound_sort.append_text(_("Longest"));
589 freesound_sort.append_text(_("Shortest"));
590 freesound_sort.append_text(_("Newest"));
591 freesound_sort.append_text(_("Oldest"));
592 freesound_sort.append_text(_("Most downloaded"));
593 freesound_sort.append_text(_("Least downloaded"));
594 freesound_sort.append_text(_("Highest rated"));
595 freesound_sort.append_text(_("Lowest rated"));
596 freesound_sort.set_active(0);
598 passbox->pack_start (freesound_search_btn, false, false);
599 passbox->pack_start (freesound_more_btn, false, false);
600 freesound_more_btn.set_label(_("More"));
601 freesound_more_btn.set_sensitive(false);
603 passbox->pack_start (freesound_similar_btn, false, false);
604 freesound_similar_btn.set_label(_("Similar"));
605 freesound_similar_btn.set_sensitive(false);
607 scroll = manage(new ScrolledWindow);
608 scroll->add(freesound_list_view);
609 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
611 vbox = manage(new VBox);
612 vbox->set_spacing (3);
613 vbox->pack_start (*passbox, PACK_SHRINK);
614 vbox->pack_start (*scroll);
616 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
617 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
618 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
619 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
620 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
621 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
622 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
623 freesound_list_view.get_column(0)->set_alignment(0.5);
624 freesound_list_view.get_column(1)->set_expand(true); // filename
625 freesound_list_view.get_column(1)->set_resizable(true); // filename
626 freesound_list_view.get_column(2)->set_alignment(0.5);
627 freesound_list_view.get_column(3)->set_alignment(0.5);
628 freesound_list_view.get_column(4)->set_alignment(0.5);
629 freesound_list_view.get_column(5)->set_alignment(0.5);
631 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
632 freesound_list_view.set_tooltip_column(1);
634 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
635 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
636 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
637 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
638 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
639 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
640 notebook.append_page (*vbox, _("Search Freesound"));
642 notebook.set_size_request (500, -1);
643 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
647 Gtk::HButtonBox* button_box = manage (new HButtonBox);
649 button_box->set_layout (BUTTONBOX_END);
650 button_box->pack_start (cancel_button, false, false);
651 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
653 button_box->pack_start (apply_button, false, false);
654 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
657 button_box->pack_start (ok_button, false, false);
658 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
660 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
661 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
662 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
664 vpacker.pack_end (*button_box, false, false);
666 set_wmclass (X_("import"), PROGRAM_NAME);
669 SoundFileBrowser::~SoundFileBrowser ()
671 persistent_folder = chooser.get_current_folder();
675 SoundFileBrowser::run ()
684 gtk_main_iteration ();
691 SoundFileBrowser::set_action_sensitive (bool yn)
693 ok_button.set_sensitive (yn);
694 apply_button.set_sensitive (yn);
698 SoundFileBrowser::do_something (int action)
705 SoundFileBrowser::on_show ()
707 ArdourWindow::on_show ();
712 SoundFileBrowser::clear_selection ()
714 chooser.unselect_all ();
715 found_list_view.get_selection()->unselect_all ();
719 SoundFileBrowser::chooser_file_activated ()
725 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
731 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
737 SoundFileBrowser::set_session (Session* s)
739 ArdourWindow::set_session (s);
740 preview.set_session (s);
745 remove_gain_meter ();
750 SoundFileBrowser::add_gain_meter ()
754 gm = new GainMeter (_session, 250);
756 boost::shared_ptr<Route> r = _session->the_auditioner ();
758 gm->set_controls (r, r->shared_peak_meter(), r->amp());
759 gm->set_fader_name (X_("GainFader"));
761 meter_packer.set_border_width (12);
762 meter_packer.pack_start (*gm, false, true);
763 hpacker.pack_end (meter_packer, false, false);
764 meter_packer.show_all ();
769 SoundFileBrowser::remove_gain_meter ()
772 meter_packer.remove (*gm);
773 hpacker.remove (meter_packer);
780 SoundFileBrowser::start_metering ()
782 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
786 SoundFileBrowser::stop_metering ()
788 metering_connection.disconnect();
792 SoundFileBrowser::meter ()
794 if (is_mapped () && _session && gm) {
795 gm->update_meters ();
800 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
802 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
806 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
808 return SMFSource::safe_midi_file_extension (filter_info.filename);
812 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
814 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
818 SoundFileBrowser::update_preview ()
820 if (preview.setup_labels (chooser.get_preview_filename())) {
821 if (preview.autoplay()) {
822 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
828 SoundFileBrowser::found_list_view_selected ()
830 if (!reset_options ()) {
831 set_action_sensitive (false);
835 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
838 TreeIter iter = found_list->get_iter(*rows.begin());
839 file = (*iter)[found_list_columns.pathname];
840 chooser.set_filename (file);
841 set_action_sensitive (true);
843 set_action_sensitive (false);
846 preview.setup_labels (file);
851 SoundFileBrowser::found_search_clicked ()
853 string tag_string = found_entry.get_text ();
857 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
858 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
862 vector<string> results;
863 Library->search_members_and (results, tags);
866 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
867 TreeModel::iterator new_row = found_list->append();
868 TreeModel::Row row = *new_row;
869 string path = Glib::filename_from_uri (string ("file:") + *i);
870 row[found_list_columns.pathname] = path;
876 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
879 Mootcher *mootcher = new Mootcher;
882 string id = (*iter)[freesound_list_columns.id];
883 string uri = (*iter)[freesound_list_columns.uri];
884 string ofn = (*iter)[freesound_list_columns.filename];
886 if (mootcher->checkAudioFile(ofn, id)) {
887 // file already exists, no need to download it again
888 file = mootcher->audioFileName;
890 (*iter)[freesound_list_columns.started] = false;
893 if (!(*iter)[freesound_list_columns.started]) {
894 // start downloading the sound file
895 (*iter)[freesound_list_columns.started] = true;
896 mootcher->fetchAudioFile(ofn, id, uri, this);
902 SoundFileBrowser::freesound_list_view_selected ()
905 if (!reset_options ()) {
906 set_action_sensitive (false);
909 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
910 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
911 file = freesound_get_audio_file (freesound_list->get_iter(*i));
914 switch (rows.size()) {
917 freesound_similar_btn.set_sensitive(false);
918 set_action_sensitive (false);
921 // exactly one item selected
923 // file exists on disk already
924 chooser.set_filename (file);
925 preview.setup_labels (file);
926 set_action_sensitive (true);
928 freesound_similar_btn.set_sensitive(true);
931 // multiple items selected
932 preview.setup_labels ("");
933 freesound_similar_btn.set_sensitive(false);
941 SoundFileBrowser::refresh_display(std::string ID, std::string file)
943 // called when the mootcher has finished downloading a file
944 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
945 if (rows.size() == 1) {
946 // there's a single item selected in the freesound list
947 //XXX make a function to be used to construct the actual file name both here and in the mootcher
948 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
949 std::string selected_ID = (*row)[freesound_list_columns.id];
950 if (ID == selected_ID) {
951 // the selected item in the freesound list is the item that has just finished downloading
952 chooser.set_filename(file);
953 preview.setup_labels (file);
954 set_action_sensitive (true);
960 SoundFileBrowser::freesound_search_clicked ()
963 freesound_list->clear();
969 SoundFileBrowser::freesound_more_clicked ()
974 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
975 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
979 SoundFileBrowser::freesound_similar_clicked ()
981 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
982 if (rows.size() == 1) {
985 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
986 id = (*iter)[freesound_list_columns.id];
987 freesound_list->clear();
989 GdkCursor *prev_cursor;
990 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
991 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
994 std::string theString = mootcher.searchSimilar(id);
996 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
997 handle_freesound_results(theString);
1002 SoundFileBrowser::freesound_search()
1006 string search_string = freesound_entry.get_text ();
1007 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1009 GdkCursor *prev_cursor;
1010 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1011 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1014 std::string theString = mootcher.searchText(
1018 "", // OSX eats anything incl mp3
1020 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1025 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1026 handle_freesound_results(theString);
1030 SoundFileBrowser::handle_freesound_results(std::string theString) {
1032 doc.read_buffer( theString );
1033 XMLNode *root = doc.root();
1036 error << "no root XML node!" << endmsg;
1040 if ( strcmp(root->name().c_str(), "response") != 0) {
1041 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1045 // find out how many pages are available to search
1046 int freesound_n_pages = 1;
1047 XMLNode *res = root->child("num_pages");
1049 string result = res->child("text")->content();
1050 freesound_n_pages = atoi(result);
1053 int more_pages = freesound_n_pages - freesound_page;
1055 if (more_pages > 0) {
1056 freesound_more_btn.set_sensitive(true);
1057 freesound_more_btn.set_tooltip_text(string_compose(P_(
1058 "%1 more page of 100 results available",
1059 "%1 more pages of 100 results available",
1060 more_pages), more_pages));
1062 freesound_more_btn.set_sensitive(false);
1063 freesound_more_btn.set_tooltip_text(_("No more results available"));
1066 XMLNode *sounds_root = root->child("sounds");
1068 error << "no child node \"sounds\" found!" << endmsg;
1072 XMLNodeList sounds = sounds_root->children();
1073 if (sounds.size() == 0) {
1078 XMLNodeConstIterator niter;
1080 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1082 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1083 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1087 // node->dump(cerr, "node:");
1090 XMLNode *id_node = node->child ("id");
1091 XMLNode *uri_node = node->child ("serve");
1092 XMLNode *ofn_node = node->child ("original_filename");
1093 XMLNode *dur_node = node->child ("duration");
1094 XMLNode *siz_node = node->child ("filesize");
1095 XMLNode *srt_node = node->child ("samplerate");
1096 XMLNode *lic_node = node->child ("license");
1098 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1100 std::string id = id_node->child("text")->content();
1101 std::string uri = uri_node->child("text")->content();
1102 std::string ofn = ofn_node->child("text")->content();
1103 std::string dur = dur_node->child("text")->content();
1104 std::string siz = siz_node->child("text")->content();
1105 std::string srt = srt_node->child("text")->content();
1106 std::string lic = lic_node->child("text")->content();
1109 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1111 double duration_seconds = atof(dur);
1113 char duration_hhmmss[16];
1114 if (duration_seconds >= 99 * 60 * 60) {
1115 strcpy(duration_hhmmss, ">99h");
1117 s = modf(duration_seconds/60, &m) * 60;
1118 m = modf(m/60, &h) * 60;
1119 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1124 double size_bytes = atof(siz);
1126 if (size_bytes < 1000) {
1127 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1128 } else if (size_bytes < 1000000 ) {
1129 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1130 } else if (size_bytes < 10000000) {
1131 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1132 } else if (size_bytes < 1000000000) {
1133 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1135 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1138 /* see http://www.freesound.org/help/faq/#licenses */
1139 char shortlicense[64];
1140 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1141 sprintf(shortlicense, "CC-BY-NC");
1142 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1143 sprintf(shortlicense, "CC-BY");
1144 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1145 sprintf(shortlicense, "sampling+");
1146 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1147 sprintf(shortlicense, "PD");
1149 snprintf(shortlicense, 64, "%s", lic.c_str());
1150 shortlicense[63]= '\0';
1153 TreeModel::iterator new_row = freesound_list->append();
1154 TreeModel::Row row = *new_row;
1156 row[freesound_list_columns.id ] = id;
1157 row[freesound_list_columns.uri ] = uri;
1158 row[freesound_list_columns.filename] = ofn;
1159 row[freesound_list_columns.duration] = duration_hhmmss;
1160 row[freesound_list_columns.filesize] = bsize;
1161 row[freesound_list_columns.smplrate] = srt;
1162 row[freesound_list_columns.license ] = shortlicense;
1169 SoundFileBrowser::get_paths ()
1171 vector<string> results;
1173 int n = notebook.get_current_page ();
1176 vector<string> filenames = chooser.get_filenames();
1177 vector<string>::iterator i;
1179 for (i = filenames.begin(); i != filenames.end(); ++i) {
1181 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1182 results.push_back (*i);
1186 } else if (n == 1) {
1188 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1189 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1190 TreeIter iter = found_list->get_iter(*i);
1191 string str = (*iter)[found_list_columns.pathname];
1193 results.push_back (str);
1196 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1197 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1198 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1200 results.push_back (str);
1209 SoundFileOmega::reset_options_noret ()
1211 if (!resetting_ourselves) {
1212 (void) reset_options ();
1217 SoundFileOmega::reset_options ()
1219 vector<string> paths = get_paths ();
1221 if (paths.empty()) {
1223 channel_combo.set_sensitive (false);
1224 action_combo.set_sensitive (false);
1225 where_combo.set_sensitive (false);
1226 copy_files_btn.set_active (true);
1227 copy_files_btn.set_sensitive (false);
1233 channel_combo.set_sensitive (true);
1234 action_combo.set_sensitive (true);
1235 where_combo.set_sensitive (true);
1237 /* if we get through this function successfully, this may be
1238 reset at the end, once we know if we can use hard links
1239 to do embedding (or if we are importing a MIDI file).
1242 if (Config->get_only_copy_imported_files()) {
1243 copy_files_btn.set_sensitive (false);
1245 copy_files_btn.set_sensitive (false);
1251 bool selection_includes_multichannel;
1252 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1255 /* See if we are thinking about importing any MIDI files */
1256 vector<string>::iterator i = paths.begin ();
1257 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1260 bool const have_a_midi_file = (i != paths.end ());
1262 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1263 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1267 string existing_choice;
1268 vector<string> action_strings;
1270 resetting_ourselves = true;
1272 if (chooser.get_filter() == &audio_filter) {
1276 if (selected_audio_track_cnt > 0) {
1277 if (channel_combo.get_active_text().length()) {
1278 ImportDisposition id = get_channel_disposition();
1281 case Editing::ImportDistinctFiles:
1282 if (selected_audio_track_cnt == paths.size()) {
1283 action_strings.push_back (importmode2string (ImportToTrack));
1287 case Editing::ImportDistinctChannels:
1288 /* XXX it would be nice to allow channel-per-selected track
1289 but its too hard we don't want to deal with all the
1290 different per-file + per-track channel configurations.
1295 action_strings.push_back (importmode2string (ImportToTrack));
1305 if (selected_midi_track_cnt > 0) {
1306 action_strings.push_back (importmode2string (ImportToTrack));
1310 action_strings.push_back (importmode2string (ImportAsTrack));
1311 action_strings.push_back (importmode2string (ImportAsRegion));
1312 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1314 existing_choice = action_combo.get_active_text();
1316 set_popdown_strings (action_combo, action_strings);
1318 /* preserve any existing choice, if possible */
1321 if (existing_choice.length()) {
1322 vector<string>::iterator x;
1323 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1324 if (*x == existing_choice) {
1325 action_combo.set_active_text (existing_choice);
1329 if (x == action_strings.end()) {
1330 action_combo.set_active_text (action_strings.front());
1333 action_combo.set_active_text (action_strings.front());
1336 resetting_ourselves = false;
1338 if ((mode = get_mode()) == ImportAsRegion) {
1339 where_combo.set_sensitive (false);
1341 where_combo.set_sensitive (true);
1344 vector<string> channel_strings;
1346 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1347 channel_strings.push_back (_("one track per file"));
1349 if (selection_includes_multichannel) {
1350 channel_strings.push_back (_("one track per channel"));
1353 if (paths.size() > 1) {
1354 /* tape tracks are a single region per track, so we cannot
1355 sequence multiple files.
1357 if (mode != ImportAsTapeTrack) {
1358 channel_strings.push_back (_("sequence files"));
1361 channel_strings.push_back (_("all files in one track"));
1362 channel_strings.push_back (_("merge files"));
1368 channel_strings.push_back (_("one region per file"));
1370 if (selection_includes_multichannel) {
1371 channel_strings.push_back (_("one region per channel"));
1374 if (paths.size() > 1) {
1376 channel_strings.push_back (_("all files in one region"));
1381 resetting_ourselves = true;
1383 existing_choice = channel_combo.get_active_text();
1385 set_popdown_strings (channel_combo, channel_strings);
1387 /* preserve any existing choice, if possible */
1389 if (existing_choice.length()) {
1390 vector<string>::iterator x;
1391 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1392 if (*x == existing_choice) {
1393 channel_combo.set_active_text (existing_choice);
1397 if (x == channel_strings.end()) {
1398 channel_combo.set_active_text (channel_strings.front());
1401 channel_combo.set_active_text (channel_strings.front());
1404 resetting_ourselves = false;
1407 src_combo.set_sensitive (true);
1409 src_combo.set_sensitive (false);
1412 /* We must copy MIDI files or those from Freesound
1413 * or any file if we are under nsm control */
1414 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1416 if (Config->get_only_copy_imported_files()) {
1418 if (selection_can_be_embedded_with_links && !must_copy) {
1419 copy_files_btn.set_sensitive (true);
1422 copy_files_btn.set_active (true);
1424 copy_files_btn.set_sensitive (false);
1430 copy_files_btn.set_active (true);
1432 copy_files_btn.set_sensitive (!must_copy);
1440 SoundFileOmega::bad_file_message()
1442 MessageDialog msg (*this,
1443 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1448 resetting_ourselves = true;
1449 chooser.unselect_uri (chooser.get_preview_uri());
1450 resetting_ourselves = false;
1456 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1465 multichannel = false;
1467 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1469 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1470 if (info.channels > 1) {
1471 multichannel = true;
1476 if (sz != info.length) {
1481 if (info.samplerate != _session->frame_rate()) {
1485 } else if (SMFSource::safe_midi_file_extension (*i)) {
1489 if (reader.num_tracks() > 1) {
1490 multichannel = true; // "channel" == track here...
1493 /* XXX we need err = true handling here in case
1494 we can't check the file
1507 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1509 #ifdef PLATFORM_WINDOWS
1512 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1515 if (mkdir (tmpdir.c_str(), 0744)) {
1516 if (errno != EEXIST) {
1521 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1523 char tmpc[PATH_MAX+1];
1525 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1529 if (link ((*i).c_str(), tmpc)) {
1539 rmdir (tmpdir.c_str());
1544 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1545 : SoundFileBrowser (title, s, false)
1547 chooser.set_select_multiple (false);
1548 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1549 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1553 SoundFileChooser::on_hide ()
1555 ArdourWindow::on_hide();
1559 _session->cancel_audition();
1564 SoundFileChooser::get_filename ()
1566 vector<string> paths;
1568 paths = get_paths ();
1570 if (paths.empty()) {
1574 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1578 return paths.front();
1581 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1582 uint32_t selected_audio_tracks,
1583 uint32_t selected_midi_tracks,
1585 Editing::ImportMode mode_hint)
1586 : SoundFileBrowser (title, s, persistent)
1587 , copy_files_btn ( _("Copy files to session"))
1588 , selected_audio_track_cnt (selected_audio_tracks)
1589 , selected_midi_track_cnt (selected_midi_tracks)
1595 set_size_request (-1, 450);
1597 block_two.set_border_width (12);
1598 block_three.set_border_width (12);
1599 block_four.set_border_width (12);
1601 options.set_spacing (12);
1604 str.push_back (_("file timestamp"));
1605 str.push_back (_("edit point"));
1606 str.push_back (_("playhead"));
1607 str.push_back (_("session start"));
1608 set_popdown_strings (where_combo, str);
1609 where_combo.set_active_text (str.front());
1611 Label* l = manage (new Label);
1612 l->set_markup (_("<b>Add files as ...</b>"));
1614 vbox = manage (new VBox);
1615 vbox->set_border_width (12);
1616 vbox->set_spacing (6);
1617 vbox->pack_start (*l, false, false);
1618 vbox->pack_start (action_combo, false, false);
1619 hbox = manage (new HBox);
1620 hbox->pack_start (*vbox, false, false);
1621 options.pack_start (*hbox, false, false);
1623 /* dummy entry for action combo so that it doesn't look odd if we
1624 come up with no tracks selected.
1628 str.push_back (importmode2string (mode_hint));
1629 set_popdown_strings (action_combo, str);
1630 action_combo.set_active_text (str.front());
1631 action_combo.set_sensitive (false);
1633 l = manage (new Label);
1634 l->set_markup (_("<b>Insert at</b>"));
1636 vbox = manage (new VBox);
1637 vbox->set_border_width (12);
1638 vbox->set_spacing (6);
1639 vbox->pack_start (*l, false, false);
1640 vbox->pack_start (where_combo, false, false);
1641 hbox = manage (new HBox);
1642 hbox->pack_start (*vbox, false, false);
1643 options.pack_start (*hbox, false, false);
1646 l = manage (new Label);
1647 l->set_markup (_("<b>Mapping</b>"));
1649 vbox = manage (new VBox);
1650 vbox->set_border_width (12);
1651 vbox->set_spacing (6);
1652 vbox->pack_start (*l, false, false);
1653 vbox->pack_start (channel_combo, false, false);
1654 hbox = manage (new HBox);
1655 hbox->pack_start (*vbox, false, false);
1656 options.pack_start (*hbox, false, false);
1659 str.push_back (_("one track per file"));
1660 set_popdown_strings (channel_combo, str);
1661 channel_combo.set_active_text (str.front());
1662 channel_combo.set_sensitive (false);
1664 l = manage (new Label);
1665 l->set_markup (_("<b>Conversion quality</b>"));
1667 vbox = manage (new VBox);
1668 vbox->set_border_width (12);
1669 vbox->set_spacing (6);
1670 vbox->pack_start (*l, false, false);
1671 vbox->pack_start (src_combo, false, false);
1672 hbox = manage (new HBox);
1673 hbox->pack_start (*vbox, false, false);
1674 options.pack_start (*hbox, false, false);
1677 str.push_back (_("Best"));
1678 str.push_back (_("Good"));
1679 str.push_back (_("Quick"));
1680 str.push_back (_("Fast"));
1681 str.push_back (_("Fastest"));
1683 set_popdown_strings (src_combo, str);
1684 src_combo.set_active_text (str.front());
1685 src_combo.set_sensitive (false);
1689 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1690 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1692 copy_files_btn.set_active (true);
1694 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1697 copy_label->set_size_request (175, -1);
1698 copy_label->set_line_wrap (true);
1701 block_four.pack_start (copy_files_btn, false, false);
1703 options.pack_start (block_four, false, false);
1705 vpacker.pack_start (options, false, false);
1707 /* setup disposition map */
1709 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1710 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1711 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1712 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1714 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1715 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1716 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1717 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1719 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1721 /* set size requests for a couple of combos to allow them to display the longest text
1722 they will ever be asked to display. This prevents them being resized when the user
1723 selects a file to import, which in turn prevents the size of the dialog from jumping
1727 t.push_back (_("one track per file"));
1728 t.push_back (_("one track per channel"));
1729 t.push_back (_("sequence files"));
1730 t.push_back (_("all files in one region"));
1731 set_popdown_strings (channel_combo, t);
1734 t.push_back (importmode2string (ImportAsTrack));
1735 t.push_back (importmode2string (ImportToTrack));
1736 t.push_back (importmode2string (ImportAsRegion));
1737 t.push_back (importmode2string (ImportAsTapeTrack));
1738 set_popdown_strings (action_combo, t);
1742 SoundFileOmega::set_mode (ImportMode mode)
1744 action_combo.set_active_text (importmode2string (mode));
1748 SoundFileOmega::get_mode () const
1750 return string2importmode (action_combo.get_active_text());
1754 SoundFileOmega::on_hide ()
1756 ArdourWindow::on_hide();
1758 _session->cancel_audition();
1763 SoundFileOmega::get_position() const
1765 string str = where_combo.get_active_text();
1767 if (str == _("file timestamp")) {
1768 return ImportAtTimestamp;
1769 } else if (str == _("edit point")) {
1770 return ImportAtEditPoint;
1771 } else if (str == _("playhead")) {
1772 return ImportAtPlayhead;
1774 return ImportAtStart;
1779 SoundFileOmega::get_src_quality() const
1781 string str = src_combo.get_active_text();
1783 if (str == _("Best")) {
1785 } else if (str == _("Good")) {
1787 } else if (str == _("Quick")) {
1789 } else if (str == _("Fast")) {
1797 SoundFileOmega::get_channel_disposition () const
1799 /* we use a map here because the channel combo can contain different strings
1800 depending on the state of the other combos. the map contains all possible strings
1801 and the ImportDisposition enum that corresponds to it.
1804 string str = channel_combo.get_active_text();
1805 DispositionMap::const_iterator x = disposition_map.find (str);
1807 if (x == disposition_map.end()) {
1808 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1816 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1818 selected_audio_track_cnt = selected_audio_tracks;
1819 selected_midi_track_cnt = selected_midi_tracks;
1821 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1822 chooser.set_filter (midi_filter);
1823 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1824 chooser.set_filter (audio_filter);
1826 chooser.set_filter (audio_and_midi_filter);
1833 SoundFileOmega::file_selection_changed ()
1835 if (resetting_ourselves) {
1839 if (!reset_options ()) {
1840 set_action_sensitive (false);
1842 if (chooser.get_filenames().size() > 0) {
1843 set_action_sensitive (true);
1845 set_action_sensitive (false);
1851 SoundFileOmega::do_something (int action)
1853 SoundFileBrowser::do_something (action);
1855 if (action == RESPONSE_CANCEL) {
1862 vector<string> paths = get_paths ();
1863 ImportPosition pos = get_position ();
1864 ImportMode mode = get_mode ();
1865 ImportDisposition chns = get_channel_disposition ();
1869 case ImportAtEditPoint:
1870 where = PublicEditor::instance().get_preferred_edit_position ();
1872 case ImportAtTimestamp:
1875 case ImportAtPlayhead:
1876 where = _session->transport_frame();
1879 where = _session->current_start_frame();
1883 SrcQuality quality = get_src_quality();
1885 if (copy_files_btn.get_active()) {
1886 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1888 PublicEditor::instance().do_embed (paths, chns, mode, where);
1891 if (action == RESPONSE_OK) {