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.
26 #include <sys/param.h>
28 #include <gtkmm/box.h>
29 #include <gtkmm/stock.h>
30 #include <glibmm/fileutils.h>
32 #include <pbd/convert.h>
33 #include <pbd/tokenizer.h>
34 #include <pbd/enumwriter.h>
35 #include <pbd/pthread_utils.h>
36 #include <pbd/xml++.h>
38 #include <gtkmm2ext/utils.h>
40 #include <ardour/audio_library.h>
41 #include <ardour/auditioner.h>
42 #include <ardour/audioregion.h>
43 #include <ardour/audiofilesource.h>
44 #include <ardour/region_factory.h>
45 #include <ardour/source_factory.h>
46 #include <ardour/profile.h>
48 #include "ardour_ui.h"
50 #include "gui_thread.h"
55 #include "gain_meter.h"
58 #include "sfdb_freesound_mootcher.h"
63 using namespace ARDOUR;
67 using namespace Gtkmm2ext;
68 using namespace Editing;
72 ustring SoundFileBrowser::persistent_folder;
75 string2importmode (string str)
77 if (str == _("as new tracks")) {
79 } else if (str == _("to selected tracks")) {
81 } else if (str == _("to region list")) {
82 return ImportAsRegion;
83 } else if (str == _("as new tape tracks")) {
84 return ImportAsTapeTrack;
87 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
93 importmode2string (ImportMode mode)
97 return _("as new tracks");
99 return _("to selected tracks");
101 return _("to region list");
102 case ImportAsTapeTrack:
103 return _("as new tape tracks");
106 return _("as new tracks");
109 SoundFileBox::SoundFileBox (bool persistent)
112 length_clock ("sfboxLengthClock", !persistent, "EditCursorClock", false, true, false),
113 timecode_clock ("sfboxTimecodeClock", !persistent, "EditCursorClock", false, false, false),
115 autoplay_btn (_("Auto-play"))
121 set_name (X_("SoundFileBox"));
122 set_size_request (300, -1);
124 preview_label.set_markup (_("<b>Soundfile Info</b>"));
126 border_frame.set_label_widget (preview_label);
127 border_frame.add (main_box);
129 pack_start (border_frame, true, true);
130 set_border_width (6);
132 main_box.set_border_width (6);
133 main_box.set_spacing (12);
135 length.set_text (_("Length:"));
136 timecode.set_text (_("Timestamp:"));
137 format.set_text (_("Format:"));
138 channels.set_text (_("Channels:"));
139 samplerate.set_text (_("Sample rate:"));
141 table.set_col_spacings (6);
142 table.set_homogeneous (false);
143 table.set_row_spacings (6);
145 table.attach (channels, 0, 1, 0, 1, FILL|EXPAND, (AttachOptions) 0);
146 table.attach (samplerate, 0, 1, 1, 2, FILL|EXPAND, (AttachOptions) 0);
147 table.attach (format, 0, 1, 2, 4, FILL|EXPAND, (AttachOptions) 0);
148 table.attach (length, 0, 1, 4, 5, FILL|EXPAND, (AttachOptions) 0);
149 table.attach (timecode, 0, 1, 5, 6, FILL|EXPAND, (AttachOptions) 0);
151 table.attach (channels_value, 1, 2, 0, 1, FILL, (AttachOptions) 0);
152 table.attach (samplerate_value, 1, 2, 1, 2, FILL, (AttachOptions) 0);
153 table.attach (format_text, 1, 2, 2, 4, FILL, AttachOptions (0));
154 table.attach (length_clock, 1, 2, 4, 5, FILL, (AttachOptions) 0);
155 table.attach (timecode_clock, 1, 2, 5, 6, FILL, (AttachOptions) 0);
157 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock.mode());
158 timecode_clock.set_mode (AudioClock::SMPTE);
160 hbox = manage (new HBox);
161 hbox->pack_start (table, false, false);
162 main_box.pack_start (*hbox, false, false);
164 tags_entry.set_editable (true);
165 tags_entry.signal_focus_out_event().connect (mem_fun (*this, &SoundFileBox::tags_entry_left));
166 hbox = manage (new HBox);
167 hbox->pack_start (tags_entry, true, true);
169 vbox = manage (new VBox);
171 Label* label = manage (new Label (_("Tags:")));
172 label->set_alignment (0.0f, 0.5f);
173 vbox->set_spacing (6);
174 vbox->pack_start(*label, false, false);
175 vbox->pack_start(*hbox, true, true);
177 main_box.pack_start(*vbox, true, true);
178 main_box.pack_start(bottom_box, false, false);
180 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
181 play_btn.set_label (_("Play (double click)"));
183 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
184 stop_btn.set_label (_("Stop"));
186 bottom_box.set_homogeneous (false);
187 bottom_box.set_spacing (6);
188 bottom_box.pack_start(play_btn, true, true);
189 bottom_box.pack_start(stop_btn, true, true);
190 bottom_box.pack_start(autoplay_btn, false, false);
192 play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::audition));
193 stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_audition));
195 length.set_alignment (0.0f, 0.5f);
196 format.set_alignment (0.0f, 0.5f);
197 channels.set_alignment (0.0f, 0.5f);
198 samplerate.set_alignment (0.0f, 0.5f);
199 timecode.set_alignment (0.0f, 0.5f);
201 channels_value.set_alignment (0.0f, 0.5f);
202 samplerate_value.set_alignment (0.0f, 0.5f);
206 SoundFileBox::set_session(Session* s)
211 play_btn.set_sensitive (false);
212 stop_btn.set_sensitive (false);
216 length_clock.set_session (s);
217 timecode_clock.set_session (s);
221 SoundFileBox::setup_labels (const ustring& filename)
224 // save existing tags
232 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
234 preview_label.set_markup (_("<b>Soundfile Info</b>"));
235 format_text.set_text (_("n/a"));
236 channels_value.set_text (_("n/a"));
237 samplerate_value.set_text (_("n/a"));
238 tags_entry.get_buffer()->set_text ("");
240 length_clock.set (0);
241 timecode_clock.set (0);
243 tags_entry.set_sensitive (false);
244 play_btn.set_sensitive (false);
249 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::path_get_basename (filename)));
250 format_text.set_text (sf_info.format_name);
251 channels_value.set_text (to_string (sf_info.channels, std::dec));
253 if (_session && sf_info.samplerate != _session->frame_rate()) {
254 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
255 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
256 samplerate_value.set_name ("NewSessionSR1Label");
257 samplerate.set_name ("NewSessionSR1Label");
259 samplerate.set_text (_("Sample rate:"));
260 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
261 samplerate_value.set_name ("NewSessionSR2Label");
262 samplerate.set_name ("NewSessionSR2Label");
265 double src_coef = (double) _session->nominal_frame_rate() / sf_info.samplerate;
267 length_clock.set (sf_info.length * src_coef + 0.5, true);
268 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
270 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
272 vector<string> tags = Library->get_tags (string ("//") + filename);
274 stringstream tag_string;
275 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
276 if (i != tags.begin()) {
281 tags_entry.get_buffer()->set_text (tag_string.str());
283 tags_entry.set_sensitive (true);
285 play_btn.set_sensitive (true);
292 SoundFileBox::autoplay() const
294 return autoplay_btn.get_active();
298 SoundFileBox::audition_oneshot()
305 SoundFileBox::audition ()
311 _session->cancel_audition();
313 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
314 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
318 boost::shared_ptr<Region> r;
320 boost::shared_ptr<AudioFileSource> afs;
321 bool old_sbp = AudioSource::get_build_peakfiles ();
323 /* don't even think of building peakfiles for these files */
325 AudioSource::set_build_peakfiles (false);
327 for (int n = 0; n < sf_info.channels; ++n) {
329 afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (*_session, path, n, AudioFileSource::Flag (0), false));
331 srclist.push_back(afs);
333 } catch (failed_constructor& err) {
334 error << _("Could not access soundfile: ") << path << endmsg;
335 AudioSource::set_build_peakfiles (old_sbp);
340 AudioSource::set_build_peakfiles (old_sbp);
342 if (srclist.empty()) {
346 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
347 string rname = region_name_from_path (afs->path(), false);
348 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false));
350 _session->audition_region(r);
354 SoundFileBox::stop_audition ()
357 _session->cancel_audition();
362 SoundFileBox::tags_entry_left (GdkEventFocus *ev)
369 SoundFileBox::tags_changed ()
371 string tag_string = tags_entry.get_buffer()->get_text ();
373 if (tag_string.empty()) {
379 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
380 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
388 SoundFileBox::save_tags (const vector<string>& tags)
390 Library->set_tags (string ("//") + path, tags);
391 Library->save_changes ();
394 SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::Session* s, bool persistent)
395 : ArdourDialog (parent, title, false, false),
396 found_list (ListStore::create(found_list_columns)),
397 freesound_list (ListStore::create(freesound_list_columns)),
398 chooser (FILE_CHOOSER_ACTION_OPEN),
399 preview (persistent),
400 found_search_btn (_("Search")),
401 found_list_view (found_list),
402 freesound_search_btn (_("Start Downloading")),
403 freesound_list_view (freesound_list)
405 resetting_ourselves = false;
408 if (ARDOUR::Profile->get_sae()) {
409 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
410 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
413 //add the file chooser
415 chooser.set_border_width (12);
416 custom_filter.add_custom (FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom));
417 custom_filter.set_name (_("Audio files"));
419 matchall_filter.add_pattern ("*.*");
420 matchall_filter.set_name (_("All files"));
422 chooser.add_filter (custom_filter);
423 chooser.add_filter (matchall_filter);
424 chooser.set_select_multiple (true);
425 chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
426 chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
428 if (!persistent_folder.empty()) {
429 chooser.set_current_folder (persistent_folder);
431 notebook.append_page (chooser, _("Browse Files"));
434 hpacker.set_spacing (6);
435 hpacker.pack_start (notebook, true, true);
436 hpacker.pack_start (preview, false, false);
438 get_vbox()->pack_start (hpacker, true, true);
446 hbox = manage(new HBox);
447 hbox->pack_start (found_entry);
448 hbox->pack_start (found_search_btn);
450 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
451 scroll->add(found_list_view);
452 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
454 vbox = manage(new VBox);
455 vbox->pack_start (*hbox, PACK_SHRINK);
456 vbox->pack_start (*scroll);
458 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
460 found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
462 found_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
464 found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
465 found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
467 notebook.append_page (*vbox, _("Search Tags"));
470 //add freesound search
477 passbox = manage(new HBox);
478 passbox->set_border_width (12);
479 passbox->set_spacing (6);
481 label = manage (new Label);
482 label->set_text (_("User:"));
483 passbox->pack_start (*label, false, false);
484 passbox->pack_start (freesound_name_entry);
485 label = manage (new Label);
486 label->set_text (_("Password:"));
487 passbox->pack_start (*label, false, false);
488 passbox->pack_start (freesound_pass_entry);
489 label = manage (new Label);
490 label->set_text (_("Tags:"));
491 passbox->pack_start (*label, false, false);
492 passbox->pack_start (freesound_entry, false, false);
493 passbox->pack_start (freesound_search_btn, false, false);
495 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
496 scroll->add(freesound_list_view);
497 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
499 vbox = manage(new VBox);
500 vbox->pack_start (*passbox, PACK_SHRINK);
501 vbox->pack_start(*scroll);
503 //vbox->pack_start (freesound_list_view);
505 freesound_list_view.append_column(_("Paths"), freesound_list_columns.pathname);
507 freesound_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
509 //freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
510 freesound_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
512 freesound_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
513 freesound_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
515 notebook.append_page (*vbox, _("Search Freesound"));
520 notebook.set_size_request (500, -1);
524 add_button (Stock::CANCEL, RESPONSE_CANCEL);
525 add_button (Stock::APPLY, RESPONSE_APPLY);
526 add_button (Stock::OK, RESPONSE_OK);
530 SoundFileBrowser::~SoundFileBrowser ()
532 persistent_folder = chooser.get_current_folder();
537 SoundFileBrowser::on_show ()
539 ArdourDialog::on_show ();
544 SoundFileBrowser::clear_selection ()
546 chooser.unselect_all ();
547 found_list_view.get_selection()->unselect_all ();
551 SoundFileBrowser::chooser_file_activated ()
557 SoundFileBrowser::found_list_view_activated (const TreeModel::Path& path, TreeViewColumn* col)
563 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path& path, TreeViewColumn* col)
569 SoundFileBrowser::set_session (Session* s)
571 ArdourDialog::set_session (s);
572 preview.set_session (s);
576 remove_gain_meter ();
581 SoundFileBrowser::add_gain_meter ()
587 gm = new GainMeter (*session);
588 gm->set_io (session->the_auditioner());
590 meter_packer.set_border_width (12);
591 meter_packer.pack_start (*gm, false, true);
592 hpacker.pack_end (meter_packer, false, false);
593 meter_packer.show_all ();
598 SoundFileBrowser::remove_gain_meter ()
601 meter_packer.remove (*gm);
602 hpacker.remove (meter_packer);
609 SoundFileBrowser::start_metering ()
611 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun(*this, &SoundFileBrowser::meter));
615 SoundFileBrowser::stop_metering ()
617 metering_connection.disconnect();
621 SoundFileBrowser::meter ()
623 if (is_mapped () && session && gm) {
624 gm->update_meters ();
629 SoundFileBrowser::on_custom (const FileFilter::Info& filter_info)
631 return AudioFileSource::safe_file_extension (filter_info.filename);
635 SoundFileBrowser::update_preview ()
637 if (preview.setup_labels (chooser.get_filename())) {
638 if (preview.autoplay()) {
639 Glib::signal_idle().connect (mem_fun (preview, &SoundFileBox::audition_oneshot));
645 SoundFileBrowser::found_list_view_selected ()
647 if (!reset_options ()) {
648 set_response_sensitive (RESPONSE_OK, false);
652 TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
655 TreeIter iter = found_list->get_iter(*rows.begin());
656 file = (*iter)[found_list_columns.pathname];
657 chooser.set_filename (file);
658 set_response_sensitive (RESPONSE_OK, true);
660 set_response_sensitive (RESPONSE_OK, false);
663 preview.setup_labels (file);
668 SoundFileBrowser::freesound_list_view_selected ()
670 if (!reset_options ()) {
671 set_response_sensitive (RESPONSE_OK, false);
675 TreeView::Selection::ListHandle_Path rows = freesound_list_view.get_selection()->get_selected_rows ();
678 TreeIter iter = freesound_list->get_iter(*rows.begin());
679 file = (*iter)[freesound_list_columns.pathname];
680 chooser.set_filename (file);
681 set_response_sensitive (RESPONSE_OK, true);
683 set_response_sensitive (RESPONSE_OK, false);
686 preview.setup_labels (file);
691 SoundFileBrowser::found_search_clicked ()
693 string tag_string = found_entry.get_text ();
697 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
698 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
702 vector<string> results;
703 Library->search_members_and (results, tags);
706 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
707 TreeModel::iterator new_row = found_list->append();
708 TreeModel::Row row = *new_row;
709 string path = Glib::filename_from_uri (string ("file:") + *i);
710 row[found_list_columns.pathname] = path;
715 freesound_search_thread_entry (void* arg)
717 PBD::notify_gui_about_thread_creation (pthread_self(), X_("Freesound Search"));
719 static_cast<SoundFileBrowser*>(arg)->freesound_search_thread ();
724 bool searching = false;
725 bool canceling = false;
728 SoundFileBrowser::freesound_search_clicked ()
730 if (canceling) //already canceling, button does nothing
734 freesound_search_btn.set_label(_("Cancelling.."));
738 freesound_search_btn.set_label(_("Cancel"));
739 pthread_t freesound_thr;
740 pthread_create_and_store ("freesound_search", &freesound_thr, 0, freesound_search_thread_entry, this);
745 SoundFileBrowser::freesound_search_thread()
748 freesound_list->clear();
751 path = Glib::get_home_dir();
752 path += "/Freesound/";
753 Mootcher theMootcher(path.c_str());
755 string name_string = freesound_name_entry.get_text ();
756 string pass_string = freesound_pass_entry.get_text ();
757 string search_string = freesound_entry.get_text ();
759 if ( theMootcher.doLogin( name_string, pass_string ) ) {
761 string theString = theMootcher.searchText(search_string);
764 doc.read_buffer( theString );
765 XMLNode *root = doc.root();
767 if (root==NULL) return;
769 if ( strcmp(root->name().c_str(), "freesound") == 0) {
772 XMLNodeList children = root->children();
773 XMLNodeConstIterator niter;
774 for (niter = children.begin(); niter != children.end() && !canceling; ++niter) {
776 if( strcmp( node->name().c_str(), "sample") == 0 ){
777 XMLProperty *prop=node->property ("id");
778 string filename = theMootcher.getFile( prop->value().c_str() );
779 if ( filename != "" ) {
780 TreeModel::iterator new_row = freesound_list->append();
781 TreeModel::Row row = *new_row;
782 string path = Glib::filename_from_uri (string ("file:") + filename);
783 row[freesound_list_columns.pathname] = path;
792 freesound_search_btn.set_label(_("Start Downloading"));
797 SoundFileBrowser::get_paths ()
799 vector<ustring> results;
801 int n = notebook.get_current_page ();
804 vector<ustring> filenames = chooser.get_filenames();
805 vector<ustring>::iterator i;
807 for (i = filenames.begin(); i != filenames.end(); ++i) {
809 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
810 results.push_back (*i);
816 typedef TreeView::Selection::ListHandle_Path ListPath;
818 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
819 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
820 TreeIter iter = found_list->get_iter(*i);
821 ustring str = (*iter)[found_list_columns.pathname];
823 results.push_back (str);
827 typedef TreeView::Selection::ListHandle_Path ListPath;
829 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
830 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
831 TreeIter iter = freesound_list->get_iter(*i);
832 ustring str = (*iter)[freesound_list_columns.pathname];
834 results.push_back (str);
842 SoundFileOmega::reset_options_noret ()
844 if (!resetting_ourselves) {
845 (void) reset_options ();
850 SoundFileOmega::reset_options ()
852 vector<ustring> paths = get_paths ();
856 channel_combo.set_sensitive (false);
857 action_combo.set_sensitive (false);
858 where_combo.set_sensitive (false);
859 copy_files_btn.set_sensitive (false);
865 channel_combo.set_sensitive (true);
866 action_combo.set_sensitive (true);
867 where_combo.set_sensitive (true);
869 /* if we get through this function successfully, this may be
870 reset at the end, once we know if we can use hard links
874 if (Config->get_only_copy_imported_files()) {
875 copy_files_btn.set_sensitive (false);
877 copy_files_btn.set_sensitive (false);
883 bool selection_includes_multichannel;
884 bool selection_can_be_embedded_with_links = check_link_status (*session, paths);
887 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
888 Glib::signal_idle().connect (mem_fun (*this, &SoundFileOmega::bad_file_message));
892 ustring existing_choice;
893 vector<string> action_strings;
895 if (selected_track_cnt > 0) {
896 if (channel_combo.get_active_text().length()) {
897 ImportDisposition id = get_channel_disposition();
900 case Editing::ImportDistinctFiles:
901 if (selected_track_cnt == paths.size()) {
902 action_strings.push_back (importmode2string (ImportToTrack));
906 case Editing::ImportDistinctChannels:
907 /* XXX it would be nice to allow channel-per-selected track
908 but its too hard we don't want to deal with all the
909 different per-file + per-track channel configurations.
914 action_strings.push_back (importmode2string (ImportToTrack));
920 action_strings.push_back (importmode2string (ImportAsTrack));
921 action_strings.push_back (importmode2string (ImportAsRegion));
922 action_strings.push_back (importmode2string (ImportAsTapeTrack));
924 resetting_ourselves = true;
926 existing_choice = action_combo.get_active_text();
928 set_popdown_strings (action_combo, action_strings);
930 /* preserve any existing choice, if possible */
933 if (existing_choice.length()) {
934 vector<string>::iterator x;
935 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
936 if (*x == existing_choice) {
937 action_combo.set_active_text (existing_choice);
941 if (x == action_strings.end()) {
942 action_combo.set_active_text (action_strings.front());
945 action_combo.set_active_text (action_strings.front());
948 resetting_ourselves = false;
950 if ((mode = get_mode()) == ImportAsRegion) {
951 where_combo.set_sensitive (false);
953 where_combo.set_sensitive (true);
956 vector<string> channel_strings;
958 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
959 channel_strings.push_back (_("one track per file"));
961 if (selection_includes_multichannel) {
962 channel_strings.push_back (_("one track per channel"));
965 if (paths.size() > 1) {
966 /* tape tracks are a single region per track, so we cannot
967 sequence multiple files.
969 if (mode != ImportAsTapeTrack) {
970 channel_strings.push_back (_("sequence files"));
973 channel_strings.push_back (_("all files in one region"));
979 channel_strings.push_back (_("one region per file"));
981 if (selection_includes_multichannel) {
982 channel_strings.push_back (_("one region per channel"));
985 if (paths.size() > 1) {
987 channel_strings.push_back (_("all files in one region"));
992 existing_choice = channel_combo.get_active_text();
994 set_popdown_strings (channel_combo, channel_strings);
996 /* preserve any existing choice, if possible */
998 if (existing_choice.length()) {
999 vector<string>::iterator x;
1000 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1001 if (*x == existing_choice) {
1002 channel_combo.set_active_text (existing_choice);
1006 if (x == channel_strings.end()) {
1007 channel_combo.set_active_text (channel_strings.front());
1010 channel_combo.set_active_text (channel_strings.front());
1014 src_combo.set_sensitive (true);
1016 src_combo.set_sensitive (false);
1019 if (Config->get_only_copy_imported_files()) {
1021 if (selection_can_be_embedded_with_links) {
1022 copy_files_btn.set_sensitive (true);
1024 copy_files_btn.set_sensitive (false);
1029 copy_files_btn.set_sensitive (true);
1037 SoundFileOmega::bad_file_message()
1039 MessageDialog msg (*this,
1040 _("One or more of the selected files\ncannot be used by Ardour"),
1045 resetting_ourselves = true;
1046 chooser.unselect_uri (chooser.get_preview_uri());
1047 resetting_ourselves = false;
1053 SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1062 multichannel = false;
1064 for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1066 if (!AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1070 if (info.channels > 1) {
1071 multichannel = true;
1077 if (sz != info.length) {
1082 if ((nframes_t) info.samplerate != session->frame_rate()) {
1092 SoundFileOmega::check_link_status (const Session& s, const vector<ustring>& paths)
1094 string tmpdir = s.sound_dir();
1097 tmpdir += "/linktest";
1099 if (mkdir (tmpdir.c_str(), 0744)) {
1100 if (errno != EEXIST) {
1105 for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1107 char tmpc[MAXPATHLEN+1];
1109 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1113 if (link ((*i).c_str(), tmpc)) {
1123 rmdir (tmpdir.c_str());
1127 SoundFileChooser::SoundFileChooser (Gtk::Window& parent, string title, ARDOUR::Session* s)
1128 : SoundFileBrowser (parent, title, s, false)
1130 chooser.set_select_multiple (false);
1131 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1132 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1136 SoundFileChooser::on_hide ()
1138 ArdourDialog::on_hide();
1142 session->cancel_audition();
1147 SoundFileChooser::get_filename ()
1149 vector<ustring> paths;
1151 paths = get_paths ();
1153 if (paths.empty()) {
1157 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1161 return paths.front();
1164 SoundFileOmega::SoundFileOmega (Gtk::Window& parent, string title, ARDOUR::Session* s, int selected_tracks, bool persistent,
1165 Editing::ImportMode mode_hint)
1166 : SoundFileBrowser (parent, title, s, persistent),
1167 copy_files_btn ( _("Copy files to session")),
1168 selected_track_cnt (selected_tracks)
1174 set_size_request (-1, 450);
1176 block_two.set_border_width (12);
1177 block_three.set_border_width (12);
1178 block_four.set_border_width (12);
1180 options.set_spacing (12);
1183 str.push_back (_("use file timestamp"));
1184 str.push_back (_("at edit point"));
1185 str.push_back (_("at playhead"));
1186 str.push_back (_("at session start"));
1187 set_popdown_strings (where_combo, str);
1188 where_combo.set_active_text (str.front());
1190 Label* l = manage (new Label);
1191 l->set_text (_("Add files:"));
1193 hbox = manage (new HBox);
1194 hbox->set_border_width (12);
1195 hbox->set_spacing (6);
1196 hbox->pack_start (*l, false, false);
1197 hbox->pack_start (action_combo, false, false);
1198 vbox = manage (new VBox);
1199 vbox->pack_start (*hbox, false, false);
1200 options.pack_start (*vbox, false, false);
1202 /* dummy entry for action combo so that it doesn't look odd if we
1203 come up with no tracks selected.
1207 str.push_back (importmode2string (mode_hint));
1208 set_popdown_strings (action_combo, str);
1209 action_combo.set_active_text (str.front());
1210 action_combo.set_sensitive (false);
1212 l = manage (new Label);
1213 l->set_text (_("Insert:"));
1215 hbox = manage (new HBox);
1216 hbox->set_border_width (12);
1217 hbox->set_spacing (6);
1218 hbox->pack_start (*l, false, false);
1219 hbox->pack_start (where_combo, false, false);
1220 vbox = manage (new VBox);
1221 vbox->pack_start (*hbox, false, false);
1222 options.pack_start (*vbox, false, false);
1225 l = manage (new Label);
1226 l->set_text (_("Mapping:"));
1228 hbox = manage (new HBox);
1229 hbox->set_border_width (12);
1230 hbox->set_spacing (6);
1231 hbox->pack_start (*l, false, false);
1232 hbox->pack_start (channel_combo, false, false);
1233 vbox = manage (new VBox);
1234 vbox->pack_start (*hbox, false, false);
1235 options.pack_start (*vbox, false, false);
1238 str.push_back (_("one track per file"));
1239 set_popdown_strings (channel_combo, str);
1240 channel_combo.set_active_text (str.front());
1241 channel_combo.set_sensitive (false);
1243 l = manage (new Label);
1244 l->set_text (_("Conversion Quality:"));
1246 hbox = manage (new HBox);
1247 hbox->set_border_width (12);
1248 hbox->set_spacing (6);
1249 hbox->pack_start (*l, false, false);
1250 hbox->pack_start (src_combo, false, false);
1251 vbox = manage (new VBox);
1252 vbox->pack_start (*hbox, false, false);
1253 options.pack_start (*vbox, false, false);
1256 str.push_back (_("Best"));
1257 str.push_back (_("Good"));
1258 str.push_back (_("Quick"));
1259 str.push_back (_("Fast"));
1260 str.push_back (_("Fastest"));
1262 set_popdown_strings (src_combo, str);
1263 src_combo.set_active_text (str.front());
1264 src_combo.set_sensitive (false);
1268 action_combo.signal_changed().connect (mem_fun (*this, &SoundFileOmega::reset_options_noret));
1270 copy_files_btn.set_active (true);
1272 block_four.pack_start (copy_files_btn, false, false);
1274 options.pack_start (block_four, false, false);
1276 get_vbox()->pack_start (options, false, false);
1278 /* setup disposition map */
1280 disposition_map.insert (pair<ustring,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1281 disposition_map.insert (pair<ustring,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1282 disposition_map.insert (pair<ustring,ImportDisposition>(_("merge files"), ImportMergeFiles));
1283 disposition_map.insert (pair<ustring,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1285 disposition_map.insert (pair<ustring,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1286 disposition_map.insert (pair<ustring,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1287 disposition_map.insert (pair<ustring,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1289 chooser.signal_selection_changed().connect (mem_fun (*this, &SoundFileOmega::file_selection_changed));
1293 SoundFileOmega::set_mode (ImportMode mode)
1295 action_combo.set_active_text (importmode2string (mode));
1299 SoundFileOmega::get_mode () const
1301 return string2importmode (action_combo.get_active_text());
1305 SoundFileOmega::on_hide ()
1307 ArdourDialog::on_hide();
1309 session->cancel_audition();
1314 SoundFileOmega::get_position() const
1316 ustring str = where_combo.get_active_text();
1318 if (str == _("use file timestamp")) {
1319 return ImportAtTimestamp;
1320 } else if (str == _("at edit point")) {
1321 return ImportAtEditPoint;
1322 } else if (str == _("at playhead")) {
1323 return ImportAtPlayhead;
1325 return ImportAtStart;
1330 SoundFileOmega::get_src_quality() const
1332 ustring str = where_combo.get_active_text();
1334 if (str == _("Best")) {
1336 } else if (str == _("Good")) {
1338 } else if (str == _("Quick")) {
1340 } else if (str == _("Fast")) {
1348 SoundFileOmega::get_channel_disposition () const
1350 /* we use a map here because the channel combo can contain different strings
1351 depending on the state of the other combos. the map contains all possible strings
1352 and the ImportDisposition enum that corresponds to it.
1355 ustring str = channel_combo.get_active_text();
1356 DispositionMap::const_iterator x = disposition_map.find (str);
1358 if (x == disposition_map.end()) {
1359 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1367 SoundFileOmega::reset (int selected_tracks)
1369 selected_track_cnt = selected_tracks;
1374 SoundFileOmega::file_selection_changed ()
1376 if (resetting_ourselves) {
1380 if (!reset_options ()) {
1381 set_response_sensitive (RESPONSE_OK, false);
1383 if (chooser.get_filenames().size() > 0) {
1384 set_response_sensitive (RESPONSE_OK, true);
1386 set_response_sensitive (RESPONSE_OK, false);