Merge with 2.0-ongoing R3071.
[ardour.git] / libs / ardour / import.cc
index 91e5b9850c0bf176069136574e2e1a0e4925e78c..2bc3a00a7a1ab849244268a10fc3b6ed440cd22d 100644 (file)
@@ -46,6 +46,7 @@
 #include <ardour/region_factory.h>
 #include <ardour/source_factory.h>
 #include <ardour/resampled_source.h>
+#include <ardour/analyser.h>
 
 #include "i18n.h"
 
@@ -65,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;
@@ -84,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
@@ -104,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);
@@ -115,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);
        }
@@ -123,6 +126,25 @@ get_paths_for_new_sources (const string& import_file_path, const string& session
        return new_paths;
 }
 
+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 +250,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 +280,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,
                                get_best_session_directory_for_new_source (),
                                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));
@@ -286,11 +318,14 @@ Session::import_audiofiles (import_status& status)
 
                /* flush the final length(s) to the header(s) */
 
-               for (AudioSources::iterator x = all_new_sources.begin();
-                               x != all_new_sources.end(); ++x)
+               for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x)
                {
                        (*x)->update_header(0, *now, xnow);
                        (*x)->done_with_peakfile_writes ();
+                       
+                       /* now that there is data there, requeue the file for analysis */
+                       
+                       Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
                }
 
                /* save state so that we don't lose these new Sources */