X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_state.cc;h=62edaa39115fe8e5b9b556228c4f283d341cd844;hb=453ed61c4a23551c7ffeee5d972b29d6d92c1591;hp=2f69ff2dee3dbd7d337bfe7d0596ce40d8b6debe;hpb=c0f7f044f3e117660641d0b8b026c7bc4f53163c;p=ardour.git diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 2f69ff2dee..62edaa3911 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -33,17 +33,11 @@ #include #include #include -#include -#include #include -#include #include #ifdef HAVE_SYS_VFS_H #include -#else -#include -#include #endif #ifdef HAVE_SYS_STATVFS_H @@ -51,9 +45,10 @@ #endif #include +#include #include -#include +#include #include @@ -68,12 +63,14 @@ #include "pbd/controllable_descriptor.h" #include "pbd/enumwriter.h" #include "pbd/error.h" +#include "pbd/file_utils.h" +#include "pbd/pathexpand.h" #include "pbd/pathscanner.h" #include "pbd/pthread_utils.h" -#include "pbd/search_path.h" #include "pbd/stacktrace.h" #include "pbd/convert.h" #include "pbd/clear_dir.h" +#include "pbd/localtime_r.h" #include "ardour/amp.h" #include "ardour/audio_diskstream.h" @@ -92,7 +89,6 @@ #include "ardour/midi_region.h" #include "ardour/midi_source.h" #include "ardour/midi_track.h" -#include "ardour/named_selection.h" #include "ardour/pannable.h" #include "ardour/playlist_factory.h" #include "ardour/port.h" @@ -107,7 +103,6 @@ #include "ardour/session_metadata.h" #include "ardour/session_playlists.h" #include "ardour/session_state_utils.h" -#include "ardour/session_utils.h" #include "ardour/silentfilesource.h" #include "ardour/sndfilesource.h" #include "ardour/source_factory.h" @@ -135,14 +130,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) throw failed_constructor(); } - char buf[PATH_MAX+1]; - if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) { - error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg; - destroy (); - throw failed_constructor(); - } - - _path = string(buf); + _path = canonical_path (fullpath); if (_path[_path.length()-1] != G_DIR_SEPARATOR) { _path += G_DIR_SEPARATOR; @@ -207,6 +195,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) _play_range = false; _exporting = false; pending_abort = false; + _adding_routes_in_progress = false; destructive_index = 0; first_file_data_format_reset = true; first_file_header_format_reset = true; @@ -288,7 +277,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) int Session::second_stage_init () { - AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string()); + AudioFileSource::set_peak_dir (_session_dir->peak_path()); if (!_is_new) { if (load_state (_current_snapshot_name)) { @@ -367,6 +356,7 @@ Session::second_stage_init () MIDI::Name::MidiPatchManager::instance().set_session (this); + ltc_tx_initialize(); /* initial program change will be delivered later; see ::config_changed() */ _state_of_the_state = Clean; @@ -392,7 +382,7 @@ Session::raid_path () const SearchPath raid_search_path; for (vector::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) { - raid_search_path += sys::path((*i).path); + raid_search_path += (*i).path; } return raid_search_path.to_string (); @@ -415,7 +405,7 @@ Session::setup_raid_path (string path) SearchPath midi_search_path; for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) { - sp.path = (*i).to_string (); + sp.path = *i; sp.blocks = 0; // not needed session_dirs.push_back (sp); @@ -433,7 +423,7 @@ bool Session::path_is_within_session (const std::string& path) { for (vector::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) { - if (PBD::sys::path_is_within (i->path, path)) { + if (PBD::path_is_within (i->path, path)) { return true; } } @@ -445,35 +435,35 @@ Session::ensure_subdirs () { string dir; - dir = session_directory().peak_path().to_string(); + dir = session_directory().peak_path(); if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; return -1; } - dir = session_directory().sound_path().to_string(); + dir = session_directory().sound_path(); if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; return -1; } - dir = session_directory().midi_path().to_string(); + dir = session_directory().midi_path(); if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; return -1; } - dir = session_directory().dead_path().to_string(); + dir = session_directory().dead_path(); if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; return -1; } - dir = session_directory().export_path().to_string(); + dir = session_directory().export_path(); if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; @@ -519,7 +509,7 @@ Session::create (const string& session_template, BusProfile* bus_profile) return -1; } - _writable = exists_and_writable (sys::path (_path)); + _writable = exists_and_writable (_path); if (!session_template.empty()) { std::string in_path = session_template_dir_to_file (session_template); @@ -538,9 +528,8 @@ Session::create (const string& session_template, BusProfile* bus_profile) _is_new = false; /* Copy plugin state files from template to new session */ - sys::path template_plugins = session_template; - template_plugins /= X_("plugins"); - sys::copy_files (template_plugins, plugins_dir ()); + std::string template_plugins = Glib::build_filename (session_template, X_("plugins")); + copy_files (template_plugins, plugins_dir ()); return 0; @@ -578,7 +567,7 @@ Session::create (const string& session_template, BusProfile* bus_profile) // boost_debug_shared_ptr_mark_interesting (r.get(), "Route"); #endif { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); r->input()->ensure_io (count, false, this); r->output()->ensure_io (count, false, this); } @@ -626,18 +615,15 @@ Session::maybe_write_autosave() void Session::remove_pending_capture_state () { - sys::path pending_state_file_path(_session_dir->root_path()); + std::string pending_state_file_path(_session_dir->root_path()); - pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix; + pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix); - try - { - sys::remove (pending_state_file_path); - } - catch(sys::filesystem_error& ex) - { - error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"), - pending_state_file_path.to_string(), ex.what()) << endmsg; + if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return; + + if (g_remove (pending_state_file_path.c_str()) != 0) { + error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"), + pending_state_file_path, g_strerror (errno)) << endmsg; } } @@ -656,17 +642,12 @@ Session::rename_state (string old_name, string new_name) const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix; const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix; - const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename; - const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename; + const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename)); + const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename)); - try - { - sys::rename (old_xml_path, new_xml_path); - } - catch (const sys::filesystem_error& err) - { + if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) { error << string_compose(_("could not rename snapshot %1 to %2 (%3)"), - old_name, new_name, err.what()) << endmsg; + old_name, new_name, g_strerror(errno)) << endmsg; } } @@ -681,9 +662,9 @@ Session::remove_state (string snapshot_name) return; } - sys::path xml_path(_session_dir->root_path()); + std::string xml_path(_session_dir->root_path()); - xml_path /= legalize_for_path (snapshot_name) + statefile_suffix; + xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix); if (!create_backup_file (xml_path)) { // don't remove it if a backup can't be made @@ -692,14 +673,17 @@ Session::remove_state (string snapshot_name) } // and delete it - sys::remove (xml_path); + if (g_remove (xml_path.c_str()) != 0) { + error << string_compose(_("Could not remove session file at path \"%1\" (%2)"), + xml_path, g_strerror (errno)) << endmsg; + } } #ifdef HAVE_JACK_SESSION void Session::jack_session_event (jack_session_event_t * event) { - char timebuf[128]; + char timebuf[128], *tmp; time_t n; struct tm local_time; @@ -707,6 +691,8 @@ Session::jack_session_event (jack_session_event_t * event) localtime_r (&n, &local_time); strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time); + while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; } + if (event->type == JackSessionSaveTemplate) { if (save_template( timebuf )) { @@ -725,13 +711,14 @@ Session::jack_session_event (jack_session_event_t * event) if (save_state (timebuf)) { event->flags = JackSessionSaveError; } else { - sys::path xml_path (_session_dir->root_path()); - xml_path /= legalize_for_path (timebuf) + statefile_suffix; + std::string xml_path (_session_dir->root_path()); + std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix; + xml_path = Glib::build_filename (xml_path, legalized_filename); string cmd ("ardour3 -P -U "); cmd += event->client_uuid; cmd += " \""; - cmd += xml_path.to_string(); + cmd += xml_path; cmd += '\"'; event->command_line = strdup (cmd.c_str()); @@ -753,7 +740,7 @@ int Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot) { XMLTree tree; - sys::path xml_path(_session_dir->root_path()); + std::string xml_path(_session_dir->root_path()); if (!_writable || (_state_of_the_state & CannotSave)) { return 1; @@ -776,6 +763,8 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot } } + SaveSession (); /* EMIT SIGNAL */ + tree.set_root (&get_state()); if (snapshot_name.empty()) { @@ -788,11 +777,11 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot /* proper save: use statefile_suffix (.ardour in English) */ - xml_path /= legalize_for_path (snapshot_name) + statefile_suffix; + xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix); /* make a backup copy of the old file */ - if (sys::exists(xml_path) && !create_backup_file (xml_path)) { + if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) { // create_backup_file will log the error return -1; } @@ -800,26 +789,31 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot } else { /* pending save: use pending_suffix (.pending in English) */ - xml_path /= legalize_for_path (snapshot_name) + pending_suffix; + xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix); } - sys::path tmp_path(_session_dir->root_path()); + std::string tmp_path(_session_dir->root_path()); + tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix); - tmp_path /= legalize_for_path (snapshot_name) + temp_suffix; + // cerr << "actually writing state to " << xml_path << endl; - // cerr << "actually writing state to " << xml_path.to_string() << endl; - - if (!tree.write (tmp_path.to_string())) { - error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg; - sys::remove (tmp_path); + if (!tree.write (tmp_path)) { + error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg; + if (g_remove (tmp_path.c_str()) != 0) { + error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"), + tmp_path, g_strerror (errno)) << endmsg; + } return -1; } else { - if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) { - error << string_compose (_("could not rename temporary session file %1 to %2"), - tmp_path.to_string(), xml_path.to_string()) << endmsg; - sys::remove (tmp_path); + if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) { + error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"), + tmp_path, xml_path, g_strerror(errno)) << endmsg; + if (g_remove (tmp_path.c_str()) != 0) { + error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"), + tmp_path, g_strerror (errno)) << endmsg; + } return -1; } } @@ -862,10 +856,10 @@ Session::load_state (string snapshot_name) /* check for leftover pending state from a crashed capture attempt */ - sys::path xmlpath(_session_dir->root_path()); - xmlpath /= legalize_for_path (snapshot_name) + pending_suffix; + std::string xmlpath(_session_dir->root_path()); + xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix); - if (sys::exists (xmlpath)) { + if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) { /* there is pending state from a crashed capture attempt */ @@ -876,15 +870,13 @@ Session::load_state (string snapshot_name) } if (!state_was_pending) { - xmlpath = _session_dir->root_path(); - xmlpath /= snapshot_name; + xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name); } - if (!sys::exists (xmlpath)) { - xmlpath = _session_dir->root_path(); - xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix; - if (!sys::exists (xmlpath)) { - error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg; + if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) { + xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix); + if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) { + error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg; return 1; } } @@ -895,8 +887,8 @@ Session::load_state (string snapshot_name) _writable = exists_and_writable (xmlpath); - if (!state_tree->read (xmlpath.to_string())) { - error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg; + if (!state_tree->read (xmlpath)) { + error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg; delete state_tree; state_tree = 0; return -1; @@ -905,7 +897,7 @@ Session::load_state (string snapshot_name) XMLNode& root (*state_tree->root()); if (root.name() != X_("Session")) { - error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg; + error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg; delete state_tree; state_tree = 0; return -1; @@ -929,28 +921,19 @@ Session::load_state (string snapshot_name) } } - if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) { + if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) { - sys::path backup_path(_session_dir->root_path()); - - backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix); + std::string backup_path(_session_dir->root_path()); + std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix); + backup_path = Glib::build_filename (backup_path, backup_filename); // only create a backup for a given statefile version once - if (!sys::exists (backup_path)) { + if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) { - info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"), - xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME) - << endmsg; + VersionMismatch (xmlpath, backup_path); - try { - sys::copy_file (xmlpath, backup_path); - - } catch (sys::filesystem_error& ex) { - - error << string_compose (_("Unable to make backup of state file %1 (%2)"), - xmlpath.to_string(), ex.what()) - << endmsg; + if (!copy_file (xmlpath, backup_path)) {; return -1; } } @@ -1053,7 +1036,7 @@ Session::state (bool full_state) child = node->add_child ("Sources"); if (full_state) { - Glib::Mutex::Lock sl (source_lock); + Glib::Threads::Mutex::Lock sl (source_lock); for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) { @@ -1080,13 +1063,17 @@ Session::state (bool full_state) child = node->add_child ("Regions"); if (full_state) { - Glib::Mutex::Lock rl (region_lock); + Glib::Threads::Mutex::Lock rl (region_lock); const RegionFactory::RegionMap& region_map (RegionFactory::all_regions()); for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) { boost::shared_ptr r = i->second; /* only store regions not attached to playlists */ if (r->playlist() == 0) { - child->add_child_nocopy (r->state ()); + if (boost::dynamic_pointer_cast(r)) { + child->add_child_nocopy ((boost::dynamic_pointer_cast(r))->get_basic_state ()); + } else { + child->add_child_nocopy (r->get_state ()); + } } } @@ -1145,7 +1132,7 @@ Session::state (bool full_state) } for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) { - if (!(*i)->is_hidden()) { + if (!(*i)->is_auditioner()) { if (full_state) { child->add_child_nocopy ((*i)->get_state()); } else { @@ -1168,13 +1155,14 @@ Session::state (bool full_state) gain_child->add_child_nocopy (_click_gain->state (full_state)); } - if (full_state) { - XMLNode* ns_child = node->add_child ("NamedSelections"); - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) { - if (full_state) { - ns_child->add_child_nocopy ((*i)->get_state()); - } - } + if (_ltc_input) { + XMLNode* ltc_input_child = node->add_child ("LTC-In"); + ltc_input_child->add_child_nocopy (_ltc_input->state (full_state)); + } + + if (_ltc_input) { + XMLNode* ltc_output_child = node->add_child ("LTC-Out"); + ltc_output_child->add_child_nocopy (_ltc_output->state (full_state)); } node->add_child_nocopy (_speakers->get_state()); @@ -1226,7 +1214,7 @@ Session::set_state (const XMLNode& node, int version) } } - setup_raid_path(_session_dir->root_path().to_string()); + setup_raid_path(_session_dir->root_path()); if ((prop = node.property (X_("id-counter"))) != 0) { uint64_t x; @@ -1336,12 +1324,6 @@ Session::set_state (const XMLNode& node, int version) } } - if ((child = find_named_node (node, "NamedSelections")) != 0) { - if (load_named_selections (*child)) { - goto out; - } - } - if (version >= 3000) { if ((child = find_named_node (node, "Bundles")) == 0) { warning << _("Session: XML state has no bundles section") << endmsg; @@ -1411,8 +1393,8 @@ Session::set_state (const XMLNode& node, int version) } } - if ((child = find_named_node (node, "ControlProtocols")) != 0) { - ControlProtocolManager::instance().set_protocol_states (*child); + if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) { + ControlProtocolManager::instance().set_state (*child, version); } update_have_rec_enabled_track (); @@ -1672,7 +1654,7 @@ Session::load_nested_sources (const XMLNode& node) XMLProperty* prop = (*niter)->property (X_("id")); if (!prop) { - error << _("Nested source has no ID info in session state file! (ignored)") << endmsg; + error << _("Nested source has no ID info in session file! (ignored)") << endmsg; continue; } @@ -1904,7 +1886,7 @@ Session::get_sources_as_xml () { XMLNode* node = new XMLNode (X_("Sources")); - Glib::Mutex::Lock lm (source_lock); + Glib::Threads::Mutex::Lock lm (source_lock); for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) { node->add_child_nocopy (i->second->get_state()); @@ -1919,7 +1901,7 @@ Session::path_from_region_name (DataType type, string name, string identifier) char buf[PATH_MAX+1]; uint32_t n; SessionDirectory sdir(get_best_session_directory_for_new_source()); - sys::path source_dir = ((type == DataType::AUDIO) + std::string source_dir = ((type == DataType::AUDIO) ? sdir.sound_path() : sdir.midi_path()); string ext = native_header_format_extension (config.get_native_file_header_format(), type); @@ -1933,10 +1915,10 @@ Session::path_from_region_name (DataType type, string name, string identifier) n, ext.c_str()); } - sys::path source_path = source_dir / buf; + std::string source_path = Glib::build_filename (source_dir, buf); - if (!sys::exists (source_path)) { - return source_path.to_string(); + if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) { + return source_path; } } @@ -2034,49 +2016,54 @@ Session::save_template (string template_name) return -1; } - sys::path user_template_dir(user_template_directory()); + std::string user_template_dir(user_template_directory()); - try - { - sys::create_directories (user_template_dir); - } - catch(sys::filesystem_error& ex) - { + 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.to_string(), ex.what()) << endmsg; + user_template_dir, g_strerror (errno)) << endmsg; return -1; } tree.set_root (&get_template()); - sys::path template_dir_path(user_template_dir); + std::string template_dir_path(user_template_dir); /* directory to put the template in */ - template_dir_path /= template_name; - if (sys::exists (template_dir_path)) - { + template_dir_path = Glib::build_filename (template_dir_path, template_name); + + 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.to_string()) << endmsg; + template_dir_path) << endmsg; return -1; } - sys::create_directories (template_dir_path); + 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 */ - sys::path template_file_path = template_dir_path; - template_file_path /= template_name + template_suffix; + std::string template_file_path(template_dir_path); + template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix); - if (!tree.write (template_file_path.to_string())) { + if (!tree.write (template_file_path)) { error << _("template not saved") << endmsg; return -1; } /* copy plugin state directory */ - sys::path template_plugin_state_path = template_dir_path; - template_plugin_state_path /= X_("plugins"); - sys::create_directories (template_plugin_state_path); - sys::copy_files (plugins_dir(), template_plugin_state_path); + std::string template_plugin_state_path(template_dir_path); + template_plugin_state_path = Glib::build_filename (template_plugin_state_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; + } + + copy_files (plugins_dir(), template_plugin_state_path); return 0; } @@ -2084,9 +2071,9 @@ Session::save_template (string template_name) void Session::refresh_disk_space () { -#if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H +#if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H) - Glib::Mutex::Lock lm (space_lock); + Glib::Threads::Mutex::Lock lm (space_lock); /* get freespace on every FS that is part of the session path */ @@ -2134,7 +2121,7 @@ string Session::get_best_session_directory_for_new_source () { vector::iterator i; - string result = _session_dir->root_path().to_string(); + string result = _session_dir->root_path(); /* handle common case without system calls */ @@ -2193,7 +2180,8 @@ Session::get_best_session_directory_for_new_source () } if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) { - if (create_session_directory ((*i).path)) { + SessionDirectory sdir(i->path); + if (sdir.create ()) { result = (*i).path; last_rr_session_dir = i; return result; @@ -2215,7 +2203,8 @@ Session::get_best_session_directory_for_new_source () sort (sorted.begin(), sorted.end(), cmp); for (i = sorted.begin(); i != sorted.end(); ++i) { - if (create_session_directory ((*i).path)) { + SessionDirectory sdir(i->path); + if (sdir.create ()) { result = (*i).path; last_rr_session_dir = i; return result; @@ -2226,39 +2215,6 @@ Session::get_best_session_directory_for_new_source () return result; } -int -Session::load_named_selections (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - NamedSelection *ns; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((ns = XMLNamedSelectionFactory (**niter)) == 0) { - error << _("Session: cannot create Named Selection from XML description.") << endmsg; - } - } - - return 0; -} - -NamedSelection * -Session::XMLNamedSelectionFactory (const XMLNode& node) -{ - try { - return new NamedSelection (*this, node); - } - - catch (failed_constructor& err) { - return 0; - } -} - string Session::automation_dir () const { @@ -2297,7 +2253,7 @@ Session::load_bundles (XMLNode const & node) } else if ((*niter)->name() == "OutputBundle") { add_bundle (boost::shared_ptr (new UserBundle (**niter, false))); } else { - error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg; + error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg; return -1; } } @@ -2624,7 +2580,7 @@ Session::find_all_sources_across_snapshots (set& result, bool exclude_th ripped = ripped.substr (0, ripped.length() - 1); } - state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true); + state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true); if (state_files == 0) { /* impossible! */ @@ -2703,6 +2659,8 @@ Session::cleanup_sources (CleanupReport& rep) bool used; string spath; int ret = -1; + string tmppath1; + string tmppath2; _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup); @@ -2750,7 +2708,7 @@ Session::cleanup_sources (CleanupReport& rep) ++nexti; SessionDirectory sdir ((*i).path); - audio_path += sdir.sound_path().to_string(); + audio_path += sdir.sound_path(); if (nexti != session_dirs.end()) { audio_path += ':'; @@ -2768,7 +2726,7 @@ Session::cleanup_sources (CleanupReport& rep) ++nexti; SessionDirectory sdir ((*i).path); - midi_path += sdir.midi_path().to_string(); + midi_path += sdir.midi_path(); if (nexti != session_dirs.end()) { midi_path += ':'; @@ -2827,9 +2785,6 @@ Session::cleanup_sources (CleanupReport& rep) i = tmp; } - char tmppath1[PATH_MAX+1]; - char tmppath2[PATH_MAX+1]; - if (candidates) { for (vector::iterator x = candidates->begin(); x != candidates->end(); ++x) { @@ -2838,19 +2793,10 @@ Session::cleanup_sources (CleanupReport& rep) for (set::iterator i = all_sources.begin(); i != all_sources.end(); ++i) { - if (realpath(spath.c_str(), tmppath1) == 0) { - error << string_compose (_("Cannot expand path %1 (%2)"), - spath, strerror (errno)) << endmsg; - continue; - } + tmppath1 = canonical_path (spath); + tmppath2 = canonical_path ((*i)); - if (realpath((*i).c_str(), tmppath2) == 0) { - error << string_compose (_("Cannot expand path %1 (%2)"), - (*i), strerror (errno)) << endmsg; - continue; - } - - if (strcmp(tmppath1, tmppath2) == 0) { + if (tmppath1 == tmppath2) { used = true; break; } @@ -2954,7 +2900,7 @@ Session::cleanup_sources (CleanupReport& rep) string peakpath = peak_path (base); if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) { - if (::unlink (peakpath.c_str()) != 0) { + if (::g_unlink (peakpath.c_str()) != 0) { error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), peakpath, _path, strerror (errno)) << endmsg; @@ -3054,7 +3000,7 @@ Session::add_controllable (boost::shared_ptr c) as part of the session. */ - Glib::Mutex::Lock lm (controllables_lock); + Glib::Threads::Mutex::Lock lm (controllables_lock); controllables.insert (c); } @@ -3067,7 +3013,7 @@ Session::remove_controllable (Controllable* c) return; } - Glib::Mutex::Lock lm (controllables_lock); + Glib::Threads::Mutex::Lock lm (controllables_lock); Controllables::iterator x = controllables.find (boost::shared_ptr(c, null_deleter())); @@ -3079,7 +3025,7 @@ Session::remove_controllable (Controllable* c) boost::shared_ptr Session::controllable_by_id (const PBD::ID& id) { - Glib::Mutex::Lock lm (controllables_lock); + Glib::Threads::Mutex::Lock lm (controllables_lock); for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) { if ((*i)->id() == id) { @@ -3203,7 +3149,7 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc) if (p) { boost::shared_ptr s = boost::dynamic_pointer_cast(p); boost::shared_ptr a = s->amp(); - + if (a) { c = s->amp()->gain_control(); } @@ -3252,16 +3198,11 @@ Session::save_history (string snapshot_name) const string history_filename = legalize_for_path (snapshot_name) + history_suffix; const string backup_filename = history_filename + backup_suffix; - const sys::path xml_path = _session_dir->root_path() / history_filename; - const sys::path backup_path = _session_dir->root_path() / backup_filename; + const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename)); + const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename)); - if (sys::exists (xml_path)) { - try - { - sys::rename (xml_path, backup_path); - } - catch (const sys::filesystem_error& err) - { + if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) { + if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) { error << _("could not backup old history file, current history not saved") << endmsg; return -1; } @@ -3273,19 +3214,17 @@ Session::save_history (string snapshot_name) tree.set_root (&_history.get_state (Config->get_saved_history_depth())); - if (!tree.write (xml_path.to_string())) + if (!tree.write (xml_path)) { - error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg; + error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg; - try - { - sys::remove (xml_path); - sys::rename (backup_path, xml_path); + if (g_remove (xml_path.c_str()) != 0) { + error << string_compose(_("Could not remove history file at path \"%1\" (%2)"), + xml_path, g_strerror (errno)) << endmsg; } - catch (const sys::filesystem_error& err) - { + if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) { error << string_compose (_("could not restore history file from backup %1 (%2)"), - backup_path.to_string(), err.what()) << endmsg; + backup_path, g_strerror (errno)) << endmsg; } return -1; @@ -3303,20 +3242,20 @@ Session::restore_history (string snapshot_name) snapshot_name = _current_snapshot_name; } - const string xml_filename = legalize_for_path (snapshot_name) + history_suffix; - const sys::path xml_path = _session_dir->root_path() / xml_filename; + const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix; + const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename)); - info << "Loading history from " << xml_path.to_string() << endmsg; + info << "Loading history from " << xml_path << endmsg; - if (!sys::exists (xml_path)) { + if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) { info << string_compose (_("%1: no history file \"%2\" for this session."), - _name, xml_path.to_string()) << endmsg; + _name, xml_path) << endmsg; return 1; } - if (!tree.read (xml_path.to_string())) { + if (!tree.read (xml_path)) { error << string_compose (_("Could not understand session history file \"%1\""), - xml_path.to_string()) << endmsg; + xml_path) << endmsg; return -1; } @@ -3445,7 +3384,7 @@ Session::config_changed (std::string p, bool ours) } else if (p == "edit-mode") { - Glib::Mutex::Lock lm (playlists->lock); + Glib::Threads::Mutex::Lock lm (playlists->lock); for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) { (*i)->set_edit_mode (Config->get_edit_mode ()); @@ -3558,16 +3497,32 @@ Session::config_changed (std::string p, bool ours) if (!config.get_external_sync()) { drop_sync_source (); } else { - switch_to_sync_source (config.get_sync_source()); + switch_to_sync_source (Config->get_sync_source()); } - } else if (p == "remote-model") { - set_remote_control_ids (); } else if (p == "denormal-model") { setup_fpu (); } else if (p == "history-depth") { set_history_depth (Config->get_history_depth()); + } else if (p == "remote-model") { + /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED + TO SET REMOTE ID'S + */ } else if (p == "sync-all-route-ordering") { - sync_order_keys ("session"); + + /* sync to editor order unless mixer is used for remote IDs + */ + + switch (Config->get_remote_model()) { + case UserOrdered: + sync_order_keys (EditorSort); + break; + case EditorOrdered: + sync_order_keys (EditorSort); + break; + case MixerOrdered: + sync_order_keys (MixerSort); + } + } else if (p == "initial-program-change") { if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) { @@ -3590,6 +3545,12 @@ Session::config_changed (std::string p, bool ours) AudioSource::allocate_working_buffers (frame_rate()); } else if (p == "automation-thinning-factor") { Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor()); + } else if (p == "ltc-source-port") { + reconnect_ltc_input (); + } else if (p == "ltc-sink-port") { + reconnect_ltc_output (); + } else if (p == "timecode-generator-offset") { + ltc_tx_parse_offset(); } set_dirty (); @@ -3681,7 +3642,7 @@ Session::rename (const std::string& new_name) string newstr; bool first = true; - string const old_sources_root = _session_dir->sources_root().to_string (); + string const old_sources_root = _session_dir->sources_root(); #define RENAME ::rename @@ -3810,7 +3771,7 @@ Session::rename (const std::string& new_name) boost::shared_ptr fs = boost::dynamic_pointer_cast (i->second); if (fs) { string p = fs->path (); - boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ()); + boost::replace_all (p, old_sources_root, _session_dir->sources_root()); fs->set_path (p); } }