From: Paul Davis Date: Sun, 13 Apr 2014 15:12:22 +0000 (-0400) Subject: further code simplification and rationalization related to MIDI source/file renaming X-Git-Tag: 4.0-rc1~1601^2~1345 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=b81d57f0495e7c5866fcd49e5c9c6483227966c2;p=ardour.git further code simplification and rationalization related to MIDI source/file renaming --- diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index ecb47a102a..20feb27001 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -194,8 +194,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop std::string peak_path (std::string) const; - std::string generate_new_source_path_from_name (std::string oldpath, std::string oldname, std::string newname, bool destructive); - std::string peak_path_from_audio_path (std::string) const; std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive); std::string new_midi_source_name (const std::string&); diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h index 193330ef36..9d85f94352 100644 --- a/libs/ardour/ardour/smf_source.h +++ b/libs/ardour/ardour/smf_source.h @@ -45,6 +45,15 @@ public: virtual ~SMFSource (); + /** Rename the file on disk referenced by this source to \param newname + * + * This method exists only for MIDI file sources, not for audio, which + * can never be renamed. It exists for MIDI so that we can get + * consistent and sane region/source numbering when regions are added + * manually (which never happens with audio). + */ + int rename (const std::string& name); + bool safe_file_extension (const std::string& path) const { return safe_midi_file_extension(path); } diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index 6dc6ad9500..709915378d 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -515,38 +515,6 @@ out: return ret; } -int -FileSource::set_source_name (const string& newname, bool destructive) -{ - Glib::Threads::Mutex::Lock lm (_lock); - string oldpath = _path; - string newpath = _session.generate_new_source_path_from_name (oldpath, _name, newname, destructive); - - if (newpath.empty()) { - error << string_compose (_("programming error: %1"), "cannot generate a changed file path") << endmsg; - return -1; - } - - // Test whether newpath exists, if yes notify the user but continue. - if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) { - error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg; - return -1; - } - - if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) { - /* rename only needed if file exists on disk */ - if (::rename (oldpath.c_str(), newpath.c_str()) != 0) { - error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg; - return -1; - } - } - - _name = Glib::path_get_basename (newpath); - _path = newpath; - - return 0; -} - void FileSource::mark_immutable () { diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index fdf155d78b..4a878c3898 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -1228,12 +1228,18 @@ MidiDiskstream::steal_write_source_name () /* this will bump the name of the current write source to the next one * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the * current write source name (e.g. "MIDI 1-1" available). See the - * comments in Session::create_midi_source_for_track() about why we do - * this. + * comments in Session::create_midi_source_by_stealing_name() about why + * we do this. */ - if (_write_source->set_source_name (name(), false)) { - return string(); + try { + string new_name = _session.new_midi_source_name (name()); + + if (_write_source->rename (new_name)) { + return string(); + } + } catch (...) { + return string (); } return our_old_name; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 68ea4c3faf..f0672b934e 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3366,112 +3366,6 @@ Session::count_sources_by_origin (const string& path) return cnt; } -string -Session::generate_new_source_path_from_name (string path, string oldname, string newname, bool destructive) -{ - string look_for; - string old_basename = PBD::basename_nosuffix (oldname); - string new_legalized = legalize_for_path (newname); - - /* note: we know (or assume) the old path is already valid */ - - if (destructive) { - - /* destructive file sources have a name of the form: - - /path/to/Tnnnn-NAME(%[LR])?.wav - - the task here is to replace NAME with the new name. - */ - - string dir; - string prefix; - string::size_type dash; - - dir = Glib::path_get_dirname (path); - path = Glib::path_get_basename (path); - - /* '-' is not a legal character for the NAME part of the path */ - - if ((dash = path.find_last_of ('-')) == string::npos) { - return ""; - } - - prefix = path.substr (0, dash); - - path += prefix; - path += '-'; - path += new_legalized; - path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO); - path = Glib::build_filename (dir, path); - - } else { - - /* non-destructive file sources have a name of the form: - - /path/to/NAME-nnnnn(%[LR])?.ext - - the task here is to replace NAME with the new name. - */ - - string dir; - string suffix; - string::size_type dash; - string::size_type postfix; - - dir = Glib::path_get_dirname (path); - path = Glib::path_get_basename (path); - - /* '-' is not a legal character for the NAME part of the path */ - - if ((dash = path.find_last_of ('-')) == string::npos) { - return ""; - } - - suffix = path.substr (dash+1); - - // Suffix is now everything after the dash. Now we need to eliminate - // the nnnnn part, which is done by either finding a '%' or a '.' - - postfix = suffix.find_last_of ("%"); - if (postfix == string::npos) { - postfix = suffix.find_last_of ('.'); - } - - if (postfix != string::npos) { - suffix = suffix.substr (postfix); - } else { - error << "Logic error in Session::change_source_path_by_name(), please report" << endl; - return ""; - } - - const uint32_t limit = 10000; - char buf[PATH_MAX+1]; - - for (uint32_t cnt = 1; cnt <= limit; ++cnt) { - - snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str()); - - if (!matching_unsuffixed_filename_exists_in (dir, buf)) { - path = Glib::build_filename (dir, buf); - if (!source_by_path (path)) { - break; - } - } - - path = ""; - } - - if (path.empty()) { - fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"), - newname) << endl; - /*NOTREACHED*/ - } - } - - return path; -} - /** Return the full path (in some session directory) for a new within-session source. * \a name must be a session-unique name that does not contain slashes * (e.g. as returned by new_*_source_name) diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 62ecab1397..e15bc9a238 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -668,3 +668,35 @@ SMFSource::prevent_deletion () _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); } + +int +SMFSource::rename (const string& newname) +{ + Glib::Threads::Mutex::Lock lm (_lock); + string oldpath = _path; + string newpath = _session.new_source_path_from_name (DataType::MIDI, newname); + + if (newpath.empty()) { + error << string_compose (_("programming error: %1"), "cannot generate a changed file path") << endmsg; + return -1; + } + + // Test whether newpath exists, if yes notify the user but continue. + if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) { + error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg; + return -1; + } + + if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) { + /* rename only needed if file exists on disk */ + if (::rename (oldpath.c_str(), newpath.c_str()) != 0) { + error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg; + return -1; + } + } + + _name = Glib::path_get_basename (newpath); + _path = newpath; + + return 0; +}