diff options
-rw-r--r-- | gtk2_ardour/editor.h | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor_audio_import.cc | 295 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 8 | ||||
-rw-r--r-- | libs/ardour/import.cc | 43 |
4 files changed, 249 insertions, 101 deletions
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index f6f4188b58..f76804d288 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1050,6 +1050,8 @@ class Editor : public PublicEditor void add_external_audio_action (Editing::ImportMode); void external_audio_dialog (); + + int check_whether_and_how_to_import(string, bool all_or_nothing = true); bool check_multichannel_status (const std::vector<Glib::ustring>& paths); SoundFileOmega* sfbrowser; @@ -1062,7 +1064,7 @@ class Editor : public PublicEditor bool idle_do_embed (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, nframes64_t&); int import_sndfiles (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::SrcQuality, nframes64_t& pos, - int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&); + int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&, bool); int embed_sndfiles (vector<Glib::ustring> paths, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode, nframes64_t& pos, int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&); diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 971b77acef..fa14e2b88f 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -42,6 +42,7 @@ #include <ardour/audiofilesource.h> #include <ardour/region_factory.h> #include <ardour/source_factory.h> +#include <ardour/session.h> #include <pbd/memento_command.h> #include "ardour_ui.h" @@ -114,60 +115,139 @@ Editor::external_audio_dialog () sfbrowser->show_all (); - again: - int response = sfbrowser->run (); - switch (response) { - case RESPONSE_APPLY: - // leave the dialog open - break; + bool keepRunning; - case RESPONSE_OK: - sfbrowser->hide (); - break; + do { + keepRunning = false; - default: - // cancel from the browser - we are done - sfbrowser->hide (); - return; - } + int response = sfbrowser->run (); - /* lets do it */ - - paths = sfbrowser->get_paths (); + switch (response) { + case RESPONSE_APPLY: + // leave the dialog open + break; - ImportPosition pos = sfbrowser->get_position (); - ImportMode mode = sfbrowser->get_mode (); - ImportDisposition chns = sfbrowser->get_channel_disposition (); - nframes64_t where; + case RESPONSE_OK: + sfbrowser->hide (); + break; - switch (pos) { - case ImportAtEditPoint: - where = get_preferred_edit_position (); - break; - case ImportAtTimestamp: - where = -1; - break; - case ImportAtPlayhead: - where = playhead_cursor->current_frame; - break; - case ImportAtStart: - where = session->current_start_frame(); - break; - } + default: + // cancel from the browser - we are done + sfbrowser->hide (); + return; + } - SrcQuality quality = sfbrowser->get_src_quality(); + /* lets do it */ + + paths = sfbrowser->get_paths (); + + ImportPosition pos = sfbrowser->get_position (); + ImportMode mode = sfbrowser->get_mode (); + ImportDisposition chns = sfbrowser->get_channel_disposition (); + nframes64_t where; + + switch (pos) { + case ImportAtEditPoint: + where = get_preferred_edit_position (); + break; + case ImportAtTimestamp: + where = -1; + break; + case ImportAtPlayhead: + where = playhead_cursor->current_frame; + break; + case ImportAtStart: + where = session->current_start_frame(); + break; + } - if (sfbrowser->copy_files_btn.get_active()) { - do_import (paths, chns, mode, quality, where); - } else { - do_embed (paths, chns, mode, where); + SrcQuality quality = sfbrowser->get_src_quality(); + + + if (sfbrowser->copy_files_btn.get_active()) { + do_import (paths, chns, mode, quality, where); + } else { + do_embed (paths, chns, mode, where); + } + + if (response == RESPONSE_APPLY) { + sfbrowser->clear_selection (); + keepRunning = true; + } + + } while (keepRunning); +} + +typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList; + +/** + * Updating is still disabled, see note in libs/ardour/import.cc Session::import_audiofiles() + * + * all_or_nothing: + * true = show "Update", "Import" and "Skip" + * false = show "Import", and "Cancel" + * + * Returns: + * 0 To update an existing source of the same name + * 1 To import/embed the file normally (make sure the new name will be unique) + * 2 If the user wants to skip this file + **/ +int +Editor::check_whether_and_how_to_import(string path, bool all_or_nothing) +{ + string wave_name (basename(path.c_str())); + + AudioSourceList all_sources = session->get_audio_sources(); + bool wave_name_exists = false; + + for (AudioSourceList::iterator i = all_sources.begin(); i != all_sources.end(); ++i) { + boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second); + + string tmp (basename(afs->path().c_str())); + + if (tmp == wave_name) { + wave_name_exists = true; + break; + } } - if (response == RESPONSE_APPLY) { - sfbrowser->clear_selection (); - goto again; + int function = 1; + + + if (wave_name_exists) { + string message; + if (all_or_nothing) { + // updating is still disabled + //message = string_compose(_("The session already contains a source file named %1. Do you want to update that file (and thus all regions using the file) or import this file as a new file?"),wave_name); + message = string_compose(_("The session already contains a source file named %1. This file will be imported as a new file, please confirm."),wave_name); + } else { + message = _("Lorem ipsum. Do you want to skidaddle?"); + + } + MessageDialog dialog(message, false,Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true); + + if (all_or_nothing) { + // disabled + //dialog.add_button("Update", 0); + dialog.add_button("Import", 1); + dialog.add_button("Skip", 2); + } else { + dialog.add_button("Import", 1); + dialog.add_button("Cancel", 2); + } + + + //dialog.add_button("Skip all", 4); // All or rest? + + dialog.show(); + + function = dialog.run (); + + dialog.hide(); } + + return function; } boost::shared_ptr<AudioTrack> @@ -205,79 +285,107 @@ Editor::do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mod { boost::shared_ptr<AudioTrack> track; vector<ustring> to_import; - bool ok = false; + bool ok = true; int nth = 0; if (interthread_progress_window == 0) { build_interthread_progress_window (); } - switch (chns) { - case Editing::ImportDistinctFiles: - for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) { - - to_import.clear (); - to_import.push_back (*a); - if (mode == Editing::ImportToTrack) { - track = get_nth_selected_audio_track (nth++); - } - - if (import_sndfiles (to_import, mode, quality, pos, 1, -1, track)) { - goto out; + if (chns == Editing::ImportMergeFiles) { + /* create 1 region from all paths, add to 1 track, + ignore "track" + */ + bool cancel = false; + for (vector<ustring>::iterator a = paths.begin(); a != paths.end() && ok; ++a) { + int check = check_whether_and_how_to_import(*a, false); + if (check == 2) { + cancel = true; + break; } + } + if (!cancel) { + if (import_sndfiles (paths, mode, quality, pos, 1, 1, track, false)) { + ok = false; + } } - break; - case Editing::ImportDistinctChannels: - for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) { + } else { + bool replace; - to_import.clear (); - to_import.push_back (*a); + for (vector<ustring>::iterator a = paths.begin(); a != paths.end() && ok; ++a) { - if (import_sndfiles (to_import, mode, quality, pos, -1, -1, track)) { - goto out; + int check = check_whether_and_how_to_import(*a, true); + + if (check == 2 ) { + // skip + continue; } - } - break; + if (check == 0) { + fatal << "Updating existing sources should be disabled!" << endl; + replace = true; + } else if (check == 1) { + replace = false; + } + - case Editing::ImportMergeFiles: - /* create 1 region from all paths, add to 1 track, - ignore "track" - */ - if (import_sndfiles (paths, mode, quality, pos, 1, 1, track)) { - goto out; - } - break; + switch (chns) { + case Editing::ImportDistinctFiles: - case Editing::ImportSerializeFiles: - for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) { + to_import.clear (); + to_import.push_back (*a); - to_import.clear (); - to_import.push_back (*a); - - /* create 1 region from this path, add to 1 track, - reuse "track" across paths - */ + if (mode == Editing::ImportToTrack) { + track = get_nth_selected_audio_track (nth++); + } - if (import_sndfiles (to_import, mode, quality, pos, 1, 1, track)) { - goto out; + if (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, replace)) { + ok = false; + } + + break; + + case Editing::ImportDistinctChannels: + + to_import.clear (); + to_import.push_back (*a); + + if (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, replace)) { + ok = false; + } + + break; + + case Editing::ImportSerializeFiles: + + to_import.clear (); + to_import.push_back (*a); + + /* create 1 region from this path, add to 1 track, + reuse "track" across paths + */ + + if (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, replace)) { + ok = false; + } + + break; + + case Editing::ImportMergeFiles: + // Not entered + break; } + } + if (ok) { + session->save_state (""); } - break; - } - ok = true; - - out: - if (ok) { - session->save_state (""); + interthread_progress_window->hide_all (); } - - interthread_progress_window->hide_all (); } bool @@ -365,7 +473,7 @@ Editor::_do_embed (vector<ustring> paths, ImportDisposition chns, ImportMode mod int Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality quality, nframes64_t& pos, - int target_regions, int target_tracks, boost::shared_ptr<AudioTrack>& track) + int target_regions, int target_tracks, boost::shared_ptr<AudioTrack>& track, bool replace) { WindowTitle title = string_compose (_("importing %1"), paths.front()); @@ -382,6 +490,7 @@ Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality qual import_status.freeze = false; import_status.done = 0.0; import_status.quality = quality; + import_status.replace_existing_source = replace; interthread_progress_connection = Glib::signal_timeout().connect (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 2889e73c38..9866c1cbe0 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -577,10 +577,10 @@ class Session : public PBD::StatefulDestructible string doing_what; /* control info */ - bool sample_convert; SrcQuality quality; volatile bool freeze; std::vector<Glib::ustring> paths; + bool replace_existing_source; /* result */ SourceList sources; @@ -1494,6 +1494,12 @@ class Session : public PBD::StatefulDestructible AudioSourceList audio_sources; + public: + AudioSourceList get_audio_sources() { return audio_sources; } + + private: + + int load_sources (const XMLNode& node); XMLNode& get_sources_as_xml (); diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 3c3e63be90..edf8f03373 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -66,7 +66,7 @@ open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQua } static std::string -get_non_existent_filename (const std::string& basename, uint channel, uint channels) +get_non_existent_filename (const bool allow_replacing, const std::string destdir, const std::string& basename, uint channel, uint channels) { char buf[PATH_MAX+1]; bool goodfile = false; @@ -85,7 +85,9 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann snprintf (buf, sizeof(buf), "%s.wav", base.c_str()); } - if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) { + + string tempname = destdir + "/" + buf; + if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) { /* if the file already exists, we must come up with * a new name for it. for now we just keep appending @@ -105,7 +107,7 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann } static vector<string> -get_paths_for_new_sources (const string& import_file_path, const string& session_dir, uint channels) +get_paths_for_new_sources (const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels) { vector<string> new_paths; const string basename = basename_nosuffix (import_file_path); @@ -116,7 +118,7 @@ get_paths_for_new_sources (const string& import_file_path, const string& session filepath = session_dir; filepath += '/'; - filepath += get_non_existent_filename (basename, n, channels); + filepath += get_non_existent_filename (allow_replacing, session_dir, basename, n, channels); new_paths.push_back (filepath); } @@ -125,6 +127,25 @@ get_paths_for_new_sources (const string& import_file_path, const string& session } static bool +map_existing_mono_sources (const vector<string>& new_paths, Session& sess, + uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles, Session *session) +{ + for (vector<string>::const_iterator i = new_paths.begin(); + i != new_paths.end(); ++i) + { + boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0); + + if (source == 0) { + error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl; + return false; + } + + newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source)); + } + return true; +} + +static bool create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess, uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles) { @@ -228,6 +249,10 @@ remove_file_source (boost::shared_ptr<AudioFileSource> file_source) ::unlink (file_source->path().c_str()); } +// This function is still unable to cleanly update an existing source, even though +// it is possible to set the import_status flag accordingly. The functinality +// is disabled at the GUI until the Source implementations are able to provide +// the necessary API. void Session::import_audiofiles (import_status& status) { @@ -254,13 +279,19 @@ Session::import_audiofiles (import_status& status) return; } - vector<string> new_paths = get_paths_for_new_sources (*p, + vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, + *p, discover_best_sound_dir (), source->channels()); AudioSources newfiles; - status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles); + if (status.replace_existing_source) { + fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl; + status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this); + } else { + status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles); + } // copy on cancel/failure so that any files that were created will be removed below std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources)); |