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"
57 #include "ardour/srcfilesource.h"
59 #include "ardour_ui.h"
61 #include "gui_thread.h"
66 #include "gain_meter.h"
67 #include "main_clock.h"
68 #include "public_editor.h"
70 #include "sfdb_freesound_mootcher.h"
74 using namespace ARDOUR;
78 using namespace Gtkmm2ext;
79 using namespace Editing;
83 string SoundFileBrowser::persistent_folder;
84 typedef TreeView::Selection::ListHandle_Path ListPath;
87 string2importmode (string str)
89 if (str == _("as new tracks")) {
91 } else if (str == _("to selected tracks")) {
93 } else if (str == _("to region list")) {
94 return ImportAsRegion;
95 } else if (str == _("as new tape tracks")) {
96 return ImportAsTapeTrack;
99 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
101 return ImportAsTrack;
105 importmode2string (ImportMode mode)
109 return _("as new tracks");
111 return _("to selected tracks");
113 return _("to region list");
114 case ImportAsTapeTrack:
115 return _("as new tape tracks");
118 return _("as new tracks");
121 SoundFileBox::SoundFileBox (bool /*persistent*/)
123 length_clock ("sfboxLengthClock", true, "", false, false, true, false),
124 timecode_clock ("sfboxTimecodeClock", true, "", false, false, false, false),
126 autoplay_btn (_("Auto-play")),
127 seek_slider(0,1000,1),
131 set_name (X_("SoundFileBox"));
132 set_size_request (300, -1);
134 preview_label.set_markup (_("<b>Sound File Information</b>"));
136 border_frame.set_label_widget (preview_label);
137 border_frame.add (main_box);
139 pack_start (border_frame, true, true);
140 set_border_width (6);
142 main_box.set_border_width (6);
144 length.set_text (_("Length:"));
145 length.set_alignment (1, 0.5);
146 timecode.set_text (_("Timestamp:"));
147 timecode.set_alignment (1, 0.5);
148 format.set_text (_("Format:"));
149 format.set_alignment (1, 0.5);
150 channels.set_text (_("Channels:"));
151 channels.set_alignment (1, 0.5);
152 samplerate.set_text (_("Sample rate:"));
153 samplerate.set_alignment (1, 0.5);
155 preview_label.set_max_width_chars (50);
156 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
158 format_text.set_max_width_chars (20);
159 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
160 format_text.set_alignment (0, 1);
162 table.set_col_spacings (6);
163 table.set_homogeneous (false);
164 table.set_row_spacings (6);
166 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
167 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
168 table.attach (format, 0, 1, 2, 4, FILL, FILL);
169 table.attach (length, 0, 1, 4, 5, FILL, FILL);
170 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
172 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
173 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
174 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
175 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
176 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
178 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
179 timecode_clock.set_mode (AudioClock::Timecode);
181 main_box.pack_start (table, false, false);
183 tags_entry.set_editable (true);
184 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
185 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
187 Label* label = manage (new Label (_("Tags:")));
188 label->set_alignment (0.0f, 0.5f);
189 main_box.pack_start (*label, false, false);
190 main_box.pack_start (tags_entry, true, true);
192 main_box.pack_start (bottom_box, false, false);
194 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
195 // play_btn.set_label (_("Play"));
197 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
198 // stop_btn.set_label (_("Stop"));
200 bottom_box.set_homogeneous (false);
201 bottom_box.set_spacing (6);
202 bottom_box.pack_start(play_btn, true, true);
203 bottom_box.pack_start(stop_btn, true, true);
204 bottom_box.pack_start(autoplay_btn, false, false);
206 seek_slider.set_draw_value(false);
208 seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
209 seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
210 seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
211 main_box.pack_start (seek_slider, false, false);
213 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
214 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
216 stop_btn.set_sensitive (false);
218 channels_value.set_alignment (0.0f, 0.5f);
219 samplerate_value.set_alignment (0.0f, 0.5f);
223 SoundFileBox::set_session(Session* s)
225 SessionHandlePtr::set_session (s);
227 length_clock.set_session (s);
228 timecode_clock.set_session (s);
231 play_btn.set_sensitive (false);
232 stop_btn.set_sensitive (false);
233 auditioner_connections.drop_connections();
235 auditioner_connections.drop_connections();
236 _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
237 _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
242 SoundFileBox::audition_active(bool active) {
243 stop_btn.set_sensitive (active);
244 seek_slider.set_sensitive (active);
246 seek_slider.set_value(0);
251 SoundFileBox::audition_progress(ARDOUR::framecnt_t pos, ARDOUR::framecnt_t len) {
253 seek_slider.set_value( 1000.0 * pos / len);
254 seek_slider.set_sensitive (true);
259 SoundFileBox::seek_button_press(GdkEventButton*) {
261 return false; // pass on to slider
265 SoundFileBox::seek_button_release(GdkEventButton*) {
267 _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
268 seek_slider.set_sensitive (false);
269 return false; // pass on to slider
273 SoundFileBox::setup_labels (const string& filename)
276 // save existing tags
284 if (SMFSource::safe_midi_file_extension (path)) {
286 boost::shared_ptr<SMFSource> ms =
287 boost::dynamic_pointer_cast<SMFSource> (
288 SourceFactory::createExternal (DataType::MIDI, *_session,
289 path, 0, Source::Flag (0), false));
291 preview_label.set_markup (_("<b>Midi File Information</b>"));
293 format_text.set_text ("MIDI");
294 samplerate_value.set_text ("-");
295 tags_entry.get_buffer()->set_text ("");
296 timecode_clock.set (0);
297 tags_entry.set_sensitive (false);
300 channels_value.set_text (to_string(ms->num_tracks(), std::dec));
301 length_clock.set (ms->length(ms->timeline_position()));
303 channels_value.set_text ("");
304 length_clock.set (0);
307 if (_session && ms) {
308 play_btn.set_sensitive (true);
310 play_btn.set_sensitive (false);
316 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
318 preview_label.set_markup (_("<b>Sound File Information</b>"));
319 format_text.set_text ("");
320 channels_value.set_text ("");
321 samplerate_value.set_text ("");
322 tags_entry.get_buffer()->set_text ("");
324 length_clock.set (0);
325 timecode_clock.set (0);
327 tags_entry.set_sensitive (false);
328 play_btn.set_sensitive (false);
333 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
334 std::string n = sf_info.format_name;
335 if (n.substr (0, 8) == X_("Format: ")) {
338 format_text.set_text (n);
339 channels_value.set_text (to_string (sf_info.channels, std::dec));
341 if (_session && sf_info.samplerate != _session->frame_rate()) {
342 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
343 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
344 samplerate_value.set_name ("NewSessionSR1Label");
345 samplerate.set_name ("NewSessionSR1Label");
347 samplerate.set_text (_("Sample rate:"));
348 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
349 samplerate_value.set_name ("NewSessionSR2Label");
350 samplerate.set_name ("NewSessionSR2Label");
353 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
354 double src_coef = (double) nfr / sf_info.samplerate;
356 length_clock.set (sf_info.length * src_coef + 0.5, true);
357 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
359 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
361 vector<string> tags = Library->get_tags (string ("//") + filename);
363 stringstream tag_string;
364 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
365 if (i != tags.begin()) {
370 tags_entry.get_buffer()->set_text (tag_string.str());
372 tags_entry.set_sensitive (true);
374 play_btn.set_sensitive (true);
381 SoundFileBox::autoplay() const
383 return autoplay_btn.get_active();
387 SoundFileBox::audition_oneshot()
394 SoundFileBox::audition ()
400 _session->cancel_audition();
402 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
403 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
407 boost::shared_ptr<Region> r;
409 if (SMFSource::safe_midi_file_extension (path)) {
411 boost::shared_ptr<SMFSource> ms =
412 boost::dynamic_pointer_cast<SMFSource> (
413 SourceFactory::createExternal (DataType::MIDI, *_session,
414 path, 0, Source::Flag (0), false));
416 string rname = region_name_from_path (ms->path(), false);
420 plist.add (ARDOUR::Properties::start, 0);
421 plist.add (ARDOUR::Properties::length, ms->length(ms->timeline_position()));
422 plist.add (ARDOUR::Properties::name, rname);
423 plist.add (ARDOUR::Properties::layer, 0);
425 r = boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (boost::dynamic_pointer_cast<Source>(ms), plist, false));
431 boost::shared_ptr<AudioFileSource> afs;
432 bool old_sbp = AudioSource::get_build_peakfiles ();
434 /* don't even think of building peakfiles for these files */
436 AudioSource::set_build_peakfiles (false);
438 for (int n = 0; n < sf_info.channels; ++n) {
440 afs = boost::dynamic_pointer_cast<AudioFileSource> (
441 SourceFactory::createExternal (DataType::AUDIO, *_session,
443 Source::Flag (0), false));
444 if (afs->sample_rate() != _session->nominal_frame_rate()) {
445 boost::shared_ptr<SrcFileSource> sfs (new SrcFileSource(*_session, afs, _src_quality));
446 srclist.push_back(sfs);
448 srclist.push_back(afs);
451 } catch (failed_constructor& err) {
452 error << _("Could not access soundfile: ") << path << endmsg;
453 AudioSource::set_build_peakfiles (old_sbp);
458 AudioSource::set_build_peakfiles (old_sbp);
460 if (srclist.empty()) {
464 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
465 string rname = region_name_from_path (afs->path(), false);
469 plist.add (ARDOUR::Properties::start, 0);
470 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
471 plist.add (ARDOUR::Properties::name, rname);
472 plist.add (ARDOUR::Properties::layer, 0);
474 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
477 _session->audition_region(r);
481 SoundFileBox::stop_audition ()
484 _session->cancel_audition();
489 SoundFileBox::tags_entry_left (GdkEventFocus *)
496 SoundFileBox::tags_changed ()
498 string tag_string = tags_entry.get_buffer()->get_text ();
500 if (tag_string.empty()) {
506 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
507 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
515 SoundFileBox::save_tags (const vector<string>& tags)
517 Library->set_tags (string ("//") + path, tags);
518 Library->save_changes ();
521 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
522 : ArdourWindow (title)
523 , found_list (ListStore::create(found_list_columns))
524 , freesound_list (ListStore::create(freesound_list_columns))
525 , chooser (FILE_CHOOSER_ACTION_OPEN)
526 , preview (persistent)
527 , found_search_btn (_("Search"))
528 , found_list_view (found_list)
529 , freesound_search_btn (_("Search"))
530 , freesound_list_view (freesound_list)
531 , resetting_ourselves (false)
535 , ok_button (Stock::OK)
536 , cancel_button (Stock::CANCEL)
537 , apply_button (Stock::APPLY)
542 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
543 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
544 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
545 chooser.add_shortcut_folder_uri("file:///Volumes");
548 //add the file chooser
550 chooser.set_border_width (12);
552 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
553 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
555 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
556 audio_filter.set_name (_("Audio files"));
558 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
559 midi_filter.set_name (_("MIDI files"));
561 matchall_filter.add_pattern ("*.*");
562 matchall_filter.set_name (_("All files"));
564 chooser.add_filter (audio_and_midi_filter);
565 chooser.add_filter (audio_filter);
566 chooser.add_filter (midi_filter);
567 chooser.add_filter (matchall_filter);
568 chooser.set_select_multiple (true);
569 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
570 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
573 /* some broken redraw behaviour - this is a bandaid */
574 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
577 if (!persistent_folder.empty()) {
578 chooser.set_current_folder (persistent_folder);
581 notebook.append_page (chooser, _("Browse Files"));
583 hpacker.set_spacing (6);
584 hpacker.pack_start (notebook, true, true);
585 hpacker.pack_start (preview, false, false);
587 vpacker.set_spacing (6);
588 vpacker.pack_start (hpacker, true, true);
598 hbox = manage(new HBox);
599 hbox->pack_start (found_entry);
600 hbox->pack_start (found_search_btn);
602 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
603 scroll->add(found_list_view);
604 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
606 vbox = manage(new VBox);
607 vbox->pack_start (*hbox, PACK_SHRINK);
608 vbox->pack_start (*scroll);
610 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
612 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
614 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
616 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
617 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
619 notebook.append_page (*vbox, _("Search Tags"));
621 //add freesound search
626 passbox = manage(new HBox);
627 passbox->set_spacing (6);
629 label = manage (new Label);
630 label->set_text (_("Tags:"));
631 passbox->pack_start (*label, false, false);
632 passbox->pack_start (freesound_entry, true, true);
634 label = manage (new Label);
635 label->set_text (_("Sort:"));
636 passbox->pack_start (*label, false, false);
637 passbox->pack_start (freesound_sort, false, false);
638 freesound_sort.clear_items();
640 // Order of the following must correspond with enum sortMethod
641 // in sfdb_freesound_mootcher.h
642 freesound_sort.append_text(_("None"));
643 freesound_sort.append_text(_("Longest"));
644 freesound_sort.append_text(_("Shortest"));
645 freesound_sort.append_text(_("Newest"));
646 freesound_sort.append_text(_("Oldest"));
647 freesound_sort.append_text(_("Most downloaded"));
648 freesound_sort.append_text(_("Least downloaded"));
649 freesound_sort.append_text(_("Highest rated"));
650 freesound_sort.append_text(_("Lowest rated"));
651 freesound_sort.set_active(0);
653 passbox->pack_start (freesound_search_btn, false, false);
654 passbox->pack_start (freesound_more_btn, false, false);
655 freesound_more_btn.set_label(_("More"));
656 freesound_more_btn.set_sensitive(false);
658 passbox->pack_start (freesound_similar_btn, false, false);
659 freesound_similar_btn.set_label(_("Similar"));
660 freesound_similar_btn.set_sensitive(false);
662 scroll = manage(new ScrolledWindow);
663 scroll->add(freesound_list_view);
664 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
666 vbox = manage(new VBox);
667 vbox->set_spacing (3);
668 vbox->pack_start (*passbox, PACK_SHRINK);
669 vbox->pack_start (*scroll);
671 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
672 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
673 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
674 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
675 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
676 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
677 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
678 freesound_list_view.get_column(0)->set_alignment(0.5);
679 freesound_list_view.get_column(1)->set_expand(true); // filename
680 freesound_list_view.get_column(1)->set_resizable(true); // filename
681 freesound_list_view.get_column(2)->set_alignment(0.5);
682 freesound_list_view.get_column(3)->set_alignment(0.5);
683 freesound_list_view.get_column(4)->set_alignment(0.5);
684 freesound_list_view.get_column(5)->set_alignment(0.5);
686 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
687 freesound_list_view.set_tooltip_column(1);
689 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
690 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
691 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
692 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
693 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
694 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
695 notebook.append_page (*vbox, _("Search Freesound"));
697 notebook.set_size_request (500, -1);
698 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
702 Gtk::HButtonBox* button_box = manage (new HButtonBox);
704 button_box->set_layout (BUTTONBOX_END);
705 button_box->pack_start (cancel_button, false, false);
706 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
708 button_box->pack_start (apply_button, false, false);
709 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
712 button_box->pack_start (ok_button, false, false);
713 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
715 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
716 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
717 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
719 vpacker.pack_end (*button_box, false, false);
721 set_wmclass (X_("import"), PROGRAM_NAME);
724 SoundFileBrowser::~SoundFileBrowser ()
726 persistent_folder = chooser.get_current_folder();
730 SoundFileBrowser::run ()
739 gtk_main_iteration ();
746 SoundFileBrowser::set_action_sensitive (bool yn)
748 ok_button.set_sensitive (yn);
749 apply_button.set_sensitive (yn);
753 SoundFileBrowser::do_something (int action)
760 SoundFileBrowser::on_show ()
762 ArdourWindow::on_show ();
767 SoundFileBrowser::clear_selection ()
769 chooser.unselect_all ();
770 found_list_view.get_selection()->unselect_all ();
774 SoundFileBrowser::chooser_file_activated ()
780 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
786 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
792 SoundFileBrowser::set_session (Session* s)
794 ArdourWindow::set_session (s);
795 preview.set_session (s);
800 remove_gain_meter ();
805 SoundFileBrowser::add_gain_meter ()
809 gm = new GainMeter (_session, 250);
811 boost::shared_ptr<Route> r = _session->the_auditioner ();
813 gm->set_controls (r, r->shared_peak_meter(), r->amp());
814 gm->set_fader_name (X_("GainFader"));
816 meter_packer.set_border_width (12);
817 meter_packer.pack_start (*gm, false, true);
818 hpacker.pack_end (meter_packer, false, false);
819 meter_packer.show_all ();
824 SoundFileBrowser::remove_gain_meter ()
827 meter_packer.remove (*gm);
828 hpacker.remove (meter_packer);
835 SoundFileBrowser::start_metering ()
837 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
841 SoundFileBrowser::stop_metering ()
843 metering_connection.disconnect();
847 SoundFileBrowser::meter ()
849 if (is_mapped () && _session && gm) {
850 gm->update_meters ();
855 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
857 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
861 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
863 return SMFSource::safe_midi_file_extension (filter_info.filename);
867 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
869 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
873 SoundFileBrowser::update_preview ()
875 if (preview.setup_labels (chooser.get_preview_filename())) {
876 if (preview.autoplay()) {
877 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
883 SoundFileBrowser::found_list_view_selected ()
885 if (!reset_options ()) {
886 set_action_sensitive (false);
890 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
893 TreeIter iter = found_list->get_iter(*rows.begin());
894 file = (*iter)[found_list_columns.pathname];
895 chooser.set_filename (file);
896 set_action_sensitive (true);
898 set_action_sensitive (false);
901 preview.setup_labels (file);
906 SoundFileBrowser::found_search_clicked ()
908 string tag_string = found_entry.get_text ();
912 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
913 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
917 vector<string> results;
918 Library->search_members_and (results, tags);
921 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
922 TreeModel::iterator new_row = found_list->append();
923 TreeModel::Row row = *new_row;
924 string path = Glib::filename_from_uri (string ("file:") + *i);
925 row[found_list_columns.pathname] = path;
931 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
934 Mootcher *mootcher = new Mootcher;
937 string id = (*iter)[freesound_list_columns.id];
938 string uri = (*iter)[freesound_list_columns.uri];
939 string ofn = (*iter)[freesound_list_columns.filename];
941 if (mootcher->checkAudioFile(ofn, id)) {
942 // file already exists, no need to download it again
943 file = mootcher->audioFileName;
945 (*iter)[freesound_list_columns.started] = false;
948 if (!(*iter)[freesound_list_columns.started]) {
949 // start downloading the sound file
950 (*iter)[freesound_list_columns.started] = true;
951 mootcher->fetchAudioFile(ofn, id, uri, this);
957 SoundFileBrowser::freesound_list_view_selected ()
960 if (!reset_options ()) {
961 set_action_sensitive (false);
964 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
965 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
966 file = freesound_get_audio_file (freesound_list->get_iter(*i));
969 switch (rows.size()) {
972 freesound_similar_btn.set_sensitive(false);
973 set_action_sensitive (false);
976 // exactly one item selected
978 // file exists on disk already
979 chooser.set_filename (file);
980 preview.setup_labels (file);
981 set_action_sensitive (true);
983 freesound_similar_btn.set_sensitive(true);
986 // multiple items selected
987 preview.setup_labels ("");
988 freesound_similar_btn.set_sensitive(false);
996 SoundFileBrowser::refresh_display(std::string ID, std::string file)
998 // called when the mootcher has finished downloading a file
999 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1000 if (rows.size() == 1) {
1001 // there's a single item selected in the freesound list
1002 //XXX make a function to be used to construct the actual file name both here and in the mootcher
1003 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
1004 std::string selected_ID = (*row)[freesound_list_columns.id];
1005 if (ID == selected_ID) {
1006 // the selected item in the freesound list is the item that has just finished downloading
1007 chooser.set_filename(file);
1008 preview.setup_labels (file);
1009 set_action_sensitive (true);
1015 SoundFileBrowser::freesound_search_clicked ()
1018 freesound_list->clear();
1024 SoundFileBrowser::freesound_more_clicked ()
1029 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
1030 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
1034 SoundFileBrowser::freesound_similar_clicked ()
1036 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1037 if (rows.size() == 1) {
1040 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
1041 id = (*iter)[freesound_list_columns.id];
1042 freesound_list->clear();
1044 GdkCursor *prev_cursor;
1045 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1046 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1049 std::string theString = mootcher.searchSimilar(id);
1051 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1052 handle_freesound_results(theString);
1057 SoundFileBrowser::freesound_search()
1061 string search_string = freesound_entry.get_text ();
1062 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1064 GdkCursor *prev_cursor;
1065 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1066 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1069 std::string theString = mootcher.searchText(
1073 "", // OSX eats anything incl mp3
1075 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1080 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1081 handle_freesound_results(theString);
1085 SoundFileBrowser::handle_freesound_results(std::string theString) {
1087 doc.read_buffer( theString );
1088 XMLNode *root = doc.root();
1091 error << "no root XML node!" << endmsg;
1095 if ( strcmp(root->name().c_str(), "response") != 0) {
1096 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1100 // find out how many pages are available to search
1101 int freesound_n_pages = 1;
1102 XMLNode *res = root->child("num_pages");
1104 string result = res->child("text")->content();
1105 freesound_n_pages = atoi(result);
1108 int more_pages = freesound_n_pages - freesound_page;
1110 if (more_pages > 0) {
1111 freesound_more_btn.set_sensitive(true);
1112 freesound_more_btn.set_tooltip_text(string_compose(P_(
1113 "%1 more page of 100 results available",
1114 "%1 more pages of 100 results available",
1115 more_pages), more_pages));
1117 freesound_more_btn.set_sensitive(false);
1118 freesound_more_btn.set_tooltip_text(_("No more results available"));
1121 XMLNode *sounds_root = root->child("sounds");
1123 error << "no child node \"sounds\" found!" << endmsg;
1127 XMLNodeList sounds = sounds_root->children();
1128 if (sounds.size() == 0) {
1133 XMLNodeConstIterator niter;
1135 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1137 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1138 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1142 // node->dump(cerr, "node:");
1145 XMLNode *id_node = node->child ("id");
1146 XMLNode *uri_node = node->child ("serve");
1147 XMLNode *ofn_node = node->child ("original_filename");
1148 XMLNode *dur_node = node->child ("duration");
1149 XMLNode *siz_node = node->child ("filesize");
1150 XMLNode *srt_node = node->child ("samplerate");
1151 XMLNode *lic_node = node->child ("license");
1153 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1155 std::string id = id_node->child("text")->content();
1156 std::string uri = uri_node->child("text")->content();
1157 std::string ofn = ofn_node->child("text")->content();
1158 std::string dur = dur_node->child("text")->content();
1159 std::string siz = siz_node->child("text")->content();
1160 std::string srt = srt_node->child("text")->content();
1161 std::string lic = lic_node->child("text")->content();
1164 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1166 double duration_seconds = atof(dur);
1168 char duration_hhmmss[16];
1169 if (duration_seconds >= 99 * 60 * 60) {
1170 strcpy(duration_hhmmss, ">99h");
1172 s = modf(duration_seconds/60, &m) * 60;
1173 m = modf(m/60, &h) * 60;
1174 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1179 double size_bytes = atof(siz);
1181 if (size_bytes < 1000) {
1182 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1183 } else if (size_bytes < 1000000 ) {
1184 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1185 } else if (size_bytes < 10000000) {
1186 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1187 } else if (size_bytes < 1000000000) {
1188 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1190 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1193 /* see http://www.freesound.org/help/faq/#licenses */
1194 char shortlicense[64];
1195 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1196 sprintf(shortlicense, "CC-BY-NC");
1197 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1198 sprintf(shortlicense, "CC-BY");
1199 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1200 sprintf(shortlicense, "sampling+");
1201 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1202 sprintf(shortlicense, "PD");
1204 snprintf(shortlicense, 64, "%s", lic.c_str());
1205 shortlicense[63]= '\0';
1208 TreeModel::iterator new_row = freesound_list->append();
1209 TreeModel::Row row = *new_row;
1211 row[freesound_list_columns.id ] = id;
1212 row[freesound_list_columns.uri ] = uri;
1213 row[freesound_list_columns.filename] = ofn;
1214 row[freesound_list_columns.duration] = duration_hhmmss;
1215 row[freesound_list_columns.filesize] = bsize;
1216 row[freesound_list_columns.smplrate] = srt;
1217 row[freesound_list_columns.license ] = shortlicense;
1224 SoundFileBrowser::get_paths ()
1226 vector<string> results;
1228 int n = notebook.get_current_page ();
1231 vector<string> filenames = chooser.get_filenames();
1232 vector<string>::iterator i;
1234 for (i = filenames.begin(); i != filenames.end(); ++i) {
1236 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1237 results.push_back (*i);
1241 } else if (n == 1) {
1243 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1244 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1245 TreeIter iter = found_list->get_iter(*i);
1246 string str = (*iter)[found_list_columns.pathname];
1248 results.push_back (str);
1251 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1252 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1253 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1255 results.push_back (str);
1264 SoundFileOmega::reset_options_noret ()
1266 if (!resetting_ourselves) {
1267 (void) reset_options ();
1272 SoundFileOmega::reset_options ()
1274 vector<string> paths = get_paths ();
1276 if (paths.empty()) {
1278 channel_combo.set_sensitive (false);
1279 action_combo.set_sensitive (false);
1280 where_combo.set_sensitive (false);
1281 copy_files_btn.set_active (true);
1282 copy_files_btn.set_sensitive (false);
1288 channel_combo.set_sensitive (true);
1289 action_combo.set_sensitive (true);
1290 where_combo.set_sensitive (true);
1292 /* if we get through this function successfully, this may be
1293 reset at the end, once we know if we can use hard links
1294 to do embedding (or if we are importing a MIDI file).
1297 if (Config->get_only_copy_imported_files()) {
1298 copy_files_btn.set_sensitive (false);
1300 copy_files_btn.set_sensitive (false);
1306 bool selection_includes_multichannel;
1307 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1310 /* See if we are thinking about importing any MIDI files */
1311 vector<string>::iterator i = paths.begin ();
1312 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1315 bool const have_a_midi_file = (i != paths.end ());
1317 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1318 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1322 string existing_choice;
1323 vector<string> action_strings;
1325 resetting_ourselves = true;
1327 if (chooser.get_filter() == &audio_filter) {
1331 if (selected_audio_track_cnt > 0) {
1332 if (channel_combo.get_active_text().length()) {
1333 ImportDisposition id = get_channel_disposition();
1336 case Editing::ImportDistinctFiles:
1337 if (selected_audio_track_cnt == paths.size()) {
1338 action_strings.push_back (importmode2string (ImportToTrack));
1342 case Editing::ImportDistinctChannels:
1343 /* XXX it would be nice to allow channel-per-selected track
1344 but its too hard we don't want to deal with all the
1345 different per-file + per-track channel configurations.
1350 action_strings.push_back (importmode2string (ImportToTrack));
1360 if (selected_midi_track_cnt > 0) {
1361 action_strings.push_back (importmode2string (ImportToTrack));
1365 action_strings.push_back (importmode2string (ImportAsTrack));
1366 action_strings.push_back (importmode2string (ImportAsRegion));
1367 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1369 existing_choice = action_combo.get_active_text();
1371 set_popdown_strings (action_combo, action_strings);
1373 /* preserve any existing choice, if possible */
1376 if (existing_choice.length()) {
1377 vector<string>::iterator x;
1378 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1379 if (*x == existing_choice) {
1380 action_combo.set_active_text (existing_choice);
1384 if (x == action_strings.end()) {
1385 action_combo.set_active_text (action_strings.front());
1388 action_combo.set_active_text (action_strings.front());
1391 resetting_ourselves = false;
1393 if ((mode = get_mode()) == ImportAsRegion) {
1394 where_combo.set_sensitive (false);
1396 where_combo.set_sensitive (true);
1399 vector<string> channel_strings;
1401 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1402 channel_strings.push_back (_("one track per file"));
1404 if (selection_includes_multichannel) {
1405 channel_strings.push_back (_("one track per channel"));
1408 if (paths.size() > 1) {
1409 /* tape tracks are a single region per track, so we cannot
1410 sequence multiple files.
1412 if (mode != ImportAsTapeTrack) {
1413 channel_strings.push_back (_("sequence files"));
1416 channel_strings.push_back (_("all files in one track"));
1417 channel_strings.push_back (_("merge files"));
1423 channel_strings.push_back (_("one region per file"));
1425 if (selection_includes_multichannel) {
1426 channel_strings.push_back (_("one region per channel"));
1429 if (paths.size() > 1) {
1431 channel_strings.push_back (_("all files in one region"));
1436 resetting_ourselves = true;
1438 existing_choice = channel_combo.get_active_text();
1440 set_popdown_strings (channel_combo, channel_strings);
1442 /* preserve any existing choice, if possible */
1444 if (existing_choice.length()) {
1445 vector<string>::iterator x;
1446 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1447 if (*x == existing_choice) {
1448 channel_combo.set_active_text (existing_choice);
1452 if (x == channel_strings.end()) {
1453 channel_combo.set_active_text (channel_strings.front());
1456 channel_combo.set_active_text (channel_strings.front());
1459 resetting_ourselves = false;
1462 src_combo.set_sensitive (true);
1464 src_combo.set_sensitive (false);
1467 /* We must copy MIDI files or those from Freesound
1468 * or any file if we are under nsm control */
1469 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1471 if (Config->get_only_copy_imported_files()) {
1473 if (selection_can_be_embedded_with_links && !must_copy) {
1474 copy_files_btn.set_sensitive (true);
1477 copy_files_btn.set_active (true);
1479 copy_files_btn.set_sensitive (false);
1485 copy_files_btn.set_active (true);
1487 copy_files_btn.set_sensitive (!must_copy);
1495 SoundFileOmega::bad_file_message()
1497 MessageDialog msg (*this,
1498 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1503 resetting_ourselves = true;
1504 chooser.unselect_uri (chooser.get_preview_uri());
1505 resetting_ourselves = false;
1511 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1520 multichannel = false;
1522 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1524 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1525 if (info.channels > 1) {
1526 multichannel = true;
1531 if (sz != info.length) {
1536 if (info.samplerate != _session->frame_rate()) {
1540 } else if (SMFSource::safe_midi_file_extension (*i)) {
1544 if (reader.num_tracks() > 1) {
1545 multichannel = true; // "channel" == track here...
1548 /* XXX we need err = true handling here in case
1549 we can't check the file
1562 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1564 #ifdef PLATFORM_WINDOWS
1567 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1570 if (mkdir (tmpdir.c_str(), 0744)) {
1571 if (errno != EEXIST) {
1576 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1578 char tmpc[PATH_MAX+1];
1580 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1584 if (link ((*i).c_str(), tmpc)) {
1594 rmdir (tmpdir.c_str());
1599 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1600 : SoundFileBrowser (title, s, false)
1602 chooser.set_select_multiple (false);
1603 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1604 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1608 SoundFileChooser::on_hide ()
1610 ArdourWindow::on_hide();
1614 _session->cancel_audition();
1619 SoundFileChooser::get_filename ()
1621 vector<string> paths;
1623 paths = get_paths ();
1625 if (paths.empty()) {
1629 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1633 return paths.front();
1636 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1637 uint32_t selected_audio_tracks,
1638 uint32_t selected_midi_tracks,
1640 Editing::ImportMode mode_hint)
1641 : SoundFileBrowser (title, s, persistent)
1642 , copy_files_btn ( _("Copy files to session"))
1643 , selected_audio_track_cnt (selected_audio_tracks)
1644 , selected_midi_track_cnt (selected_midi_tracks)
1650 set_size_request (-1, 450);
1652 block_two.set_border_width (12);
1653 block_three.set_border_width (12);
1654 block_four.set_border_width (12);
1656 options.set_spacing (12);
1659 str.push_back (_("file timestamp"));
1660 str.push_back (_("edit point"));
1661 str.push_back (_("playhead"));
1662 str.push_back (_("session start"));
1663 set_popdown_strings (where_combo, str);
1664 where_combo.set_active_text (str.front());
1666 Label* l = manage (new Label);
1667 l->set_markup (_("<b>Add files as ...</b>"));
1669 vbox = manage (new VBox);
1670 vbox->set_border_width (12);
1671 vbox->set_spacing (6);
1672 vbox->pack_start (*l, false, false);
1673 vbox->pack_start (action_combo, false, false);
1674 hbox = manage (new HBox);
1675 hbox->pack_start (*vbox, false, false);
1676 options.pack_start (*hbox, false, false);
1678 /* dummy entry for action combo so that it doesn't look odd if we
1679 come up with no tracks selected.
1683 str.push_back (importmode2string (mode_hint));
1684 set_popdown_strings (action_combo, str);
1685 action_combo.set_active_text (str.front());
1686 action_combo.set_sensitive (false);
1688 l = manage (new Label);
1689 l->set_markup (_("<b>Insert at</b>"));
1691 vbox = manage (new VBox);
1692 vbox->set_border_width (12);
1693 vbox->set_spacing (6);
1694 vbox->pack_start (*l, false, false);
1695 vbox->pack_start (where_combo, false, false);
1696 hbox = manage (new HBox);
1697 hbox->pack_start (*vbox, false, false);
1698 options.pack_start (*hbox, false, false);
1701 l = manage (new Label);
1702 l->set_markup (_("<b>Mapping</b>"));
1704 vbox = manage (new VBox);
1705 vbox->set_border_width (12);
1706 vbox->set_spacing (6);
1707 vbox->pack_start (*l, false, false);
1708 vbox->pack_start (channel_combo, false, false);
1709 hbox = manage (new HBox);
1710 hbox->pack_start (*vbox, false, false);
1711 options.pack_start (*hbox, false, false);
1714 str.push_back (_("one track per file"));
1715 set_popdown_strings (channel_combo, str);
1716 channel_combo.set_active_text (str.front());
1717 channel_combo.set_sensitive (false);
1719 l = manage (new Label);
1720 l->set_markup (_("<b>Conversion quality</b>"));
1722 vbox = manage (new VBox);
1723 vbox->set_border_width (12);
1724 vbox->set_spacing (6);
1725 vbox->pack_start (*l, false, false);
1726 vbox->pack_start (src_combo, false, false);
1727 hbox = manage (new HBox);
1728 hbox->pack_start (*vbox, false, false);
1729 options.pack_start (*hbox, false, false);
1732 str.push_back (_("Best"));
1733 str.push_back (_("Good"));
1734 str.push_back (_("Quick"));
1735 str.push_back (_("Fast"));
1736 str.push_back (_("Fastest"));
1738 set_popdown_strings (src_combo, str);
1739 src_combo.set_active_text (str.front());
1740 src_combo.set_sensitive (false);
1741 src_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::src_combo_changed));
1745 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1746 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1748 copy_files_btn.set_active (true);
1750 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1753 copy_label->set_size_request (175, -1);
1754 copy_label->set_line_wrap (true);
1757 block_four.pack_start (copy_files_btn, false, false);
1759 options.pack_start (block_four, false, false);
1761 vpacker.pack_start (options, false, false);
1763 /* setup disposition map */
1765 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1766 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1767 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1768 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1770 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1771 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1772 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1773 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1775 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1777 /* set size requests for a couple of combos to allow them to display the longest text
1778 they will ever be asked to display. This prevents them being resized when the user
1779 selects a file to import, which in turn prevents the size of the dialog from jumping
1783 t.push_back (_("one track per file"));
1784 t.push_back (_("one track per channel"));
1785 t.push_back (_("sequence files"));
1786 t.push_back (_("all files in one region"));
1787 set_popdown_strings (channel_combo, t);
1790 t.push_back (importmode2string (ImportAsTrack));
1791 t.push_back (importmode2string (ImportToTrack));
1792 t.push_back (importmode2string (ImportAsRegion));
1793 t.push_back (importmode2string (ImportAsTapeTrack));
1794 set_popdown_strings (action_combo, t);
1798 SoundFileOmega::set_mode (ImportMode mode)
1800 action_combo.set_active_text (importmode2string (mode));
1804 SoundFileOmega::get_mode () const
1806 return string2importmode (action_combo.get_active_text());
1810 SoundFileOmega::on_hide ()
1812 ArdourWindow::on_hide();
1814 _session->cancel_audition();
1819 SoundFileOmega::get_position() const
1821 string str = where_combo.get_active_text();
1823 if (str == _("file timestamp")) {
1824 return ImportAtTimestamp;
1825 } else if (str == _("edit point")) {
1826 return ImportAtEditPoint;
1827 } else if (str == _("playhead")) {
1828 return ImportAtPlayhead;
1830 return ImportAtStart;
1835 SoundFileOmega::get_src_quality() const
1837 string str = src_combo.get_active_text();
1839 if (str == _("Best")) {
1841 } else if (str == _("Good")) {
1843 } else if (str == _("Quick")) {
1845 } else if (str == _("Fast")) {
1853 SoundFileOmega::src_combo_changed()
1855 preview.set_src_quality(get_src_quality());
1859 SoundFileOmega::get_channel_disposition () const
1861 /* we use a map here because the channel combo can contain different strings
1862 depending on the state of the other combos. the map contains all possible strings
1863 and the ImportDisposition enum that corresponds to it.
1866 string str = channel_combo.get_active_text();
1867 DispositionMap::const_iterator x = disposition_map.find (str);
1869 if (x == disposition_map.end()) {
1870 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1878 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1880 selected_audio_track_cnt = selected_audio_tracks;
1881 selected_midi_track_cnt = selected_midi_tracks;
1883 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1884 chooser.set_filter (midi_filter);
1885 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1886 chooser.set_filter (audio_filter);
1888 chooser.set_filter (audio_and_midi_filter);
1895 SoundFileOmega::file_selection_changed ()
1897 if (resetting_ourselves) {
1901 if (!reset_options ()) {
1902 set_action_sensitive (false);
1904 if (chooser.get_filenames().size() > 0) {
1905 set_action_sensitive (true);
1907 set_action_sensitive (false);
1913 SoundFileOmega::do_something (int action)
1915 SoundFileBrowser::do_something (action);
1917 if (action == RESPONSE_CANCEL) {
1924 vector<string> paths = get_paths ();
1925 ImportPosition pos = get_position ();
1926 ImportMode mode = get_mode ();
1927 ImportDisposition chns = get_channel_disposition ();
1931 case ImportAtEditPoint:
1932 where = PublicEditor::instance().get_preferred_edit_position ();
1934 case ImportAtTimestamp:
1937 case ImportAtPlayhead:
1938 where = _session->transport_frame();
1941 where = _session->current_start_frame();
1945 SrcQuality quality = get_src_quality();
1947 if (copy_files_btn.get_active()) {
1948 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1950 PublicEditor::instance().do_embed (paths, chns, mode, where);
1953 if (action == RESPONSE_OK) {