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/session.h>
45 #include <ardour/session_directory.h>
46 #include <ardour/profile.h>
48 #include "ardour_ui.h"
50 #include "gui_thread.h"
55 #include "gain_meter.h"
59 using namespace ARDOUR;
63 using namespace Gtkmm2ext;
64 using namespace Editing;
68 ustring SoundFileBrowser::persistent_folder;
71 string2importmode (string str)
73 if (str == "as new tracks") {
75 } else if (str == "to selected tracks") {
77 } else if (str == "to region list") {
78 return ImportAsRegion;
79 } else if (str == "as new tape tracks") {
80 return ImportAsTapeTrack;
83 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
89 importmode2string (ImportMode mode)
93 return _("as new tracks");
95 return _("to selected tracks");
97 return _("to region list");
98 case ImportAsTapeTrack:
99 return _("as new tape tracks");
102 return _("as new tracks");
105 SoundFileBox::SoundFileBox (bool persistent)
108 length_clock ("sfboxLengthClock", !persistent, "EditCursorClock", false, true, false),
109 timecode_clock ("sfboxTimecodeClock", !persistent, "EditCursorClock", false, false, false),
111 autoplay_btn (_("Auto-play"))
117 set_name (X_("SoundFileBox"));
118 set_size_request (300, -1);
120 preview_label.set_markup (_("<b>Soundfile Info</b>"));
122 border_frame.set_label_widget (preview_label);
123 border_frame.add (main_box);
125 pack_start (border_frame, true, true);
126 set_border_width (6);
128 main_box.set_border_width (6);
129 main_box.set_spacing (12);
131 length.set_text (_("Length:"));
132 timecode.set_text (_("Timestamp:"));
133 format.set_text (_("Format:"));
134 channels.set_text (_("Channels:"));
135 samplerate.set_text (_("Sample rate:"));
137 table.set_col_spacings (6);
138 table.set_homogeneous (false);
139 table.set_row_spacings (6);
141 table.attach (channels, 0, 1, 0, 1, FILL|EXPAND, (AttachOptions) 0);
142 table.attach (samplerate, 0, 1, 1, 2, FILL|EXPAND, (AttachOptions) 0);
143 table.attach (format, 0, 1, 2, 4, FILL|EXPAND, (AttachOptions) 0);
144 table.attach (length, 0, 1, 4, 5, FILL|EXPAND, (AttachOptions) 0);
145 table.attach (timecode, 0, 1, 5, 6, FILL|EXPAND, (AttachOptions) 0);
147 table.attach (channels_value, 1, 2, 0, 1, FILL, (AttachOptions) 0);
148 table.attach (samplerate_value, 1, 2, 1, 2, FILL, (AttachOptions) 0);
149 table.attach (format_text, 1, 2, 2, 4, FILL, AttachOptions (0));
150 table.attach (length_clock, 1, 2, 4, 5, FILL, (AttachOptions) 0);
151 table.attach (timecode_clock, 1, 2, 5, 6, FILL, (AttachOptions) 0);
153 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock.mode());
154 timecode_clock.set_mode (AudioClock::SMPTE);
156 hbox = manage (new HBox);
157 hbox->pack_start (table, false, false);
158 main_box.pack_start (*hbox, false, false);
160 tags_entry.set_editable (true);
161 tags_entry.signal_focus_out_event().connect (mem_fun (*this, &SoundFileBox::tags_entry_left));
162 hbox = manage (new HBox);
163 hbox->pack_start (tags_entry, true, true);
165 vbox = manage (new VBox);
167 Label* label = manage (new Label (_("Tags:")));
168 label->set_alignment (0.0f, 0.5f);
169 vbox->set_spacing (6);
170 vbox->pack_start(*label, false, false);
171 vbox->pack_start(*hbox, true, true);
173 main_box.pack_start(*vbox, true, true);
174 main_box.pack_start(bottom_box, false, false);
176 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
177 play_btn.set_label (_("Play (double click)"));
179 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
180 stop_btn.set_label (_("Stop"));
182 bottom_box.set_homogeneous (false);
183 bottom_box.set_spacing (6);
184 bottom_box.pack_start(play_btn, true, true);
185 bottom_box.pack_start(stop_btn, true, true);
186 bottom_box.pack_start(autoplay_btn, false, false);
188 play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::audition));
189 stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_audition));
191 length.set_alignment (0.0f, 0.5f);
192 format.set_alignment (0.0f, 0.5f);
193 channels.set_alignment (0.0f, 0.5f);
194 samplerate.set_alignment (0.0f, 0.5f);
195 timecode.set_alignment (0.0f, 0.5f);
197 channels_value.set_alignment (0.0f, 0.5f);
198 samplerate_value.set_alignment (0.0f, 0.5f);
202 SoundFileBox::set_session(Session* s)
207 play_btn.set_sensitive (false);
208 stop_btn.set_sensitive (false);
212 length_clock.set_session (s);
213 timecode_clock.set_session (s);
217 SoundFileBox::setup_labels (const ustring& filename)
220 // save existing tags
228 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
230 preview_label.set_markup (_("<b>Soundfile Info</b>"));
231 format_text.set_text (_("n/a"));
232 channels_value.set_text (_("n/a"));
233 samplerate_value.set_text (_("n/a"));
234 tags_entry.get_buffer()->set_text ("");
236 length_clock.set (0);
237 timecode_clock.set (0);
239 tags_entry.set_sensitive (false);
240 play_btn.set_sensitive (false);
245 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::path_get_basename (filename)));
246 format_text.set_text (sf_info.format_name);
247 channels_value.set_text (to_string (sf_info.channels, std::dec));
249 if (_session && sf_info.samplerate != _session->frame_rate()) {
250 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
251 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
252 samplerate_value.set_name ("NewSessionSR1Label");
253 samplerate.set_name ("NewSessionSR1Label");
255 samplerate.set_text (_("Sample rate:"));
256 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
257 samplerate_value.set_name ("NewSessionSR2Label");
258 samplerate.set_name ("NewSessionSR2Label");
261 length_clock.set (sf_info.length, true);
262 timecode_clock.set (sf_info.timecode, true);
264 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
266 vector<string> tags = Library->get_tags (string ("//") + filename);
268 stringstream tag_string;
269 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
270 if (i != tags.begin()) {
275 tags_entry.get_buffer()->set_text (tag_string.str());
277 tags_entry.set_sensitive (true);
279 play_btn.set_sensitive (true);
286 SoundFileBox::autoplay() const
288 return autoplay_btn.get_active();
292 SoundFileBox::audition_oneshot()
299 SoundFileBox::audition ()
305 _session->cancel_audition();
307 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
308 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
312 boost::shared_ptr<Region> r;
314 boost::shared_ptr<AudioFileSource> afs;
315 bool old_sbp = AudioSource::get_build_peakfiles ();
317 /* don't even think of building peakfiles for these files */
319 AudioSource::set_build_peakfiles (false);
321 for (int n = 0; n < sf_info.channels; ++n) {
323 afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, *_session, path,
324 n, AudioFileSource::Flag (0), false));
326 srclist.push_back(afs);
328 } catch (failed_constructor& err) {
329 error << _("Could not access soundfile: ") << path << endmsg;
330 AudioSource::set_build_peakfiles (old_sbp);
335 AudioSource::set_build_peakfiles (old_sbp);
337 if (srclist.empty()) {
341 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
342 string rname = region_name_from_path (afs->path(), false);
343 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false));
345 _session->audition_region(r);
349 SoundFileBox::stop_audition ()
352 _session->cancel_audition();
357 SoundFileBox::tags_entry_left (GdkEventFocus *ev)
364 SoundFileBox::tags_changed ()
366 string tag_string = tags_entry.get_buffer()->get_text ();
368 if (tag_string.empty()) {
374 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
375 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
383 SoundFileBox::save_tags (const vector<string>& tags)
385 Library->set_tags (string ("//") + path, tags);
386 Library->save_changes ();
389 SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::Session* s, bool persistent)
390 : ArdourDialog (parent, title, false, false),
391 found_list (ListStore::create(found_list_columns)),
392 chooser (FILE_CHOOSER_ACTION_OPEN),
393 found_list_view (found_list),
394 preview (persistent),
395 found_search_btn (_("Search"))
404 resetting_ourselves = false;
406 hpacker.set_spacing (6);
407 hpacker.pack_start (notebook, true, true);
408 hpacker.pack_start (preview, false, false);
410 get_vbox()->pack_start (hpacker, true, true);
412 hbox = manage(new HBox);
413 hbox->pack_start (found_entry);
414 hbox->pack_start (found_search_btn);
416 vbox = manage(new VBox);
417 vbox->pack_start (*hbox, PACK_SHRINK);
418 vbox->pack_start (found_list_view);
419 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
421 chooser.set_border_width (12);
423 notebook.append_page (chooser, _("Browse Files"));
424 notebook.append_page (*vbox, _("Search Tags"));
426 notebook.set_size_request (500, -1);
428 found_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
429 found_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
431 custom_filter.add_custom (FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom));
432 custom_filter.set_name (_("Audio files"));
434 matchall_filter.add_pattern ("*.*");
435 matchall_filter.set_name (_("All files"));
437 chooser.add_filter (custom_filter);
438 chooser.add_filter (matchall_filter);
439 chooser.set_select_multiple (true);
440 chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
441 chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
443 if (!persistent_folder.empty()) {
444 chooser.set_current_folder (persistent_folder);
447 found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
449 found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
450 found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
452 add_button (Stock::CANCEL, RESPONSE_CANCEL);
453 add_button (Stock::APPLY, RESPONSE_APPLY);
454 add_button (Stock::OK, RESPONSE_OK);
458 SoundFileBrowser::~SoundFileBrowser ()
460 persistent_folder = chooser.get_current_folder();
465 SoundFileBrowser::on_show ()
467 ArdourDialog::on_show ();
472 SoundFileBrowser::clear_selection ()
474 chooser.unselect_all ();
475 found_list_view.get_selection()->unselect_all ();
479 SoundFileBrowser::chooser_file_activated ()
485 SoundFileBrowser::found_list_view_activated (const TreeModel::Path& path, TreeViewColumn* col)
491 SoundFileBrowser::set_session (Session* s)
493 ArdourDialog::set_session (s);
494 preview.set_session (s);
498 remove_gain_meter ();
503 SoundFileBrowser::add_gain_meter ()
509 gm = new GainMeter (session->the_auditioner(), *session);
511 meter_packer.set_border_width (12);
512 meter_packer.pack_start (*gm, false, true);
513 hpacker.pack_end (meter_packer, false, false);
514 meter_packer.show_all ();
519 SoundFileBrowser::remove_gain_meter ()
522 meter_packer.remove (*gm);
523 hpacker.remove (meter_packer);
530 SoundFileBrowser::start_metering ()
532 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun(*this, &SoundFileBrowser::meter));
536 SoundFileBrowser::stop_metering ()
538 metering_connection.disconnect();
542 SoundFileBrowser::meter ()
544 if (is_mapped () && session && gm) {
545 gm->update_meters ();
550 SoundFileBrowser::on_custom (const FileFilter::Info& filter_info)
552 return AudioFileSource::safe_file_extension (filter_info.filename);
556 SoundFileBrowser::update_preview ()
558 if (preview.setup_labels (chooser.get_filename())) {
559 if (preview.autoplay()) {
560 Glib::signal_idle().connect (mem_fun (preview, &SoundFileBox::audition_oneshot));
566 SoundFileBrowser::found_list_view_selected ()
568 if (!reset_options ()) {
569 set_response_sensitive (RESPONSE_OK, false);
573 TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
576 TreeIter iter = found_list->get_iter(*rows.begin());
577 file = (*iter)[found_list_columns.pathname];
578 chooser.set_filename (file);
579 set_response_sensitive (RESPONSE_OK, true);
581 set_response_sensitive (RESPONSE_OK, false);
584 preview.setup_labels (file);
589 SoundFileBrowser::found_search_clicked ()
591 string tag_string = found_entry.get_text ();
595 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
596 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
600 vector<string> results;
601 Library->search_members_and (results, tags);
604 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
605 TreeModel::iterator new_row = found_list->append();
606 TreeModel::Row row = *new_row;
607 string path = Glib::filename_from_uri (string ("file:") + *i);
608 row[found_list_columns.pathname] = path;
613 SoundFileBrowser::get_paths ()
615 vector<ustring> results;
617 int n = notebook.get_current_page ();
620 vector<ustring> filenames = chooser.get_filenames();
621 vector<ustring>::iterator i;
623 for (i = filenames.begin(); i != filenames.end(); ++i) {
625 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
626 results.push_back (*i);
632 typedef TreeView::Selection::ListHandle_Path ListPath;
634 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
635 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
636 TreeIter iter = found_list->get_iter(*i);
637 ustring str = (*iter)[found_list_columns.pathname];
639 results.push_back (str);
647 SoundFileOmega::reset_options_noret ()
649 if (!resetting_ourselves) {
650 (void) reset_options ();
655 SoundFileOmega::reset_options ()
657 vector<ustring> paths = get_paths ();
661 channel_combo.set_sensitive (false);
662 action_combo.set_sensitive (false);
663 where_combo.set_sensitive (false);
664 copy_files_btn.set_sensitive (false);
670 channel_combo.set_sensitive (true);
671 action_combo.set_sensitive (true);
672 where_combo.set_sensitive (true);
674 /* if we get through this function successfully, this may be
675 reset at the end, once we know if we can use hard links
679 if (Config->get_only_copy_imported_files()) {
680 copy_files_btn.set_sensitive (false);
682 copy_files_btn.set_sensitive (false);
688 bool selection_includes_multichannel;
689 bool selection_can_be_embedded_with_links = check_link_status (*session, paths);
692 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
693 Glib::signal_idle().connect (mem_fun (*this, &SoundFileOmega::bad_file_message));
697 ustring existing_choice;
698 vector<string> action_strings;
700 if (selected_track_cnt > 0) {
701 if (channel_combo.get_active_text().length()) {
702 ImportDisposition id = get_channel_disposition();
705 case Editing::ImportDistinctFiles:
706 if (selected_track_cnt == paths.size()) {
707 action_strings.push_back (importmode2string (ImportToTrack));
711 case Editing::ImportDistinctChannels:
712 /* XXX it would be nice to allow channel-per-selected track
713 but its too hard we don't want to deal with all the
714 different per-file + per-track channel configurations.
719 action_strings.push_back (importmode2string (ImportToTrack));
725 action_strings.push_back (importmode2string (ImportAsTrack));
726 action_strings.push_back (importmode2string (ImportAsRegion));
727 action_strings.push_back (importmode2string (ImportAsTapeTrack));
729 resetting_ourselves = true;
731 existing_choice = action_combo.get_active_text();
733 set_popdown_strings (action_combo, action_strings);
735 /* preserve any existing choice, if possible */
738 if (existing_choice.length()) {
739 vector<string>::iterator x;
740 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
741 if (*x == existing_choice) {
742 action_combo.set_active_text (existing_choice);
746 if (x == action_strings.end()) {
747 action_combo.set_active_text (action_strings.front());
750 action_combo.set_active_text (action_strings.front());
753 resetting_ourselves = false;
755 if ((mode = get_mode()) == ImportAsRegion) {
756 where_combo.set_sensitive (false);
758 where_combo.set_sensitive (true);
761 vector<string> channel_strings;
763 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
764 channel_strings.push_back (_("one track per file"));
766 if (selection_includes_multichannel) {
767 channel_strings.push_back (_("one track per channel"));
770 if (paths.size() > 1) {
771 /* tape tracks are a single region per track, so we cannot
772 sequence multiple files.
774 if (mode != ImportAsTapeTrack) {
775 channel_strings.push_back (_("sequence files"));
778 channel_strings.push_back (_("all files in one region"));
784 channel_strings.push_back (_("one region per file"));
786 if (selection_includes_multichannel) {
787 channel_strings.push_back (_("one region per channel"));
790 if (paths.size() > 1) {
792 channel_strings.push_back (_("all files in one region"));
797 existing_choice = channel_combo.get_active_text();
799 set_popdown_strings (channel_combo, channel_strings);
801 /* preserve any existing choice, if possible */
803 if (existing_choice.length()) {
804 vector<string>::iterator x;
805 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
806 if (*x == existing_choice) {
807 channel_combo.set_active_text (existing_choice);
811 if (x == channel_strings.end()) {
812 channel_combo.set_active_text (channel_strings.front());
815 channel_combo.set_active_text (channel_strings.front());
819 src_combo.set_sensitive (true);
821 src_combo.set_sensitive (false);
824 if (Config->get_only_copy_imported_files()) {
826 if (selection_can_be_embedded_with_links) {
827 copy_files_btn.set_sensitive (true);
829 copy_files_btn.set_sensitive (false);
834 copy_files_btn.set_sensitive (true);
842 SoundFileOmega::bad_file_message()
844 MessageDialog msg (*this,
845 _("One or more of the selected files\ncannot be used by Ardour"),
850 resetting_ourselves = true;
851 chooser.unselect_uri (chooser.get_preview_uri());
852 resetting_ourselves = false;
858 SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool& src_needed, bool& multichannel)
867 multichannel = false;
869 for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
871 info.format = 0; // libsndfile says to clear this before sf_open().
873 if ((sf = sf_open ((char*) (*i).c_str(), SFM_READ, &info)) != 0) {
876 if (info.channels > 1) {
883 if (sz != info.frames) {
888 if ((nframes_t) info.samplerate != session->frame_rate()) {
902 SoundFileOmega::check_link_status (const Session& s, const vector<ustring>& paths)
904 sys::path path = s.session_directory().sound_path() / "linktest";
905 string tmpdir = path.to_string();
908 if (mkdir (tmpdir.c_str(), 0744)) {
909 if (errno != EEXIST) {
914 for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
916 char tmpc[MAXPATHLEN+1];
918 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
922 if (link ((*i).c_str(), tmpc)) {
932 rmdir (tmpdir.c_str());
936 SoundFileChooser::SoundFileChooser (Gtk::Window& parent, string title, ARDOUR::Session* s)
937 : SoundFileBrowser (parent, title, s, false)
939 chooser.set_select_multiple (false);
940 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
944 SoundFileChooser::on_hide ()
946 ArdourDialog::on_hide();
950 session->cancel_audition();
955 SoundFileChooser::get_filename ()
957 vector<ustring> paths;
959 paths = get_paths ();
965 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
969 return paths.front();
972 SoundFileOmega::SoundFileOmega (Gtk::Window& parent, string title, ARDOUR::Session* s, int selected_tracks, bool persistent,
973 Editing::ImportMode mode_hint)
974 : SoundFileBrowser (parent, title, s, persistent),
975 copy_files_btn ( _("Copy files to session")),
976 selected_track_cnt (selected_tracks)
982 set_size_request (-1, 450);
984 block_two.set_border_width (12);
985 block_three.set_border_width (12);
986 block_four.set_border_width (12);
988 options.set_spacing (12);
991 str.push_back (_("use file timestamp"));
992 str.push_back (_("at edit cursor"));
993 str.push_back (_("at playhead"));
994 str.push_back (_("at session start"));
995 set_popdown_strings (where_combo, str);
996 where_combo.set_active_text (str.front());
998 Label* l = manage (new Label);
999 l->set_text (_("Add files:"));
1001 hbox = manage (new HBox);
1002 hbox->set_border_width (12);
1003 hbox->set_spacing (6);
1004 hbox->pack_start (*l, false, false);
1005 hbox->pack_start (action_combo, false, false);
1006 vbox = manage (new VBox);
1007 vbox->pack_start (*hbox, false, false);
1008 options.pack_start (*vbox, false, false);
1010 /* dummy entry for action combo so that it doesn't look odd if we
1011 come up with no tracks selected.
1015 str.push_back (importmode2string (mode_hint));
1016 set_popdown_strings (action_combo, str);
1017 action_combo.set_active_text (str.front());
1018 action_combo.set_sensitive (false);
1020 l = manage (new Label);
1021 l->set_text (_("Insert:"));
1023 hbox = manage (new HBox);
1024 hbox->set_border_width (12);
1025 hbox->set_spacing (6);
1026 hbox->pack_start (*l, false, false);
1027 hbox->pack_start (where_combo, false, false);
1028 vbox = manage (new VBox);
1029 vbox->pack_start (*hbox, false, false);
1030 options.pack_start (*vbox, false, false);
1033 l = manage (new Label);
1034 l->set_text (_("Mapping:"));
1036 hbox = manage (new HBox);
1037 hbox->set_border_width (12);
1038 hbox->set_spacing (6);
1039 hbox->pack_start (*l, false, false);
1040 hbox->pack_start (channel_combo, false, false);
1041 vbox = manage (new VBox);
1042 vbox->pack_start (*hbox, false, false);
1043 options.pack_start (*vbox, false, false);
1046 str.push_back (_("one track per file"));
1047 set_popdown_strings (channel_combo, str);
1048 channel_combo.set_active_text (str.front());
1049 channel_combo.set_sensitive (false);
1051 l = manage (new Label);
1052 l->set_text (_("Conversion Quality:"));
1054 hbox = manage (new HBox);
1055 hbox->set_border_width (12);
1056 hbox->set_spacing (6);
1057 hbox->pack_start (*l, false, false);
1058 hbox->pack_start (src_combo, false, false);
1059 vbox = manage (new VBox);
1060 vbox->pack_start (*hbox, false, false);
1061 options.pack_start (*vbox, false, false);
1064 str.push_back (_("Best"));
1065 str.push_back (_("Good"));
1066 str.push_back (_("Quick"));
1067 str.push_back (_("Fast"));
1068 str.push_back (_("Fastest"));
1070 set_popdown_strings (src_combo, str);
1071 src_combo.set_active_text (str.front());
1072 src_combo.set_sensitive (false);
1076 action_combo.signal_changed().connect (mem_fun (*this, &SoundFileOmega::reset_options_noret));
1078 copy_files_btn.set_active (true);
1080 block_four.pack_start (copy_files_btn, false, false);
1082 options.pack_start (block_four, false, false);
1084 get_vbox()->pack_start (options, false, false);
1086 /* setup disposition map */
1088 disposition_map.insert (pair<ustring,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1089 disposition_map.insert (pair<ustring,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1090 disposition_map.insert (pair<ustring,ImportDisposition>(_("merge files"), ImportMergeFiles));
1091 disposition_map.insert (pair<ustring,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1093 disposition_map.insert (pair<ustring,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1094 disposition_map.insert (pair<ustring,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1095 disposition_map.insert (pair<ustring,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1097 chooser.signal_selection_changed().connect (mem_fun (*this, &SoundFileOmega::file_selection_changed));
1101 SoundFileOmega::set_mode (ImportMode mode)
1103 action_combo.set_active_text (importmode2string (mode));
1107 SoundFileOmega::get_mode () const
1109 return string2importmode (action_combo.get_active_text());
1113 SoundFileOmega::on_hide ()
1115 ArdourDialog::on_hide();
1117 session->cancel_audition();
1122 SoundFileOmega::get_position() const
1124 ustring str = where_combo.get_active_text();
1126 if (str == _("use file timestamp")) {
1127 return ImportAtTimestamp;
1128 } else if (str == _("at edit cursor")) {
1129 return ImportAtEditCursor;
1130 } else if (str == _("at playhead")) {
1131 return ImportAtPlayhead;
1133 return ImportAtStart;
1138 SoundFileOmega::get_src_quality() const
1140 ustring str = where_combo.get_active_text();
1142 if (str == _("Best")) {
1144 } else if (str == _("Good")) {
1146 } else if (str == _("Quick")) {
1148 } else if (str == _("Fast")) {
1156 SoundFileOmega::get_channel_disposition () const
1158 /* we use a map here because the channel combo can contain different strings
1159 depending on the state of the other combos. the map contains all possible strings
1160 and the ImportDisposition enum that corresponds to it.
1163 ustring str = channel_combo.get_active_text();
1164 DispositionMap::const_iterator x = disposition_map.find (str);
1166 if (x == disposition_map.end()) {
1167 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1175 SoundFileOmega::reset (int selected_tracks)
1177 selected_track_cnt = selected_tracks;
1182 SoundFileOmega::file_selection_changed ()
1184 if (resetting_ourselves) {
1188 if (!reset_options ()) {
1189 set_response_sensitive (RESPONSE_OK, false);
1191 if (chooser.get_filenames().size() > 0) {
1192 set_response_sensitive (RESPONSE_OK, true);
1194 set_response_sensitive (RESPONSE_OK, false);