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>
36 #include <gtkmm2ext/utils.h>
38 #include <ardour/audio_library.h>
39 #include <ardour/auditioner.h>
40 #include <ardour/audioregion.h>
41 #include <ardour/audiofilesource.h>
42 #include <ardour/region_factory.h>
43 #include <ardour/source_factory.h>
44 #include <ardour/profile.h>
46 #include "ardour_ui.h"
48 #include "gui_thread.h"
53 #include "gain_meter.h"
57 using namespace ARDOUR;
61 using namespace Gtkmm2ext;
62 using namespace Editing;
66 ustring SoundFileBrowser::persistent_folder;
69 string2importmode (string str)
71 if (str == "as new tracks") {
73 } else if (str == "to selected tracks") {
75 } else if (str == "to region list") {
76 return ImportAsRegion;
77 } else if (str == "as new tape tracks") {
78 return ImportAsTapeTrack;
81 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
87 importmode2string (ImportMode mode)
91 return _("as new tracks");
93 return _("to selected tracks");
95 return _("to region list");
96 case ImportAsTapeTrack:
97 return _("as new tape tracks");
100 return _("as new tracks");
103 SoundFileBox::SoundFileBox (bool persistent)
106 length_clock ("sfboxLengthClock", !persistent, "EditCursorClock", false, true, false),
107 timecode_clock ("sfboxTimecodeClock", !persistent, "EditCursorClock", false, false, false),
109 autoplay_btn (_("Auto-play"))
115 set_name (X_("SoundFileBox"));
116 set_size_request (300, -1);
118 preview_label.set_markup (_("<b>Soundfile Info</b>"));
120 border_frame.set_label_widget (preview_label);
121 border_frame.add (main_box);
123 pack_start (border_frame, true, true);
124 set_border_width (6);
126 main_box.set_border_width (6);
127 main_box.set_spacing (12);
129 length.set_text (_("Length:"));
130 timecode.set_text (_("Timestamp:"));
131 format.set_text (_("Format:"));
132 channels.set_text (_("Channels:"));
133 samplerate.set_text (_("Sample rate:"));
135 table.set_col_spacings (6);
136 table.set_homogeneous (false);
137 table.set_row_spacings (6);
139 table.attach (channels, 0, 1, 0, 1, FILL|EXPAND, (AttachOptions) 0);
140 table.attach (samplerate, 0, 1, 1, 2, FILL|EXPAND, (AttachOptions) 0);
141 table.attach (format, 0, 1, 2, 4, FILL|EXPAND, (AttachOptions) 0);
142 table.attach (length, 0, 1, 4, 5, FILL|EXPAND, (AttachOptions) 0);
143 table.attach (timecode, 0, 1, 5, 6, FILL|EXPAND, (AttachOptions) 0);
145 table.attach (channels_value, 1, 2, 0, 1, FILL, (AttachOptions) 0);
146 table.attach (samplerate_value, 1, 2, 1, 2, FILL, (AttachOptions) 0);
147 table.attach (format_text, 1, 2, 2, 4, FILL, AttachOptions (0));
148 table.attach (length_clock, 1, 2, 4, 5, FILL, (AttachOptions) 0);
149 table.attach (timecode_clock, 1, 2, 5, 6, FILL, (AttachOptions) 0);
151 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock.mode());
152 timecode_clock.set_mode (AudioClock::SMPTE);
154 hbox = manage (new HBox);
155 hbox->pack_start (table, false, false);
156 main_box.pack_start (*hbox, false, false);
158 tags_entry.set_editable (true);
159 tags_entry.signal_focus_out_event().connect (mem_fun (*this, &SoundFileBox::tags_entry_left));
160 hbox = manage (new HBox);
161 hbox->pack_start (tags_entry, true, true);
163 vbox = manage (new VBox);
165 Label* label = manage (new Label (_("Tags:")));
166 label->set_alignment (0.0f, 0.5f);
167 vbox->set_spacing (6);
168 vbox->pack_start(*label, false, false);
169 vbox->pack_start(*hbox, true, true);
171 main_box.pack_start(*vbox, true, true);
172 main_box.pack_start(bottom_box, false, false);
174 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
175 play_btn.set_label (_("Play (double click)"));
177 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
178 stop_btn.set_label (_("Stop"));
180 bottom_box.set_homogeneous (false);
181 bottom_box.set_spacing (6);
182 bottom_box.pack_start(play_btn, true, true);
183 bottom_box.pack_start(stop_btn, true, true);
184 bottom_box.pack_start(autoplay_btn, false, false);
186 play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::audition));
187 stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_audition));
189 length.set_alignment (0.0f, 0.5f);
190 format.set_alignment (0.0f, 0.5f);
191 channels.set_alignment (0.0f, 0.5f);
192 samplerate.set_alignment (0.0f, 0.5f);
193 timecode.set_alignment (0.0f, 0.5f);
195 channels_value.set_alignment (0.0f, 0.5f);
196 samplerate_value.set_alignment (0.0f, 0.5f);
200 SoundFileBox::set_session(Session* s)
205 play_btn.set_sensitive (false);
206 stop_btn.set_sensitive (false);
210 length_clock.set_session (s);
211 timecode_clock.set_session (s);
215 SoundFileBox::setup_labels (const ustring& filename)
218 // save existing tags
226 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
228 preview_label.set_markup (_("<b>Soundfile Info</b>"));
229 format_text.set_text (_("n/a"));
230 channels_value.set_text (_("n/a"));
231 samplerate_value.set_text (_("n/a"));
232 tags_entry.get_buffer()->set_text ("");
234 length_clock.set (0);
235 timecode_clock.set (0);
237 tags_entry.set_sensitive (false);
238 play_btn.set_sensitive (false);
243 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::path_get_basename (filename)));
244 format_text.set_text (sf_info.format_name);
245 channels_value.set_text (to_string (sf_info.channels, std::dec));
247 if (_session && sf_info.samplerate != _session->frame_rate()) {
248 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
249 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
250 samplerate_value.set_name ("NewSessionSR1Label");
251 samplerate.set_name ("NewSessionSR1Label");
253 samplerate.set_text (_("Sample rate:"));
254 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
255 samplerate_value.set_name ("NewSessionSR2Label");
256 samplerate.set_name ("NewSessionSR2Label");
259 length_clock.set (sf_info.length, true);
260 timecode_clock.set (sf_info.timecode, true);
262 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
264 vector<string> tags = Library->get_tags (string ("//") + filename);
266 stringstream tag_string;
267 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
268 if (i != tags.begin()) {
273 tags_entry.get_buffer()->set_text (tag_string.str());
275 tags_entry.set_sensitive (true);
277 play_btn.set_sensitive (true);
284 SoundFileBox::autoplay() const
286 return autoplay_btn.get_active();
290 SoundFileBox::audition_oneshot()
297 SoundFileBox::audition ()
303 _session->cancel_audition();
305 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
306 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
310 boost::shared_ptr<Region> r;
312 boost::shared_ptr<AudioFileSource> afs;
313 bool old_sbp = AudioSource::get_build_peakfiles ();
315 /* don't even think of building peakfiles for these files */
317 AudioSource::set_build_peakfiles (false);
319 for (int n = 0; n < sf_info.channels; ++n) {
321 afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (*_session, path, n, AudioFileSource::Flag (0), false));
323 srclist.push_back(afs);
325 } catch (failed_constructor& err) {
326 error << _("Could not access soundfile: ") << path << endmsg;
327 AudioSource::set_build_peakfiles (old_sbp);
332 AudioSource::set_build_peakfiles (old_sbp);
334 if (srclist.empty()) {
338 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
339 string rname = region_name_from_path (afs->path(), false);
340 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false));
342 _session->audition_region(r);
346 SoundFileBox::stop_audition ()
349 _session->cancel_audition();
354 SoundFileBox::tags_entry_left (GdkEventFocus *ev)
361 SoundFileBox::tags_changed ()
363 string tag_string = tags_entry.get_buffer()->get_text ();
365 if (tag_string.empty()) {
371 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
372 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
380 SoundFileBox::save_tags (const vector<string>& tags)
382 Library->set_tags (string ("//") + path, tags);
383 Library->save_changes ();
386 SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::Session* s, bool persistent)
387 : ArdourDialog (parent, title, false, false),
388 found_list (ListStore::create(found_list_columns)),
389 chooser (FILE_CHOOSER_ACTION_OPEN),
390 found_list_view (found_list),
391 preview (persistent),
392 found_search_btn (_("Search"))
395 if (ARDOUR::Profile->get_sae()) {
396 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
397 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
406 resetting_ourselves = false;
408 hpacker.set_spacing (6);
409 hpacker.pack_start (notebook, true, true);
410 hpacker.pack_start (preview, false, false);
412 get_vbox()->pack_start (hpacker, true, true);
414 hbox = manage(new HBox);
415 hbox->pack_start (found_entry);
416 hbox->pack_start (found_search_btn);
418 vbox = manage(new VBox);
419 vbox->pack_start (*hbox, PACK_SHRINK);
420 vbox->pack_start (found_list_view);
421 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
423 chooser.set_border_width (12);
425 notebook.append_page (chooser, _("Browse Files"));
426 notebook.append_page (*vbox, _("Search Tags"));
428 notebook.set_size_request (500, -1);
430 found_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
431 found_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
433 custom_filter.add_custom (FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom));
434 custom_filter.set_name (_("Audio files"));
436 matchall_filter.add_pattern ("*.*");
437 matchall_filter.set_name (_("All files"));
439 chooser.add_filter (custom_filter);
440 chooser.add_filter (matchall_filter);
441 chooser.set_select_multiple (true);
442 chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
443 chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
445 if (!persistent_folder.empty()) {
446 chooser.set_current_folder (persistent_folder);
449 found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
451 found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
452 found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
454 add_button (Stock::CANCEL, RESPONSE_CANCEL);
455 add_button (Stock::APPLY, RESPONSE_APPLY);
456 add_button (Stock::OK, RESPONSE_OK);
460 SoundFileBrowser::~SoundFileBrowser ()
462 persistent_folder = chooser.get_current_folder();
467 SoundFileBrowser::on_show ()
469 ArdourDialog::on_show ();
474 SoundFileBrowser::clear_selection ()
476 chooser.unselect_all ();
477 found_list_view.get_selection()->unselect_all ();
481 SoundFileBrowser::chooser_file_activated ()
487 SoundFileBrowser::found_list_view_activated (const TreeModel::Path& path, TreeViewColumn* col)
493 SoundFileBrowser::set_session (Session* s)
495 ArdourDialog::set_session (s);
496 preview.set_session (s);
500 remove_gain_meter ();
505 SoundFileBrowser::add_gain_meter ()
511 gm = new GainMeter (session->the_auditioner(), *session);
513 meter_packer.set_border_width (12);
514 meter_packer.pack_start (*gm, false, true);
515 hpacker.pack_end (meter_packer, false, false);
516 meter_packer.show_all ();
521 SoundFileBrowser::remove_gain_meter ()
524 meter_packer.remove (*gm);
525 hpacker.remove (meter_packer);
532 SoundFileBrowser::start_metering ()
534 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun(*this, &SoundFileBrowser::meter));
538 SoundFileBrowser::stop_metering ()
540 metering_connection.disconnect();
544 SoundFileBrowser::meter ()
546 if (is_mapped () && session && gm) {
547 gm->update_meters ();
552 SoundFileBrowser::on_custom (const FileFilter::Info& filter_info)
554 return AudioFileSource::safe_file_extension (filter_info.filename);
558 SoundFileBrowser::update_preview ()
560 if (preview.setup_labels (chooser.get_filename())) {
561 if (preview.autoplay()) {
562 Glib::signal_idle().connect (mem_fun (preview, &SoundFileBox::audition_oneshot));
568 SoundFileBrowser::found_list_view_selected ()
570 if (!reset_options ()) {
571 set_response_sensitive (RESPONSE_OK, false);
575 TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
578 TreeIter iter = found_list->get_iter(*rows.begin());
579 file = (*iter)[found_list_columns.pathname];
580 chooser.set_filename (file);
581 set_response_sensitive (RESPONSE_OK, true);
583 set_response_sensitive (RESPONSE_OK, false);
586 preview.setup_labels (file);
591 SoundFileBrowser::found_search_clicked ()
593 string tag_string = found_entry.get_text ();
597 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
598 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
602 vector<string> results;
603 Library->search_members_and (results, tags);
606 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
607 TreeModel::iterator new_row = found_list->append();
608 TreeModel::Row row = *new_row;
609 string path = Glib::filename_from_uri (string ("file:") + *i);
610 row[found_list_columns.pathname] = path;
615 SoundFileBrowser::get_paths ()
617 vector<ustring> results;
619 int n = notebook.get_current_page ();
622 vector<ustring> filenames = chooser.get_filenames();
623 vector<ustring>::iterator i;
625 for (i = filenames.begin(); i != filenames.end(); ++i) {
627 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
628 results.push_back (*i);
634 typedef TreeView::Selection::ListHandle_Path ListPath;
636 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
637 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
638 TreeIter iter = found_list->get_iter(*i);
639 ustring str = (*iter)[found_list_columns.pathname];
641 results.push_back (str);
649 SoundFileOmega::reset_options_noret ()
651 if (!resetting_ourselves) {
652 (void) reset_options ();
657 SoundFileOmega::reset_options ()
659 vector<ustring> paths = get_paths ();
663 channel_combo.set_sensitive (false);
664 action_combo.set_sensitive (false);
665 where_combo.set_sensitive (false);
666 copy_files_btn.set_sensitive (false);
672 channel_combo.set_sensitive (true);
673 action_combo.set_sensitive (true);
674 where_combo.set_sensitive (true);
676 /* if we get through this function successfully, this may be
677 reset at the end, once we know if we can use hard links
681 if (Config->get_only_copy_imported_files()) {
682 copy_files_btn.set_sensitive (false);
684 copy_files_btn.set_sensitive (false);
690 bool selection_includes_multichannel;
691 bool selection_can_be_embedded_with_links = check_link_status (*session, paths);
694 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
695 Glib::signal_idle().connect (mem_fun (*this, &SoundFileOmega::bad_file_message));
699 ustring existing_choice;
700 vector<string> action_strings;
702 if (selected_track_cnt > 0) {
703 if (channel_combo.get_active_text().length()) {
704 ImportDisposition id = get_channel_disposition();
707 case Editing::ImportDistinctFiles:
708 if (selected_track_cnt == paths.size()) {
709 action_strings.push_back (importmode2string (ImportToTrack));
713 case Editing::ImportDistinctChannels:
714 /* XXX it would be nice to allow channel-per-selected track
715 but its too hard we don't want to deal with all the
716 different per-file + per-track channel configurations.
721 action_strings.push_back (importmode2string (ImportToTrack));
727 action_strings.push_back (importmode2string (ImportAsTrack));
728 action_strings.push_back (importmode2string (ImportAsRegion));
729 action_strings.push_back (importmode2string (ImportAsTapeTrack));
731 resetting_ourselves = true;
733 existing_choice = action_combo.get_active_text();
735 set_popdown_strings (action_combo, action_strings);
737 /* preserve any existing choice, if possible */
740 if (existing_choice.length()) {
741 vector<string>::iterator x;
742 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
743 if (*x == existing_choice) {
744 action_combo.set_active_text (existing_choice);
748 if (x == action_strings.end()) {
749 action_combo.set_active_text (action_strings.front());
752 action_combo.set_active_text (action_strings.front());
755 resetting_ourselves = false;
757 if ((mode = get_mode()) == ImportAsRegion) {
758 where_combo.set_sensitive (false);
760 where_combo.set_sensitive (true);
763 vector<string> channel_strings;
765 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
766 channel_strings.push_back (_("one track per file"));
768 if (selection_includes_multichannel) {
769 channel_strings.push_back (_("one track per channel"));
772 if (paths.size() > 1) {
773 /* tape tracks are a single region per track, so we cannot
774 sequence multiple files.
776 if (mode != ImportAsTapeTrack) {
777 channel_strings.push_back (_("sequence files"));
780 channel_strings.push_back (_("all files in one region"));
786 channel_strings.push_back (_("one region per file"));
788 if (selection_includes_multichannel) {
789 channel_strings.push_back (_("one region per channel"));
792 if (paths.size() > 1) {
794 channel_strings.push_back (_("all files in one region"));
799 existing_choice = channel_combo.get_active_text();
801 set_popdown_strings (channel_combo, channel_strings);
803 /* preserve any existing choice, if possible */
805 if (existing_choice.length()) {
806 vector<string>::iterator x;
807 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
808 if (*x == existing_choice) {
809 channel_combo.set_active_text (existing_choice);
813 if (x == channel_strings.end()) {
814 channel_combo.set_active_text (channel_strings.front());
817 channel_combo.set_active_text (channel_strings.front());
821 src_combo.set_sensitive (true);
823 src_combo.set_sensitive (false);
826 if (Config->get_only_copy_imported_files()) {
828 if (selection_can_be_embedded_with_links) {
829 copy_files_btn.set_sensitive (true);
831 copy_files_btn.set_sensitive (false);
836 copy_files_btn.set_sensitive (true);
844 SoundFileOmega::bad_file_message()
846 MessageDialog msg (*this,
847 _("One or more of the selected files\ncannot be used by Ardour"),
852 resetting_ourselves = true;
853 chooser.unselect_uri (chooser.get_preview_uri());
854 resetting_ourselves = false;
860 SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool& src_needed, bool& multichannel)
869 multichannel = false;
871 for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
873 info.format = 0; // libsndfile says to clear this before sf_open().
875 if ((sf = sf_open ((char*) (*i).c_str(), SFM_READ, &info)) != 0) {
878 if (info.channels > 1) {
885 if (sz != info.frames) {
890 if ((nframes_t) info.samplerate != session->frame_rate()) {
904 SoundFileOmega::check_link_status (const Session& s, const vector<ustring>& paths)
906 string tmpdir = s.sound_dir();
909 tmpdir += "/linktest";
911 if (mkdir (tmpdir.c_str(), 0744)) {
912 if (errno != EEXIST) {
917 for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
919 char tmpc[MAXPATHLEN+1];
921 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
925 if (link ((*i).c_str(), tmpc)) {
935 rmdir (tmpdir.c_str());
939 SoundFileChooser::SoundFileChooser (Gtk::Window& parent, string title, ARDOUR::Session* s)
940 : SoundFileBrowser (parent, title, s, false)
942 chooser.set_select_multiple (false);
943 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
947 SoundFileChooser::on_hide ()
949 ArdourDialog::on_hide();
953 session->cancel_audition();
958 SoundFileChooser::get_filename ()
960 vector<ustring> paths;
962 paths = get_paths ();
968 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
972 return paths.front();
975 SoundFileOmega::SoundFileOmega (Gtk::Window& parent, string title, ARDOUR::Session* s, int selected_tracks, bool persistent,
976 Editing::ImportMode mode_hint)
977 : SoundFileBrowser (parent, title, s, persistent),
978 copy_files_btn ( _("Copy files to session")),
979 selected_track_cnt (selected_tracks)
985 set_size_request (-1, 450);
987 block_two.set_border_width (12);
988 block_three.set_border_width (12);
989 block_four.set_border_width (12);
991 options.set_spacing (12);
994 str.push_back (_("use file timestamp"));
995 str.push_back (_("at edit point"));
996 str.push_back (_("at playhead"));
997 str.push_back (_("at session start"));
998 set_popdown_strings (where_combo, str);
999 where_combo.set_active_text (str.front());
1001 Label* l = manage (new Label);
1002 l->set_text (_("Add files:"));
1004 hbox = manage (new HBox);
1005 hbox->set_border_width (12);
1006 hbox->set_spacing (6);
1007 hbox->pack_start (*l, false, false);
1008 hbox->pack_start (action_combo, false, false);
1009 vbox = manage (new VBox);
1010 vbox->pack_start (*hbox, false, false);
1011 options.pack_start (*vbox, false, false);
1013 /* dummy entry for action combo so that it doesn't look odd if we
1014 come up with no tracks selected.
1018 str.push_back (importmode2string (mode_hint));
1019 set_popdown_strings (action_combo, str);
1020 action_combo.set_active_text (str.front());
1021 action_combo.set_sensitive (false);
1023 l = manage (new Label);
1024 l->set_text (_("Insert:"));
1026 hbox = manage (new HBox);
1027 hbox->set_border_width (12);
1028 hbox->set_spacing (6);
1029 hbox->pack_start (*l, false, false);
1030 hbox->pack_start (where_combo, false, false);
1031 vbox = manage (new VBox);
1032 vbox->pack_start (*hbox, false, false);
1033 options.pack_start (*vbox, false, false);
1036 l = manage (new Label);
1037 l->set_text (_("Mapping:"));
1039 hbox = manage (new HBox);
1040 hbox->set_border_width (12);
1041 hbox->set_spacing (6);
1042 hbox->pack_start (*l, false, false);
1043 hbox->pack_start (channel_combo, false, false);
1044 vbox = manage (new VBox);
1045 vbox->pack_start (*hbox, false, false);
1046 options.pack_start (*vbox, false, false);
1049 str.push_back (_("one track per file"));
1050 set_popdown_strings (channel_combo, str);
1051 channel_combo.set_active_text (str.front());
1052 channel_combo.set_sensitive (false);
1054 l = manage (new Label);
1055 l->set_text (_("Conversion Quality:"));
1057 hbox = manage (new HBox);
1058 hbox->set_border_width (12);
1059 hbox->set_spacing (6);
1060 hbox->pack_start (*l, false, false);
1061 hbox->pack_start (src_combo, false, false);
1062 vbox = manage (new VBox);
1063 vbox->pack_start (*hbox, false, false);
1064 options.pack_start (*vbox, false, false);
1067 str.push_back (_("Best"));
1068 str.push_back (_("Good"));
1069 str.push_back (_("Quick"));
1070 str.push_back (_("Fast"));
1071 str.push_back (_("Fastest"));
1073 set_popdown_strings (src_combo, str);
1074 src_combo.set_active_text (str.front());
1075 src_combo.set_sensitive (false);
1079 action_combo.signal_changed().connect (mem_fun (*this, &SoundFileOmega::reset_options_noret));
1081 copy_files_btn.set_active (true);
1083 block_four.pack_start (copy_files_btn, false, false);
1085 options.pack_start (block_four, false, false);
1087 get_vbox()->pack_start (options, false, false);
1089 /* setup disposition map */
1091 disposition_map.insert (pair<ustring,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1092 disposition_map.insert (pair<ustring,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1093 disposition_map.insert (pair<ustring,ImportDisposition>(_("merge files"), ImportMergeFiles));
1094 disposition_map.insert (pair<ustring,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1096 disposition_map.insert (pair<ustring,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1097 disposition_map.insert (pair<ustring,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1098 disposition_map.insert (pair<ustring,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1100 chooser.signal_selection_changed().connect (mem_fun (*this, &SoundFileOmega::file_selection_changed));
1104 SoundFileOmega::set_mode (ImportMode mode)
1106 action_combo.set_active_text (importmode2string (mode));
1110 SoundFileOmega::get_mode () const
1112 return string2importmode (action_combo.get_active_text());
1116 SoundFileOmega::on_hide ()
1118 ArdourDialog::on_hide();
1120 session->cancel_audition();
1125 SoundFileOmega::get_position() const
1127 ustring str = where_combo.get_active_text();
1129 if (str == _("use file timestamp")) {
1130 return ImportAtTimestamp;
1131 } else if (str == _("at edit point")) {
1132 return ImportAtEditPoint;
1133 } else if (str == _("at playhead")) {
1134 return ImportAtPlayhead;
1136 return ImportAtStart;
1141 SoundFileOmega::get_src_quality() const
1143 ustring str = where_combo.get_active_text();
1145 if (str == _("Best")) {
1147 } else if (str == _("Good")) {
1149 } else if (str == _("Quick")) {
1151 } else if (str == _("Fast")) {
1159 SoundFileOmega::get_channel_disposition () const
1161 /* we use a map here because the channel combo can contain different strings
1162 depending on the state of the other combos. the map contains all possible strings
1163 and the ImportDisposition enum that corresponds to it.
1166 ustring str = channel_combo.get_active_text();
1167 DispositionMap::const_iterator x = disposition_map.find (str);
1169 if (x == disposition_map.end()) {
1170 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1178 SoundFileOmega::reset (int selected_tracks)
1180 selected_track_cnt = selected_tracks;
1185 SoundFileOmega::file_selection_changed ()
1187 if (resetting_ourselves) {
1191 if (!reset_options ()) {
1192 set_response_sensitive (RESPONSE_OK, false);
1194 if (chooser.get_filenames().size() > 0) {
1195 set_response_sensitive (RESPONSE_OK, true);
1197 set_response_sensitive (RESPONSE_OK, false);