#include "ardour/playlist_source.h"
#include "ardour/port.h"
#include "ardour/processor.h"
+#include "ardour/profile.h"
#include "ardour/proxy_controllable.h"
#include "ardour/recent_sessions.h"
#include "ardour/region_factory.h"
_path = canonical_path(fullpath);
/* is it new ? */
+ if (Profile->get_trx() ) {
+ // Waves TracksLive has a usecase of session replacement with a new one.
+ // We should check session state file (<session_name>.ardour) existance
+ // to determine if the session is new or not
- _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+ string full_session_name = Glib::build_filename( fullpath, _name );
+ full_session_name += statefile_suffix;
+
+ _is_new = !Glib::file_test (full_session_name, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+ } else {
+ _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+ }
/* finish initialization that can't be done in a normal C++ constructor
definition.
Config->map_parameters (ff);
config.map_parameters (ft);
+ _butler->map_parameters ();
/* Reset all panners */
state_was_pending = false;
}
+ /* Now, finally, we can fill the playback buffers */
+
+ BootMessage (_("Filling playback buffers"));
+
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+ boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
+ if (trk && !trk->hidden()) {
+ trk->seek (_transport_frame, true);
+ }
+ }
+
return 0;
}
+void
+Session::session_loaded ()
+{
+ SessionLoaded();
+
+ _state_of_the_state = Clean;
+
+ DirtyChanged (); /* EMIT SIGNAL */
+
+ if (_is_new) {
+ save_state ("");
+ } else if (state_was_pending) {
+ save_state ("");
+ remove_pending_capture_state ();
+ state_was_pending = false;
+ }
+
+ /* Now, finally, we can fill the playback buffers */
+
+ BootMessage (_("Filling playback buffers"));
+ force_locate (_transport_frame, false);
+}
+
string
Session::raid_path () const
{
_writable = exists_and_writable (_path);
if (!session_template.empty()) {
- std::string in_path = session_template_dir_to_file (session_template);
+ std::string in_path = (ARDOUR::Profile->get_trx () ? session_template : session_template_dir_to_file (session_template));
ifstream in(in_path.c_str());
out << in.rdbuf();
_is_new = false;
- /* Copy plugin state files from template to new session */
- std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
- copy_recurse (template_plugins, plugins_dir ());
-
+ if (!ARDOUR::Profile->get_trx()) {
+ /* Copy plugin state files from template to new session */
+ std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
+ copy_recurse (template_plugins, plugins_dir ());
+ }
+
return 0;
} else {
}
- /* set initial start + end point */
+ if (Profile->get_trx()) {
+
+ /* set initial start + end point : ARDOUR::Session::session_end_shift long.
+ Remember that this is a brand new session. Sessions
+ loaded from saved state will get this range from the saved state.
+ */
+
+ set_session_range_location (0, 0);
+
+ /* Initial loop location, from absolute zero, length 10 seconds */
+
+ Location* loc = new Location (*this, 0, 10.0 * _engine.sample_rate(), _("Loop"), Location::IsAutoLoop);
+ _locations->add (loc, true);
+ set_auto_loop_location (loc);
+ }
_state_of_the_state = Clean;
RouteList rl;
ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
- if (bus_profile->master_out_channels) {
- boost::shared_ptr<Route> r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO));
+ // Waves Tracks: always create master bus for Tracks
+ if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) {
+ boost::shared_ptr<Route> r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO));
if (r->init ()) {
return -1;
}
add_routes (rl, false, false, false);
}
- /* this allows the user to override settings with an environment variable.
- */
-
- if (no_auto_connect()) {
- bus_profile->input_ac = AutoConnectOption (0);
- bus_profile->output_ac = AutoConnectOption (0);
- }
-
- Config->set_input_auto_connect (bus_profile->input_ac);
- Config->set_output_auto_connect (bus_profile->output_ac);
+ // Waves Tracks: Skip this. Always use autoconnection for Tracks
+ if (!ARDOUR::Profile->get_trx()) {
+
+ /* this allows the user to override settings with an environment variable.
+ */
+
+ if (no_auto_connect()) {
+ bus_profile->input_ac = AutoConnectOption (0);
+ bus_profile->output_ac = AutoConnectOption (0);
+ }
+
+ Config->set_input_auto_connect (bus_profile->input_ac);
+ Config->set_output_auto_connect (bus_profile->output_ac);
+ }
}
if (Config->get_use_monitor_bus() && bus_profile) {
/** @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());
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;
}
}
}
+
+
if (full_state) {
- node->add_child_nocopy (_locations->get_state());
+
+ if (_locations) {
+ node->add_child_nocopy (_locations->get_state());
+ }
} else {
+ Locations loc (*this);
// for a template, just create a new Locations, populate it
// with the default start and end, and get the state for that.
- Locations loc (*this);
Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
range->set (max_framepos, 0);
loc.add (range);
- node->add_child_nocopy (loc.get_state());
+ XMLNode& locations_state = loc.get_state();
+
+ if (ARDOUR::Profile->get_trx() && _locations) {
+ // For tracks we need stored the Auto Loop Range and all MIDI markers.
+ for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
+ if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
+ locations_state.add_child_nocopy ((*i)->get_state ());
+ }
+ }
+ }
+ node->add_child_nocopy (locations_state);
}
child = node->add_child ("Bundles");
RoutePublicOrderSorter cmp;
RouteList public_order (*r);
public_order.sort (cmp);
-
- /* the sort should have put control outs first */
-
- if (_monitor_out) {
- assert (_monitor_out == public_order.front());
- }
+
+ /* the sort should have put control outs first */
+
+ if (_monitor_out) {
+ assert (_monitor_out == public_order.front());
+ }
for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
if (!(*i)->is_auditioner()) {
ControlProtocolManager::instance().set_state (*child, version);
}
- update_have_rec_enabled_track ();
+ update_route_record_state ();
/* here beginneth the second phase ... */
void
Session::reset_write_sources (bool mark_write_complete, bool force)
{
- boost::shared_ptr<RouteList> rl = routes.reader();
- for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
- boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
- if (tr) {
-
- // block state saving
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
_state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
tr->reset_write_sources(mark_write_complete, force);
_state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
- }
- }
+ }
+ }
}
int
int
Session::save_template (string template_name)
{
- XMLTree tree;
-
- if (_state_of_the_state & CannotSave) {
+ if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
return -1;
}
- std::string user_template_dir(user_template_directory());
+ bool absolute_path = Glib::path_is_absolute (template_name);
- if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
- error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
- user_template_dir, g_strerror (errno)) << endmsg;
- return -1;
- }
+ /* directory to put the template in */
+ std::string template_dir_path;
- tree.set_root (&get_template());
+ if (!absolute_path) {
+ std::string user_template_dir(user_template_directory());
- std::string template_dir_path(user_template_dir);
-
- /* directory to put the template in */
- template_dir_path = Glib::build_filename (template_dir_path, template_name);
+ if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
+ error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
+ user_template_dir, g_strerror (errno)) << endmsg;
+ return -1;
+ }
- if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
- warning << string_compose(_("Template \"%1\" already exists - new version not created"),
- template_dir_path) << endmsg;
- return -1;
+ template_dir_path = Glib::build_filename (user_template_dir, template_name);
+ } else {
+ template_dir_path = template_name;
}
-
- if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
- error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
- template_dir_path, g_strerror (errno)) << endmsg;
- return -1;
+
+ if (!ARDOUR::Profile->get_trx()) {
+ if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
+ warning << string_compose(_("Template \"%1\" already exists - new version not created"),
+ template_dir_path) << endmsg;
+ return -1;
+ }
+
+ if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
+ error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
+ template_dir_path, g_strerror (errno)) << endmsg;
+ return -1;
+ }
}
/* file to write */
- std::string template_file_path(template_dir_path);
- template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
+ std::string template_file_path;
+
+ if (ARDOUR::Profile->get_trx()) {
+ template_file_path = template_name;
+ } else {
+ if (absolute_path) {
+ template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
+ } else {
+ template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
+ }
+ }
+
+ SessionSaveUnderway (); /* EMIT SIGNAL */
+
+ XMLTree tree;
+ tree.set_root (&get_template());
if (!tree.write (template_file_path)) {
error << _("template not saved") << endmsg;
return -1;
}
- /* copy plugin state directory */
+ if (!ARDOUR::Profile->get_trx()) {
+ /* copy plugin state directory */
- std::string template_plugin_state_path(template_dir_path);
- template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
+ std::string template_plugin_state_path (Glib::build_filename (template_dir_path, X_("plugins")));
- if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
- error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
- template_plugin_state_path, g_strerror (errno)) << endmsg;
- return -1;
+ if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
+ error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
+ template_plugin_state_path, g_strerror (errno)) << endmsg;
+ return -1;
+ }
+ copy_files (plugins_dir(), template_plugin_state_path);
}
- copy_recurse (plugins_dir(), template_plugin_state_path);
+ store_recent_templates (template_file_path);
return 0;
}
string
Session::automation_dir () const
{
- return Glib::build_filename (_path, "automation");
+ return Glib::build_filename (_path, automation_dir_name);
}
string
Session::analysis_dir () const
{
- return Glib::build_filename (_path, "analysis");
+ return Glib::build_filename (_path, analysis_dir_name);
}
string
Session::plugins_dir () const
{
- return Glib::build_filename (_path, "plugins");
+ return Glib::build_filename (_path, plugins_dir_name);
}
string
Session::externals_dir () const
{
- return Glib::build_filename (_path, "externals");
+ return Glib::build_filename (_path, externals_dir_name);
}
int
in the region list.
*/
+ std::string fpath = i->second->name ();
+
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 == fpath ) {
+ all_sources.erase (j);
+ break;
+ }
+ }
}
}
}
c = r->gain_control ();
break;
+ case ControllableDescriptor::Trim:
+ c = r->trim()->gain_control ();
+ break;
+
case ControllableDescriptor::Solo:
c = r->solo_control();
break;
reconnect_ltc_output ();
} else if (p == "timecode-generator-offset") {
ltc_tx_parse_offset();
+ } else if (p == "auto-return-target-list") {
+ follow_playhead_priority ();
}
set_dirty ();
}
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;
* Backup files are left unchanged and not renamed.
*/
+ /* Windows requires that we close all files before attempting the
+ * rename. This works on other platforms, but isn't necessary there.
+ * Leave it in place for all platforms though, since it may help
+ * catch issues that could arise if the way Source files work ever
+ * change (since most developers are not using Windows).
+ */
+
+ for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
+ boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
+ if (fs) {
+ fs->close ();
+ }
+ }
+
/* pass one: not 100% safe check that the new directory names don't
* 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) {
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" */
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);
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))
/* 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;
}
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 */
}
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) {
find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
+ /* add dir separator to protect against collisions with
+ * track names (e.g. track named "audiofiles" or
+ * "analysis".
+ */
+
+ static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
+ static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
+ static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
+
/* copy all the files. Handling is different for media files
than others because of the *silly* subtree we have below the interchange
folder. That really was a bad idea, but I'm not fixing it as part of
for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
std::string from = *i;
+
+#ifdef __APPLE__
+ string filename = Glib::path_get_basename (from);
+ std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
+ if (filename == ".DS_STORE") {
+ continue;
+ }
+#endif
- if ((*i).find (interchange_dir_name) != string::npos) {
+ if (from.find (audiofile_dir_string) != string::npos) {
- /* media file */
+ /* audio file: only copy if asked */
- 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");
+ throw Glib::FileError (Glib::FileError::IO_ERROR,
+ string_compose(_("\ncopying \"%1\" failed !"), from));
}
}
/* we found media files inside the session folder */
internal_file_cnt++;
+
+ } else if (from.find (midifile_dir_string) != string::npos) {
+
+ /* midi file: always copy unless
+ * creating an empty new session
+ */
+
+ if (saveas.include_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");
+ }
+ }
+
+ /* we found media files inside the session folder */
+
+ internal_file_cnt++;
+
+ } else if (from.find (analysis_dir_string) != string::npos) {
+
+ /* make sure analysis dir exists in
+ * new session folder, but we're not
+ * copying analysis files here, see
+ * below
+ */
+
+ (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
+ continue;
} else {
bool do_copy = true;
for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
- if (((*i).length() > (*v).length()) && ((*i).find (*v) == (*i).length() - (*v).length())) {
+ if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
/* end of filename matches extension, do not copy file */
do_copy = false;
break;
}
}
+
+ if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
+ /* don't copy peakfiles if
+ * we're not copying media
+ */
+ do_copy = false;
+ }
if (do_copy) {
- string to = Glib::build_filename (to_dir, (*i).substr (prefix_len));
+ string to = Glib::build_filename (to_dir, from.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");
+ throw Glib::FileError (Glib::FileError::IO_ERROR,
+ string_compose(_("\ncopying \"%1\" failed !"), from));
}
}
}
*/
GStatBuf gsb;
- g_stat ((*i).c_str(), &gsb);
+ g_stat (from.c_str(), &gsb);
copied += gsb.st_size;
cnt++;
double fraction = (double) copied / total_bytes;
- /* tell someone "X percent, file M of N"; M is one-based */
-
- boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
bool keep_going = true;
- if (res) {
- keep_going = *res;
+ if (saveas.copy_media) {
+
+ /* no need or expectation of this if
+ * media is not being copied, because
+ * it will be fast(ish).
+ */
+
+ /* tell someone "X percent, file M of N"; M is one-based */
+
+ boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
+
+ if (res) {
+ keep_going = *res;
+ }
}
if (!keep_going) {
}
+ /* 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) {
+#ifndef PLATFORM_WINDOWS
+ /* There are problems with analysis files on
+ * Windows, because they used a colon in their
+ * names as late as 4.0. Colons are not legal
+ * under Windows even if NTFS allows them.
+ *
+ * This is a tricky problem to solve so for
+ * just don't copy these files. They will be
+ * regenerated as-needed anyway, subject to the
+ * existing issue that the filenames will be
+ * rejected by Windows, which is a separate
+ * problem (though related).
+ */
+
+ /* 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);
+ }
+#endif /* PLATFORM_WINDOWS */
+ }
+ }
+
+
_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.
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) {
- ensure_search_path_includes (*s, DataType::MIDI);
- }
+ /* we do not do this for MIDI because we copy
+ all MIDI files if saveas.include_media is
+ true
+ */
}
}
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) {
}
}
+ saveas.final_session_folder_name = _path;
+
+ store_recent_sessions (_name, _path);
+
if (!saveas.switch_to) {
/* switch back to the way things were */