summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-02-22 10:38:17 +0100
committerRobin Gareus <robin@gareus.org>2017-02-22 10:51:08 +0100
commitcdc8807728ff57ba3df56aa5a9e00255f9e81b0b (patch)
tree980d63b4e4fa9a475cbe1ec310926548d86da304 /libs
parent75773a43d4ac711ef93c80705c3f38ce0b00c74e (diff)
Prepare re-locating missing external files.
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/session.h6
-rw-r--r--libs/ardour/session_state.cc37
2 files changed, 40 insertions, 3 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index dac899db5c..8ce31630f0 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1145,6 +1145,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
*/
static PBD::Signal3<int,Session*,std::string,DataType> MissingFile;
+ void set_missing_file_replacement (const std::string& mfr) {
+ _missing_file_replacement = mfr;
+ }
+
/** Emitted when the session wants Ardour to quit */
static PBD::Signal0<void> Quit;
@@ -1260,6 +1264,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
bool _under_nsm_control;
unsigned int _xrun_count;
+ std::string _missing_file_replacement;
+
void mtc_status_changed (bool);
PBD::ScopedConnection mtc_status_connection;
void ltc_status_changed (bool);
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 5e63e0c357..0c2fa42073 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -2198,19 +2198,23 @@ Session::load_sources (const XMLNode& node)
nlist = node.children();
set_dirty();
+ std::map<std::string, std::string> relocation;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
#ifdef PLATFORM_WINDOWS
int old_mode = 0;
#endif
+ XMLNode srcnode (**niter);
+ bool try_replace_abspath = true;
+
retry:
try {
#ifdef PLATFORM_WINDOWS
// do not show "insert media" popups (files embedded from removable media).
old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
- if ((source = XMLSourceFactory (**niter)) == 0) {
+ if ((source = XMLSourceFactory (srcnode)) == 0) {
error << _("Session: cannot create Source from XML description.") << endmsg;
}
#ifdef PLATFORM_WINDOWS
@@ -2222,10 +2226,25 @@ retry:
SetErrorMode(old_mode);
#endif
+ /* try previous abs path replacements first */
+ if (try_replace_abspath && Glib::path_is_absolute (err.path)) {
+ std::string dir = Glib::path_get_dirname (err.path);
+ std::map<std::string, std::string>::const_iterator rl = relocation.find (dir);
+ if (rl != relocation.end ()) {
+ std::string newpath = Glib::build_filename (rl->second, Glib::path_get_basename (err.path));
+ if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
+ srcnode.add_property ("origin", newpath);
+ try_replace_abspath = false;
+ goto retry;
+ }
+ }
+ }
+
int user_choice;
+ _missing_file_replacement = "";
if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
- error << string_compose (_("A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
+ error << string_compose (_("An external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
PROGRAM_NAME) << endmsg;
return -1;
}
@@ -2238,7 +2257,19 @@ retry:
switch (user_choice) {
case 0:
- /* user added a new search location, so try again */
+ /* user added a new search location
+ * or selected a new absolute path,
+ * so try again */
+ if (Glib::path_is_absolute (err.path)) {
+ if (!_missing_file_replacement.empty ()) {
+ /* replace origin, in XML */
+ std::string newpath = Glib::build_filename (
+ _missing_file_replacement, Glib::path_get_basename (err.path));
+ srcnode.add_property ("origin", newpath);
+ relocation[Glib::path_get_dirname (err.path)] = _missing_file_replacement;
+ _missing_file_replacement = "";
+ }
+ }
goto retry;