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"
55 #include "ardour/srcfilesource.h"
57 #include "ardour_ui.h"
59 #include "gui_thread.h"
64 #include "gain_meter.h"
65 #include "main_clock.h"
66 #include "public_editor.h"
68 #include "sfdb_freesound_mootcher.h"
72 using namespace ARDOUR;
76 using namespace Gtkmm2ext;
77 using namespace Editing;
81 string SoundFileBrowser::persistent_folder;
82 typedef TreeView::Selection::ListHandle_Path ListPath;
85 string2importmode (string str)
87 if (str == _("as new tracks")) {
89 } else if (str == _("to selected tracks")) {
91 } else if (str == _("to region list")) {
92 return ImportAsRegion;
93 } else if (str == _("as new tape tracks")) {
94 return ImportAsTapeTrack;
97 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
103 importmode2string (ImportMode mode)
107 return _("as new tracks");
109 return _("to selected tracks");
111 return _("to region list");
112 case ImportAsTapeTrack:
113 return _("as new tape tracks");
116 return _("as new tracks");
119 SoundFileBox::SoundFileBox (bool persistent)
121 length_clock ("sfboxLengthClock", true, "", false, false, true, false),
122 timecode_clock ("sfboxTimecodeClock", true, "", false, false, false, false),
124 autoplay_btn (_("Auto-play")),
125 seek_slider(0,1000,1),
129 set_name (X_("SoundFileBox"));
130 set_size_request (300, -1);
132 preview_label.set_markup (_("<b>Sound File Information</b>"));
134 border_frame.set_label_widget (preview_label);
135 border_frame.add (main_box);
137 pack_start (border_frame, true, true);
138 set_border_width (6);
140 main_box.set_border_width (6);
142 length.set_text (_("Length:"));
143 length.set_alignment (1, 0.5);
144 timecode.set_text (_("Timestamp:"));
145 timecode.set_alignment (1, 0.5);
146 format.set_text (_("Format:"));
147 format.set_alignment (1, 0.5);
148 channels.set_text (_("Channels:"));
149 channels.set_alignment (1, 0.5);
150 samplerate.set_text (_("Sample rate:"));
151 samplerate.set_alignment (1, 0.5);
153 preview_label.set_max_width_chars (50);
154 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
156 format_text.set_max_width_chars (20);
157 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
158 format_text.set_alignment (0, 1);
160 table.set_col_spacings (6);
161 table.set_homogeneous (false);
162 table.set_row_spacings (6);
164 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
165 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
166 table.attach (format, 0, 1, 2, 4, FILL, FILL);
167 table.attach (length, 0, 1, 4, 5, FILL, FILL);
168 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
170 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
171 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
172 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
173 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
174 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
176 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
177 timecode_clock.set_mode (AudioClock::Timecode);
179 main_box.pack_start (table, false, false);
181 tags_entry.set_editable (true);
182 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
183 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
185 Label* label = manage (new Label (_("Tags:")));
186 label->set_alignment (0.0f, 0.5f);
187 main_box.pack_start (*label, false, false);
188 main_box.pack_start (tags_entry, true, true);
190 main_box.pack_start (bottom_box, false, false);
192 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
193 // play_btn.set_label (_("Play"));
195 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
196 // stop_btn.set_label (_("Stop"));
198 bottom_box.set_homogeneous (false);
199 bottom_box.set_spacing (6);
200 bottom_box.pack_start(play_btn, true, true);
201 bottom_box.pack_start(stop_btn, true, true);
202 bottom_box.pack_start(autoplay_btn, false, false);
204 seek_slider.set_draw_value(false);
206 seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
207 seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
208 seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
209 main_box.pack_start (seek_slider, false, false);
211 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
212 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
214 stop_btn.set_sensitive (false);
216 channels_value.set_alignment (0.0f, 0.5f);
217 samplerate_value.set_alignment (0.0f, 0.5f);
221 SoundFileBox::set_session(Session* s)
223 SessionHandlePtr::set_session (s);
225 length_clock.set_session (s);
226 timecode_clock.set_session (s);
229 play_btn.set_sensitive (false);
230 stop_btn.set_sensitive (false);
231 auditioner_connections.drop_connections();
233 auditioner_connections.drop_connections();
234 _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
235 _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
240 SoundFileBox::audition_active(bool active) {
241 stop_btn.set_sensitive (active);
242 seek_slider.set_sensitive (active);
244 seek_slider.set_value(0);
249 SoundFileBox::audition_progress(ARDOUR::framecnt_t pos, ARDOUR::framecnt_t len) {
251 seek_slider.set_value( 1000.0 * pos / len);
252 seek_slider.set_sensitive (true);
257 SoundFileBox::seek_button_press(GdkEventButton*) {
259 return false; // pass on to slider
263 SoundFileBox::seek_button_release(GdkEventButton*) {
265 _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
266 seek_slider.set_sensitive (false);
267 return false; // pass on to slider
271 SoundFileBox::setup_labels (const string& filename)
274 // save existing tags
282 if (SMFSource::safe_midi_file_extension (path)) {
284 boost::shared_ptr<SMFSource> ms =
285 boost::dynamic_pointer_cast<SMFSource> (
286 SourceFactory::createExternal (DataType::MIDI, *_session,
287 path, 0, Source::Flag (0), false));
289 preview_label.set_markup (_("<b>Midi File Information</b>"));
291 format_text.set_text ("MIDI");
292 samplerate_value.set_text ("-");
293 tags_entry.get_buffer()->set_text ("");
294 timecode_clock.set (0);
295 tags_entry.set_sensitive (false);
298 channels_value.set_text (to_string(ms->num_tracks(), std::dec));
299 length_clock.set (ms->length(ms->timeline_position()));
301 channels_value.set_text ("");
302 length_clock.set (0);
305 if (_session && ms) {
306 play_btn.set_sensitive (true);
308 play_btn.set_sensitive (false);
314 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
316 preview_label.set_markup (_("<b>Sound File Information</b>"));
317 format_text.set_text ("");
318 channels_value.set_text ("");
319 samplerate_value.set_text ("");
320 tags_entry.get_buffer()->set_text ("");
322 length_clock.set (0);
323 timecode_clock.set (0);
325 tags_entry.set_sensitive (false);
326 play_btn.set_sensitive (false);
331 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
332 std::string n = sf_info.format_name;
333 if (n.substr (0, 8) == X_("Format: ")) {
336 format_text.set_text (n);
337 channels_value.set_text (to_string (sf_info.channels, std::dec));
339 if (_session && sf_info.samplerate != _session->frame_rate()) {
340 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
341 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
342 samplerate_value.set_name ("NewSessionSR1Label");
343 samplerate.set_name ("NewSessionSR1Label");
345 samplerate.set_text (_("Sample rate:"));
346 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
347 samplerate_value.set_name ("NewSessionSR2Label");
348 samplerate.set_name ("NewSessionSR2Label");
351 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
352 double src_coef = (double) nfr / sf_info.samplerate;
354 length_clock.set (sf_info.length * src_coef + 0.5, true);
355 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
357 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
359 vector<string> tags = Library->get_tags (string ("//") + filename);
361 stringstream tag_string;
362 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
363 if (i != tags.begin()) {
368 tags_entry.get_buffer()->set_text (tag_string.str());
370 tags_entry.set_sensitive (true);
372 play_btn.set_sensitive (true);
379 SoundFileBox::autoplay() const
381 return autoplay_btn.get_active();
385 SoundFileBox::audition_oneshot()
392 SoundFileBox::audition ()
398 _session->cancel_audition();
400 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
401 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
405 boost::shared_ptr<Region> r;
407 if (SMFSource::safe_midi_file_extension (path)) {
409 boost::shared_ptr<SMFSource> ms =
410 boost::dynamic_pointer_cast<SMFSource> (
411 SourceFactory::createExternal (DataType::MIDI, *_session,
412 path, 0, Source::Flag (0), false));
414 string rname = region_name_from_path (ms->path(), false);
418 plist.add (ARDOUR::Properties::start, 0);
419 plist.add (ARDOUR::Properties::length, ms->length(ms->timeline_position()));
420 plist.add (ARDOUR::Properties::name, rname);
421 plist.add (ARDOUR::Properties::layer, 0);
423 r = boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (boost::dynamic_pointer_cast<Source>(ms), plist, false));
429 boost::shared_ptr<AudioFileSource> afs;
430 bool old_sbp = AudioSource::get_build_peakfiles ();
432 /* don't even think of building peakfiles for these files */
434 AudioSource::set_build_peakfiles (false);
436 for (int n = 0; n < sf_info.channels; ++n) {
438 afs = boost::dynamic_pointer_cast<AudioFileSource> (
439 SourceFactory::createExternal (DataType::AUDIO, *_session,
441 Source::Flag (0), false));
442 if (afs->sample_rate() != _session->nominal_frame_rate()) {
443 boost::shared_ptr<SrcFileSource> sfs (new SrcFileSource(*_session, afs, _src_quality));
444 srclist.push_back(sfs);
446 srclist.push_back(afs);
449 } catch (failed_constructor& err) {
450 error << _("Could not access soundfile: ") << path << endmsg;
451 AudioSource::set_build_peakfiles (old_sbp);
456 AudioSource::set_build_peakfiles (old_sbp);
458 if (srclist.empty()) {
462 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
463 string rname = region_name_from_path (afs->path(), false);
467 plist.add (ARDOUR::Properties::start, 0);
468 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
469 plist.add (ARDOUR::Properties::name, rname);
470 plist.add (ARDOUR::Properties::layer, 0);
472 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
475 _session->audition_region(r);
479 SoundFileBox::stop_audition ()
482 _session->cancel_audition();
487 SoundFileBox::tags_entry_left (GdkEventFocus *)
494 SoundFileBox::tags_changed ()
496 string tag_string = tags_entry.get_buffer()->get_text ();
498 if (tag_string.empty()) {
504 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
505 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
513 SoundFileBox::save_tags (const vector<string>& tags)
515 Library->set_tags (string ("//") + path, tags);
516 Library->save_changes ();
519 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
520 : ArdourWindow (title)
521 , found_list (ListStore::create(found_list_columns))
522 , freesound_list (ListStore::create(freesound_list_columns))
523 , chooser (FILE_CHOOSER_ACTION_OPEN)
524 , preview (persistent)
525 , found_search_btn (_("Search"))
526 , found_list_view (found_list)
527 , freesound_search_btn (_("Search"))
528 , freesound_list_view (freesound_list)
529 , resetting_ourselves (false)
533 , ok_button (Stock::OK)
534 , cancel_button (Stock::CANCEL)
535 , apply_button (Stock::APPLY)
540 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
541 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
542 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
543 chooser.add_shortcut_folder_uri("file:///Volumes");
546 //add the file chooser
548 chooser.set_border_width (12);
550 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
551 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
553 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
554 audio_filter.set_name (_("Audio files"));
556 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
557 midi_filter.set_name (_("MIDI files"));
559 matchall_filter.add_pattern ("*.*");
560 matchall_filter.set_name (_("All files"));
562 chooser.add_filter (audio_and_midi_filter);
563 chooser.add_filter (audio_filter);
564 chooser.add_filter (midi_filter);
565 chooser.add_filter (matchall_filter);
566 chooser.set_select_multiple (true);
567 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
568 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
571 /* some broken redraw behaviour - this is a bandaid */
572 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
575 if (!persistent_folder.empty()) {
576 chooser.set_current_folder (persistent_folder);
579 notebook.append_page (chooser, _("Browse Files"));
581 hpacker.set_spacing (6);
582 hpacker.pack_start (notebook, true, true);
583 hpacker.pack_start (preview, false, false);
585 vpacker.set_spacing (6);
586 vpacker.pack_start (hpacker, true, true);
596 hbox = manage(new HBox);
597 hbox->pack_start (found_entry);
598 hbox->pack_start (found_search_btn);
600 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
601 scroll->add(found_list_view);
602 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
604 vbox = manage(new VBox);
605 vbox->pack_start (*hbox, PACK_SHRINK);
606 vbox->pack_start (*scroll);
608 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
610 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
612 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
614 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
615 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
617 notebook.append_page (*vbox, _("Search Tags"));
619 //add freesound search
624 passbox = manage(new HBox);
625 passbox->set_spacing (6);
627 label = manage (new Label);
628 label->set_text (_("Tags:"));
629 passbox->pack_start (*label, false, false);
630 passbox->pack_start (freesound_entry, true, true);
632 label = manage (new Label);
633 label->set_text (_("Sort:"));
634 passbox->pack_start (*label, false, false);
635 passbox->pack_start (freesound_sort, false, false);
636 freesound_sort.clear_items();
638 // Order of the following must correspond with enum sortMethod
639 // in sfdb_freesound_mootcher.h
640 freesound_sort.append_text(_("None"));
641 freesound_sort.append_text(_("Longest"));
642 freesound_sort.append_text(_("Shortest"));
643 freesound_sort.append_text(_("Newest"));
644 freesound_sort.append_text(_("Oldest"));
645 freesound_sort.append_text(_("Most downloaded"));
646 freesound_sort.append_text(_("Least downloaded"));
647 freesound_sort.append_text(_("Highest rated"));
648 freesound_sort.append_text(_("Lowest rated"));
649 freesound_sort.set_active(0);
651 passbox->pack_start (freesound_search_btn, false, false);
652 passbox->pack_start (freesound_more_btn, false, false);
653 freesound_more_btn.set_label(_("More"));
654 freesound_more_btn.set_sensitive(false);
656 passbox->pack_start (freesound_similar_btn, false, false);
657 freesound_similar_btn.set_label(_("Similar"));
658 freesound_similar_btn.set_sensitive(false);
660 scroll = manage(new ScrolledWindow);
661 scroll->add(freesound_list_view);
662 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
664 vbox = manage(new VBox);
665 vbox->set_spacing (3);
666 vbox->pack_start (*passbox, PACK_SHRINK);
667 vbox->pack_start (*scroll);
669 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
670 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
671 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
672 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
673 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
674 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
675 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
676 freesound_list_view.get_column(0)->set_alignment(0.5);
677 freesound_list_view.get_column(1)->set_expand(true); // filename
678 freesound_list_view.get_column(1)->set_resizable(true); // filename
679 freesound_list_view.get_column(2)->set_alignment(0.5);
680 freesound_list_view.get_column(3)->set_alignment(0.5);
681 freesound_list_view.get_column(4)->set_alignment(0.5);
682 freesound_list_view.get_column(5)->set_alignment(0.5);
684 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
685 freesound_list_view.set_tooltip_column(1);
687 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
688 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
689 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
690 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
691 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
692 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
693 notebook.append_page (*vbox, _("Search Freesound"));
695 notebook.set_size_request (500, -1);
696 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
700 Gtk::HButtonBox* button_box = manage (new HButtonBox);
702 button_box->set_layout (BUTTONBOX_END);
703 button_box->pack_start (cancel_button, false, false);
704 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
706 button_box->pack_start (apply_button, false, false);
707 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
710 button_box->pack_start (ok_button, false, false);
711 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
713 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
714 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
715 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
717 vpacker.pack_end (*button_box, false, false);
719 set_wmclass (X_("import"), PROGRAM_NAME);
722 SoundFileBrowser::~SoundFileBrowser ()
724 persistent_folder = chooser.get_current_folder();
728 SoundFileBrowser::run ()
737 gtk_main_iteration ();
744 SoundFileBrowser::set_action_sensitive (bool yn)
746 ok_button.set_sensitive (yn);
747 apply_button.set_sensitive (yn);
751 SoundFileBrowser::do_something (int action)
758 SoundFileBrowser::on_show ()
760 ArdourWindow::on_show ();
765 SoundFileBrowser::clear_selection ()
767 chooser.unselect_all ();
768 found_list_view.get_selection()->unselect_all ();
772 SoundFileBrowser::chooser_file_activated ()
778 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
784 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
790 SoundFileBrowser::set_session (Session* s)
792 ArdourWindow::set_session (s);
793 preview.set_session (s);
798 remove_gain_meter ();
803 SoundFileBrowser::add_gain_meter ()
807 gm = new GainMeter (_session, 250);
809 boost::shared_ptr<Route> r = _session->the_auditioner ();
811 gm->set_controls (r, r->shared_peak_meter(), r->amp());
812 gm->set_fader_name (X_("GainFader"));
814 meter_packer.set_border_width (12);
815 meter_packer.pack_start (*gm, false, true);
816 hpacker.pack_end (meter_packer, false, false);
817 meter_packer.show_all ();
822 SoundFileBrowser::remove_gain_meter ()
825 meter_packer.remove (*gm);
826 hpacker.remove (meter_packer);
833 SoundFileBrowser::start_metering ()
835 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
839 SoundFileBrowser::stop_metering ()
841 metering_connection.disconnect();
845 SoundFileBrowser::meter ()
847 if (is_mapped () && _session && gm) {
848 gm->update_meters ();
853 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
855 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
859 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
861 return SMFSource::safe_midi_file_extension (filter_info.filename);
865 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
867 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
871 SoundFileBrowser::update_preview ()
873 if (preview.setup_labels (chooser.get_preview_filename())) {
874 if (preview.autoplay()) {
875 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
881 SoundFileBrowser::found_list_view_selected ()
883 if (!reset_options ()) {
884 set_action_sensitive (false);
888 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
891 TreeIter iter = found_list->get_iter(*rows.begin());
892 file = (*iter)[found_list_columns.pathname];
893 chooser.set_filename (file);
894 set_action_sensitive (true);
896 set_action_sensitive (false);
899 preview.setup_labels (file);
904 SoundFileBrowser::found_search_clicked ()
906 string tag_string = found_entry.get_text ();
910 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
911 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
915 vector<string> results;
916 Library->search_members_and (results, tags);
919 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
920 TreeModel::iterator new_row = found_list->append();
921 TreeModel::Row row = *new_row;
922 string path = Glib::filename_from_uri (string ("file:") + *i);
923 row[found_list_columns.pathname] = path;
929 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
932 Mootcher *mootcher = new Mootcher;
935 string id = (*iter)[freesound_list_columns.id];
936 string uri = (*iter)[freesound_list_columns.uri];
937 string ofn = (*iter)[freesound_list_columns.filename];
939 if (mootcher->checkAudioFile(ofn, id)) {
940 // file already exists, no need to download it again
941 file = mootcher->audioFileName;
943 (*iter)[freesound_list_columns.started] = false;
946 if (!(*iter)[freesound_list_columns.started]) {
947 // start downloading the sound file
948 (*iter)[freesound_list_columns.started] = true;
949 mootcher->fetchAudioFile(ofn, id, uri, this);
955 SoundFileBrowser::freesound_list_view_selected ()
958 if (!reset_options ()) {
959 set_action_sensitive (false);
962 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
963 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
964 file = freesound_get_audio_file (freesound_list->get_iter(*i));
967 switch (rows.size()) {
970 freesound_similar_btn.set_sensitive(false);
971 set_action_sensitive (false);
974 // exactly one item selected
976 // file exists on disk already
977 chooser.set_filename (file);
978 preview.setup_labels (file);
979 set_action_sensitive (true);
981 freesound_similar_btn.set_sensitive(true);
984 // multiple items selected
985 preview.setup_labels ("");
986 freesound_similar_btn.set_sensitive(false);
994 SoundFileBrowser::refresh_display(std::string ID, std::string file)
996 // called when the mootcher has finished downloading a file
997 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
998 if (rows.size() == 1) {
999 // there's a single item selected in the freesound list
1000 //XXX make a function to be used to construct the actual file name both here and in the mootcher
1001 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
1002 std::string selected_ID = (*row)[freesound_list_columns.id];
1003 if (ID == selected_ID) {
1004 // the selected item in the freesound list is the item that has just finished downloading
1005 chooser.set_filename(file);
1006 preview.setup_labels (file);
1007 set_action_sensitive (true);
1013 SoundFileBrowser::freesound_search_clicked ()
1016 freesound_list->clear();
1022 SoundFileBrowser::freesound_more_clicked ()
1027 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
1028 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
1032 SoundFileBrowser::freesound_similar_clicked ()
1034 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1035 if (rows.size() == 1) {
1038 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
1039 id = (*iter)[freesound_list_columns.id];
1040 freesound_list->clear();
1042 GdkCursor *prev_cursor;
1043 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1044 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1047 std::string theString = mootcher.searchSimilar(id);
1049 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1050 handle_freesound_results(theString);
1055 SoundFileBrowser::freesound_search()
1059 string search_string = freesound_entry.get_text ();
1060 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1062 GdkCursor *prev_cursor;
1063 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1064 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1067 std::string theString = mootcher.searchText(
1071 "", // OSX eats anything incl mp3
1073 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1078 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1079 handle_freesound_results(theString);
1083 SoundFileBrowser::handle_freesound_results(std::string theString) {
1085 doc.read_buffer( theString );
1086 XMLNode *root = doc.root();
1089 error << "no root XML node!" << endmsg;
1093 if ( strcmp(root->name().c_str(), "response") != 0) {
1094 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1098 // find out how many pages are available to search
1099 int freesound_n_pages = 1;
1100 XMLNode *res = root->child("num_pages");
1102 string result = res->child("text")->content();
1103 freesound_n_pages = atoi(result);
1106 int more_pages = freesound_n_pages - freesound_page;
1108 if (more_pages > 0) {
1109 freesound_more_btn.set_sensitive(true);
1110 freesound_more_btn.set_tooltip_text(string_compose(P_(
1111 "%1 more page of 100 results available",
1112 "%1 more pages of 100 results available",
1113 more_pages), more_pages));
1115 freesound_more_btn.set_sensitive(false);
1116 freesound_more_btn.set_tooltip_text(_("No more results available"));
1119 XMLNode *sounds_root = root->child("sounds");
1121 error << "no child node \"sounds\" found!" << endmsg;
1125 XMLNodeList sounds = sounds_root->children();
1126 if (sounds.size() == 0) {
1131 XMLNodeConstIterator niter;
1133 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1135 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1136 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1140 // node->dump(cerr, "node:");
1143 XMLNode *id_node = node->child ("id");
1144 XMLNode *uri_node = node->child ("serve");
1145 XMLNode *ofn_node = node->child ("original_filename");
1146 XMLNode *dur_node = node->child ("duration");
1147 XMLNode *siz_node = node->child ("filesize");
1148 XMLNode *srt_node = node->child ("samplerate");
1149 XMLNode *lic_node = node->child ("license");
1151 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1153 std::string id = id_node->child("text")->content();
1154 std::string uri = uri_node->child("text")->content();
1155 std::string ofn = ofn_node->child("text")->content();
1156 std::string dur = dur_node->child("text")->content();
1157 std::string siz = siz_node->child("text")->content();
1158 std::string srt = srt_node->child("text")->content();
1159 std::string lic = lic_node->child("text")->content();
1162 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1164 double duration_seconds = atof(dur);
1166 char duration_hhmmss[16];
1167 if (duration_seconds >= 99 * 60 * 60) {
1168 strcpy(duration_hhmmss, ">99h");
1170 s = modf(duration_seconds/60, &m) * 60;
1171 m = modf(m/60, &h) * 60;
1172 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1177 double size_bytes = atof(siz);
1179 if (size_bytes < 1000) {
1180 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1181 } else if (size_bytes < 1000000 ) {
1182 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1183 } else if (size_bytes < 10000000) {
1184 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1185 } else if (size_bytes < 1000000000) {
1186 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1188 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1191 /* see http://www.freesound.org/help/faq/#licenses */
1192 char shortlicense[64];
1193 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1194 sprintf(shortlicense, "CC-BY-NC");
1195 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1196 sprintf(shortlicense, "CC-BY");
1197 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1198 sprintf(shortlicense, "sampling+");
1199 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1200 sprintf(shortlicense, "PD");
1202 snprintf(shortlicense, 64, "%s", lic.c_str());
1203 shortlicense[63]= '\0';
1206 TreeModel::iterator new_row = freesound_list->append();
1207 TreeModel::Row row = *new_row;
1209 row[freesound_list_columns.id ] = id;
1210 row[freesound_list_columns.uri ] = uri;
1211 row[freesound_list_columns.filename] = ofn;
1212 row[freesound_list_columns.duration] = duration_hhmmss;
1213 row[freesound_list_columns.filesize] = bsize;
1214 row[freesound_list_columns.smplrate] = srt;
1215 row[freesound_list_columns.license ] = shortlicense;
1222 SoundFileBrowser::get_paths ()
1224 vector<string> results;
1226 int n = notebook.get_current_page ();
1229 vector<string> filenames = chooser.get_filenames();
1230 vector<string>::iterator i;
1232 for (i = filenames.begin(); i != filenames.end(); ++i) {
1234 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1235 results.push_back (*i);
1239 } else if (n == 1) {
1241 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1242 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1243 TreeIter iter = found_list->get_iter(*i);
1244 string str = (*iter)[found_list_columns.pathname];
1246 results.push_back (str);
1249 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1250 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1251 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1253 results.push_back (str);
1262 SoundFileOmega::reset_options_noret ()
1264 if (!resetting_ourselves) {
1265 (void) reset_options ();
1270 SoundFileOmega::reset_options ()
1272 vector<string> paths = get_paths ();
1274 if (paths.empty()) {
1276 channel_combo.set_sensitive (false);
1277 action_combo.set_sensitive (false);
1278 where_combo.set_sensitive (false);
1279 copy_files_btn.set_active (true);
1280 copy_files_btn.set_sensitive (false);
1286 channel_combo.set_sensitive (true);
1287 action_combo.set_sensitive (true);
1288 where_combo.set_sensitive (true);
1290 /* if we get through this function successfully, this may be
1291 reset at the end, once we know if we can use hard links
1292 to do embedding (or if we are importing a MIDI file).
1295 if (Config->get_only_copy_imported_files()) {
1296 copy_files_btn.set_sensitive (false);
1298 copy_files_btn.set_sensitive (false);
1304 bool selection_includes_multichannel;
1305 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1308 /* See if we are thinking about importing any MIDI files */
1309 vector<string>::iterator i = paths.begin ();
1310 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1313 bool const have_a_midi_file = (i != paths.end ());
1315 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1316 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1320 string existing_choice;
1321 vector<string> action_strings;
1323 resetting_ourselves = true;
1325 if (chooser.get_filter() == &audio_filter) {
1329 if (selected_audio_track_cnt > 0) {
1330 if (channel_combo.get_active_text().length()) {
1331 ImportDisposition id = get_channel_disposition();
1334 case Editing::ImportDistinctFiles:
1335 if (selected_audio_track_cnt == paths.size()) {
1336 action_strings.push_back (importmode2string (ImportToTrack));
1340 case Editing::ImportDistinctChannels:
1341 /* XXX it would be nice to allow channel-per-selected track
1342 but its too hard we don't want to deal with all the
1343 different per-file + per-track channel configurations.
1348 action_strings.push_back (importmode2string (ImportToTrack));
1358 if (selected_midi_track_cnt > 0) {
1359 action_strings.push_back (importmode2string (ImportToTrack));
1363 action_strings.push_back (importmode2string (ImportAsTrack));
1364 action_strings.push_back (importmode2string (ImportAsRegion));
1365 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1367 existing_choice = action_combo.get_active_text();
1369 set_popdown_strings (action_combo, action_strings);
1371 /* preserve any existing choice, if possible */
1374 if (existing_choice.length()) {
1375 vector<string>::iterator x;
1376 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1377 if (*x == existing_choice) {
1378 action_combo.set_active_text (existing_choice);
1382 if (x == action_strings.end()) {
1383 action_combo.set_active_text (action_strings.front());
1386 action_combo.set_active_text (action_strings.front());
1389 resetting_ourselves = false;
1391 if ((mode = get_mode()) == ImportAsRegion) {
1392 where_combo.set_sensitive (false);
1394 where_combo.set_sensitive (true);
1397 vector<string> channel_strings;
1399 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1400 channel_strings.push_back (_("one track per file"));
1402 if (selection_includes_multichannel) {
1403 channel_strings.push_back (_("one track per channel"));
1406 if (paths.size() > 1) {
1407 /* tape tracks are a single region per track, so we cannot
1408 sequence multiple files.
1410 if (mode != ImportAsTapeTrack) {
1411 channel_strings.push_back (_("sequence files"));
1414 channel_strings.push_back (_("all files in one track"));
1415 channel_strings.push_back (_("merge files"));
1421 channel_strings.push_back (_("one region per file"));
1423 if (selection_includes_multichannel) {
1424 channel_strings.push_back (_("one region per channel"));
1427 if (paths.size() > 1) {
1429 channel_strings.push_back (_("all files in one region"));
1434 resetting_ourselves = true;
1436 existing_choice = channel_combo.get_active_text();
1438 set_popdown_strings (channel_combo, channel_strings);
1440 /* preserve any existing choice, if possible */
1442 if (existing_choice.length()) {
1443 vector<string>::iterator x;
1444 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1445 if (*x == existing_choice) {
1446 channel_combo.set_active_text (existing_choice);
1450 if (x == channel_strings.end()) {
1451 channel_combo.set_active_text (channel_strings.front());
1454 channel_combo.set_active_text (channel_strings.front());
1457 resetting_ourselves = false;
1460 src_combo.set_sensitive (true);
1462 src_combo.set_sensitive (false);
1465 /* We must copy MIDI files or those from Freesound
1466 * or any file if we are under nsm control */
1467 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1469 if (Config->get_only_copy_imported_files()) {
1471 if (selection_can_be_embedded_with_links && !must_copy) {
1472 copy_files_btn.set_sensitive (true);
1475 copy_files_btn.set_active (true);
1477 copy_files_btn.set_sensitive (false);
1483 copy_files_btn.set_active (true);
1485 copy_files_btn.set_sensitive (!must_copy);
1493 SoundFileOmega::bad_file_message()
1495 MessageDialog msg (*this,
1496 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1501 resetting_ourselves = true;
1502 chooser.unselect_uri (chooser.get_preview_uri());
1503 resetting_ourselves = false;
1509 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1518 multichannel = false;
1520 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1522 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1523 if (info.channels > 1) {
1524 multichannel = true;
1529 if (sz != info.length) {
1534 if (info.samplerate != _session->frame_rate()) {
1538 } else if (SMFSource::safe_midi_file_extension (*i)) {
1542 if (reader.num_tracks() > 1) {
1543 multichannel = true; // "channel" == track here...
1546 /* XXX we need err = true handling here in case
1547 we can't check the file
1560 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1562 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1565 if (mkdir (tmpdir.c_str(), 0744)) {
1566 if (errno != EEXIST) {
1571 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1573 char tmpc[PATH_MAX+1];
1575 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1579 if (link ((*i).c_str(), tmpc)) {
1589 rmdir (tmpdir.c_str());
1593 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1594 : SoundFileBrowser (title, s, false)
1596 chooser.set_select_multiple (false);
1597 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1598 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1602 SoundFileChooser::on_hide ()
1604 ArdourWindow::on_hide();
1608 _session->cancel_audition();
1613 SoundFileChooser::get_filename ()
1615 vector<string> paths;
1617 paths = get_paths ();
1619 if (paths.empty()) {
1623 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1627 return paths.front();
1630 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1631 uint32_t selected_audio_tracks,
1632 uint32_t selected_midi_tracks,
1634 Editing::ImportMode mode_hint)
1635 : SoundFileBrowser (title, s, persistent)
1636 , copy_files_btn ( _("Copy files to session"))
1637 , selected_audio_track_cnt (selected_audio_tracks)
1638 , selected_midi_track_cnt (selected_midi_tracks)
1644 set_size_request (-1, 450);
1646 block_two.set_border_width (12);
1647 block_three.set_border_width (12);
1648 block_four.set_border_width (12);
1650 options.set_spacing (12);
1653 str.push_back (_("file timestamp"));
1654 str.push_back (_("edit point"));
1655 str.push_back (_("playhead"));
1656 str.push_back (_("session start"));
1657 set_popdown_strings (where_combo, str);
1658 where_combo.set_active_text (str.front());
1660 Label* l = manage (new Label);
1661 l->set_markup (_("<b>Add files as ...</b>"));
1663 vbox = manage (new VBox);
1664 vbox->set_border_width (12);
1665 vbox->set_spacing (6);
1666 vbox->pack_start (*l, false, false);
1667 vbox->pack_start (action_combo, false, false);
1668 hbox = manage (new HBox);
1669 hbox->pack_start (*vbox, false, false);
1670 options.pack_start (*hbox, false, false);
1672 /* dummy entry for action combo so that it doesn't look odd if we
1673 come up with no tracks selected.
1677 str.push_back (importmode2string (mode_hint));
1678 set_popdown_strings (action_combo, str);
1679 action_combo.set_active_text (str.front());
1680 action_combo.set_sensitive (false);
1682 l = manage (new Label);
1683 l->set_markup (_("<b>Insert at</b>"));
1685 vbox = manage (new VBox);
1686 vbox->set_border_width (12);
1687 vbox->set_spacing (6);
1688 vbox->pack_start (*l, false, false);
1689 vbox->pack_start (where_combo, false, false);
1690 hbox = manage (new HBox);
1691 hbox->pack_start (*vbox, false, false);
1692 options.pack_start (*hbox, false, false);
1695 l = manage (new Label);
1696 l->set_markup (_("<b>Mapping</b>"));
1698 vbox = manage (new VBox);
1699 vbox->set_border_width (12);
1700 vbox->set_spacing (6);
1701 vbox->pack_start (*l, false, false);
1702 vbox->pack_start (channel_combo, false, false);
1703 hbox = manage (new HBox);
1704 hbox->pack_start (*vbox, false, false);
1705 options.pack_start (*hbox, false, false);
1708 str.push_back (_("one track per file"));
1709 set_popdown_strings (channel_combo, str);
1710 channel_combo.set_active_text (str.front());
1711 channel_combo.set_sensitive (false);
1713 l = manage (new Label);
1714 l->set_markup (_("<b>Conversion quality</b>"));
1716 vbox = manage (new VBox);
1717 vbox->set_border_width (12);
1718 vbox->set_spacing (6);
1719 vbox->pack_start (*l, false, false);
1720 vbox->pack_start (src_combo, false, false);
1721 hbox = manage (new HBox);
1722 hbox->pack_start (*vbox, false, false);
1723 options.pack_start (*hbox, false, false);
1726 str.push_back (_("Best"));
1727 str.push_back (_("Good"));
1728 str.push_back (_("Quick"));
1729 str.push_back (_("Fast"));
1730 str.push_back (_("Fastest"));
1732 set_popdown_strings (src_combo, str);
1733 src_combo.set_active_text (str.front());
1734 src_combo.set_sensitive (false);
1735 src_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::src_combo_changed));
1739 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1740 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1742 copy_files_btn.set_active (true);
1744 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1747 copy_label->set_size_request (175, -1);
1748 copy_label->set_line_wrap (true);
1751 block_four.pack_start (copy_files_btn, false, false);
1753 options.pack_start (block_four, false, false);
1755 vpacker.pack_start (options, false, false);
1757 /* setup disposition map */
1759 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1760 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1761 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1762 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1764 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1765 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1766 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1767 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1769 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1771 /* set size requests for a couple of combos to allow them to display the longest text
1772 they will ever be asked to display. This prevents them being resized when the user
1773 selects a file to import, which in turn prevents the size of the dialog from jumping
1777 t.push_back (_("one track per file"));
1778 t.push_back (_("one track per channel"));
1779 t.push_back (_("sequence files"));
1780 t.push_back (_("all files in one region"));
1781 set_popdown_strings (channel_combo, t);
1784 t.push_back (importmode2string (ImportAsTrack));
1785 t.push_back (importmode2string (ImportToTrack));
1786 t.push_back (importmode2string (ImportAsRegion));
1787 t.push_back (importmode2string (ImportAsTapeTrack));
1788 set_popdown_strings (action_combo, t);
1792 SoundFileOmega::set_mode (ImportMode mode)
1794 action_combo.set_active_text (importmode2string (mode));
1798 SoundFileOmega::get_mode () const
1800 return string2importmode (action_combo.get_active_text());
1804 SoundFileOmega::on_hide ()
1806 ArdourWindow::on_hide();
1808 _session->cancel_audition();
1813 SoundFileOmega::get_position() const
1815 string str = where_combo.get_active_text();
1817 if (str == _("file timestamp")) {
1818 return ImportAtTimestamp;
1819 } else if (str == _("edit point")) {
1820 return ImportAtEditPoint;
1821 } else if (str == _("playhead")) {
1822 return ImportAtPlayhead;
1824 return ImportAtStart;
1829 SoundFileOmega::get_src_quality() const
1831 string str = src_combo.get_active_text();
1833 if (str == _("Best")) {
1835 } else if (str == _("Good")) {
1837 } else if (str == _("Quick")) {
1839 } else if (str == _("Fast")) {
1847 SoundFileOmega::src_combo_changed()
1849 preview.set_src_quality(get_src_quality());
1853 SoundFileOmega::get_channel_disposition () const
1855 /* we use a map here because the channel combo can contain different strings
1856 depending on the state of the other combos. the map contains all possible strings
1857 and the ImportDisposition enum that corresponds to it.
1860 string str = channel_combo.get_active_text();
1861 DispositionMap::const_iterator x = disposition_map.find (str);
1863 if (x == disposition_map.end()) {
1864 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1872 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1874 selected_audio_track_cnt = selected_audio_tracks;
1875 selected_midi_track_cnt = selected_midi_tracks;
1877 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1878 chooser.set_filter (midi_filter);
1879 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1880 chooser.set_filter (audio_filter);
1882 chooser.set_filter (audio_and_midi_filter);
1889 SoundFileOmega::file_selection_changed ()
1891 if (resetting_ourselves) {
1895 if (!reset_options ()) {
1896 set_action_sensitive (false);
1898 if (chooser.get_filenames().size() > 0) {
1899 set_action_sensitive (true);
1901 set_action_sensitive (false);
1907 SoundFileOmega::do_something (int action)
1909 SoundFileBrowser::do_something (action);
1911 if (action == RESPONSE_CANCEL) {
1918 vector<string> paths = get_paths ();
1919 ImportPosition pos = get_position ();
1920 ImportMode mode = get_mode ();
1921 ImportDisposition chns = get_channel_disposition ();
1925 case ImportAtEditPoint:
1926 where = PublicEditor::instance().get_preferred_edit_position ();
1928 case ImportAtTimestamp:
1931 case ImportAtPlayhead:
1932 where = _session->transport_frame();
1935 where = _session->current_start_frame();
1939 SrcQuality quality = get_src_quality();
1941 if (copy_files_btn.get_active()) {
1942 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1944 PublicEditor::instance().do_embed (paths, chns, mode, where);
1947 if (action == RESPONSE_OK) {