some more information output to log during save-as, for debugging
[ardour.git] / libs / ardour / session_state.cc
index 32b6e28c47e00fe82f283191122432f02a0e6bf3..03acb63f0e0debe3ef368862fe197afe58842ff3 100644 (file)
@@ -658,7 +658,7 @@ Session::remove_state (string snapshot_name)
 
 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
 int
-Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
+Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot, bool template_only)
 {
        XMLTree tree;
        std::string xml_path(_session_dir->root_path());
@@ -696,7 +696,11 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
 
        SessionSaveUnderway (); /* EMIT SIGNAL */
 
-       tree.set_root (&get_state());
+       if (template_only) {
+               tree.set_root (&get_template());
+       } else {
+               tree.set_root (&get_state());
+       }
 
        if (snapshot_name.empty()) {
                snapshot_name = _current_snapshot_name;
@@ -2785,6 +2789,16 @@ Session::cleanup_sources (CleanupReport& rep)
                                        
                                        RegionFactory::remove_regions_using_source (i->second);
                                        sources.erase (i);
+                                       
+                                       // also remove source from all_sources
+                                       
+                                       for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
+                                               spath = Glib::path_get_basename (*j);
+                                               if ( spath == i->second->name () ) {
+                                                       all_sources.erase (j);
+                                                       break;
+                                               }
+                                       }
                                }
                        }
                }
@@ -3077,6 +3091,10 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
                c = r->gain_control ();
                break;
 
+       case ControllableDescriptor::Trim:
+               c = r->trim()->gain_control ();
+               break;
+
        case ControllableDescriptor::Solo:
                 c = r->solo_control();
                break;
@@ -3627,7 +3645,7 @@ Session::solo_cut_control() const
 }
 
 int
-Session::rename (const std::string& new_name, bool after_copy)
+Session::rename (const std::string& new_name)
 {
        string legal_name = legalize_for_path (new_name);
        string new_path;
@@ -3662,41 +3680,34 @@ Session::rename (const std::string& new_name, bool after_copy)
         * already exist ...
         */
 
-       if (!after_copy) {
-
-               for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
-                       
-                       if (first) {
-                               /* primary session directory */
-                               newstr = _path;
-                               first = false;
-                       } else {
-                               oldstr = (*i).path;
-                               
-                               /* this is a stupid hack because Glib::path_get_dirname() is
-                                * lexical-only, and so passing it /a/b/c/ gives a different
-                                * result than passing it /a/b/c ...
-                                */
-                               
-                               if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
-                                       oldstr = oldstr.substr (0, oldstr.length() - 1);
-                               }
-
-                               string base = Glib::path_get_dirname (oldstr);
-                               string p = Glib::path_get_basename (oldstr);
-                               
-                               newstr = Glib::build_filename (base, legal_name);
-                       }
-                       
-                       if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
-                               return -1;
-                       }
+       for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
+               
+               oldstr = (*i).path;
+               
+               /* this is a stupid hack because Glib::path_get_dirname() is
+                * lexical-only, and so passing it /a/b/c/ gives a different
+                * result than passing it /a/b/c ...
+                */
+               
+               if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
+                       oldstr = oldstr.substr (0, oldstr.length() - 1);
+               }
+               
+               string base = Glib::path_get_dirname (oldstr);
+               
+               newstr = Glib::build_filename (base, legal_name);
+               
+               cerr << "Looking for " << newstr << endl;
+               
+               if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
+                       cerr << " exists\n";
+                       return -1;
                }
        }
 
        /* Session dirs */
 
-       first = false;
+       first = true;
        
        for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
 
@@ -3713,19 +3724,16 @@ Session::rename (const std::string& new_name, bool after_copy)
                        oldstr = oldstr.substr (0, oldstr.length() - 1);
                }
 
-               if (first) {
-                       newstr = _path;
-               } else {
-                       string base = Glib::path_get_dirname (oldstr);
-                       newstr = Glib::build_filename (base, legal_name);
-               }
+               string base = Glib::path_get_dirname (oldstr);
+               newstr = Glib::build_filename (base, legal_name);
 
-               if (!after_copy) {
-                       cerr << "Rename " << oldstr << " => " << newstr << endl;                
-                       if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
-                               error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
-                               return 1;
-                       }
+               cerr << "for " << oldstr << " new dir = " << newstr << endl;
+               
+               cerr << "Rename " << oldstr << " => " << newstr << endl;                
+               if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
+                       cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
+                       error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
+                       return 1;
                }
 
                /* Reset path in "session dirs" */
@@ -3746,7 +3754,9 @@ Session::rename (const std::string& new_name, bool after_copy)
                string old_interchange_dir;
                string new_interchange_dir;
 
-               /* use newstr here because we renamed the path that used to be oldstr to newstr above */                
+               /* use newstr here because we renamed the path
+                * (folder/directory) that used to be oldstr to newstr above 
+                */     
                
                v.push_back (newstr); 
                v.push_back (interchange_dir_name);
@@ -3764,6 +3774,10 @@ Session::rename (const std::string& new_name, bool after_copy)
                cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
                
                if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
+                       cerr << string_compose (_("renaming %s as %2 failed (%3)"),
+                                                old_interchange_dir, new_interchange_dir,
+                                                g_strerror (errno))
+                             << endl;
                        error << string_compose (_("renaming %s as %2 failed (%3)"),
                                                 old_interchange_dir, new_interchange_dir,
                                                 g_strerror (errno))
@@ -3774,12 +3788,13 @@ Session::rename (const std::string& new_name, bool after_copy)
 
        /* state file */
        
-       oldstr = Glib::build_filename (new_path, _current_snapshot_name) + statefile_suffix;
-       newstr= Glib::build_filename (new_path, legal_name) + statefile_suffix;
+       oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
+       newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
        
        cerr << "Rename " << oldstr << " => " << newstr << endl;                
 
        if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
+               cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
                error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
                return 1;
        }
@@ -3794,32 +3809,31 @@ Session::rename (const std::string& new_name, bool after_copy)
                cerr << "Rename " << oldstr << " => " << newstr << endl;                
                
                if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
+                       cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
                        error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
                        return 1;
                }
        }
 
-       if (!after_copy) {
-               /* remove old name from recent sessions */
-               remove_recent_sessions (_path);
-               _path = new_path;
-
-               /* update file source paths */
-               
-               for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
-                       boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
-                       if (fs) {
-                               string p = fs->path ();
-                               boost::replace_all (p, old_sources_root, _session_dir->sources_root());
-                               fs->set_path (p);
-                               SourceFactory::setup_peakfile(i->second, true);
-                       }
+       /* remove old name from recent sessions */
+       remove_recent_sessions (_path);
+       _path = new_path;
+       
+       /* update file source paths */
+       
+       for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
+               boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
+               if (fs) {
+                       string p = fs->path ();
+                       boost::replace_all (p, old_sources_root, _session_dir->sources_root());
+                       fs->set_path (p);
+                       SourceFactory::setup_peakfile(i->second, true);
                }
        }
 
        _current_snapshot_name = new_name;
        _name = new_name;
-
+       
        set_dirty ();
 
        /* save state again to get everything just right */
@@ -4087,9 +4101,8 @@ Session::save_as (SaveAs& saveas)
        }
 
        try {
-               /* copy all media files. Find each location in
-                * session_dirs, and copy files from there to
-                * target.
+               /* copy all relevant files. Find each location in session_dirs,
+                * and copy files from there to target.
                 */
                
                for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
@@ -4120,10 +4133,12 @@ Session::save_as (SaveAs& saveas)
                                        
                                        /* media file */
 
-                                       if (saveas.copy_media) {
+                                       if (saveas.include_media && saveas.copy_media) {
                                                
                                                string to = make_new_media_path (*i, to_dir, new_folder);
 
+                                               info << "media file copying from " << from << " to " << to << endmsg;
+                                               
                                                if (!copy_file (from, to)) {
                                                        throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
                                                }
@@ -4151,9 +4166,13 @@ Session::save_as (SaveAs& saveas)
                                        if (do_copy) {
                                                string to = Glib::build_filename (to_dir, (*i).substr (prefix_len));
                                                
+                                               info << "attempting to make directory/folder " << to << endmsg;
+
                                                if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
                                                        throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
                                                }
+
+                                               info << "attempting to copy " << from << " to " << to << endmsg;
                                                
                                                if (!copy_file (from, to)) {
                                                        throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
@@ -4189,11 +4208,48 @@ Session::save_as (SaveAs& saveas)
 
                }
 
+               /* copy optional folders, if any */
+
+               string old = plugins_dir ();
+               if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
+                       string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
+                       copy_files (old, newdir);
+               }
+
+               old = externals_dir ();
+               if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
+                       string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
+                       copy_files (old, newdir);
+               }
+
+               old = automation_dir ();
+               if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
+                       string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
+                       copy_files (old, newdir);
+               }
+
+               if (saveas.include_media) {
+               
+                       if (saveas.copy_media) {
+                               
+                               /* only needed if we are copying media, since the
+                                * analysis data refers to media data
+                                */
+                               
+                               old = analysis_dir ();
+                               if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
+                                       string newdir = Glib::build_filename (to_dir, "analysis");
+                                       copy_files (old, newdir);
+                               }
+                       }
+               }
+                       
+               
                _path = to_dir;
                _current_snapshot_name = saveas.new_name;
                _name = saveas.new_name;
 
-               if (!saveas.copy_media) {
+               if (saveas.include_media && !saveas.copy_media) {
 
                        /* reset search paths of the new session (which we're pretending to be right now) to
                           include the original session search path, so we can still find all audio.
@@ -4202,6 +4258,7 @@ Session::save_as (SaveAs& saveas)
                        if (internal_file_cnt) {
                                for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
                                        ensure_search_path_includes (*s, DataType::AUDIO);
+                                       cerr << "be sure to include " << *s << "  for audio" << endl;
                                }
 
                                for (vector<string>::iterator s = old_search_path[DataType::MIDI].begin(); s != old_search_path[DataType::MIDI].end(); ++s) {
@@ -4212,7 +4269,7 @@ Session::save_as (SaveAs& saveas)
                
                bool was_dirty = dirty ();
 
-               save_state ("", false, false);
+               save_state ("", false, false, !saveas.include_media);
                save_default_options ();
                
                if (saveas.copy_media && saveas.copy_external) {
@@ -4221,6 +4278,8 @@ Session::save_as (SaveAs& saveas)
                        }
                }
 
+               saveas.final_session_folder_name = _path;
+               
                if (!saveas.switch_to) {
 
                        /* switch back to the way things were */