X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ffile_source.cc;h=6ebbf0b52396f783e39eb01a8cfa59dad3e50f96;hb=1e424e11460812262df89c08c6af521a935760cf;hp=ed9c80338abeb30724e6cf0d90972a4dbe7b5cca;hpb=022818b4a796f52c0a91eea42e65aec0bc7bed43;p=ardour.git diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index ed9c80338a..6ebbf0b523 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2006-2009 Paul Davis + Copyright (C) 2006-2009 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,26 +26,27 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include "pbd/convert.h" +#include "pbd/basename.h" +#include "pbd/mountpoint.h" +#include "pbd/stl_delete.h" +#include "pbd/strsplit.h" +#include "pbd/shortpath.h" +#include "pbd/enumwriter.h" #include #include #include -#include -#include -#include -#include -#include +#include "ardour/file_source.h" +#include "ardour/session.h" +#include "ardour/session_directory.h" +#include "ardour/source_factory.h" +#include "ardour/filename_extensions.h" #include "i18n.h" +using namespace std; using namespace ARDOUR; using namespace PBD; using namespace Glib; @@ -64,9 +65,9 @@ FileSource::FileSource (Session& session, DataType type, { } -FileSource::FileSource (Session& session, const XMLNode& node, bool must_exist) +FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/) : Source(session, node) - , _file_is_new(false) + , _file_is_new (false) { _path = _name; _is_embedded = (_path.find(PATH_SEP) != string::npos); @@ -76,29 +77,34 @@ bool FileSource::removable () const { return (_flags & Removable) - && ( (_flags & RemoveAtDestroy) - || ((_flags & RemovableIfEmpty) && length() == 0)); + && ((_flags & RemoveAtDestroy) || + ((_flags & RemovableIfEmpty) && length(timeline_position()) == 0)); } int FileSource::init (const ustring& pathstr, bool must_exist) { - _length = 0; _timeline_position = 0; - if (!find (_type, pathstr, must_exist, _file_is_new, _channel)) { + if (!find (_type, pathstr, must_exist, _file_is_new, _channel, _path)) { throw MissingSource (); } + /* XXX is this necessary? or even wise? */ + + if (_is_embedded) { + _name = Glib::path_get_basename (_name); + } + if (_file_is_new && must_exist) { return -1; } - + return 0; } int -FileSource::set_state (const XMLNode& node) +FileSource::set_state (const XMLNode& node, int /*version*/) { const XMLProperty* prop; @@ -136,10 +142,10 @@ FileSource::move_to_trash (const ustring& trash_dir_name) /* don't move the file across filesystems, just stick it in the trash_dir_name directory on whichever filesystem it was already on */ - + ustring newpath; newpath = Glib::path_get_dirname (_path); - newpath = Glib::path_get_dirname (newpath); + newpath = Glib::path_get_dirname (newpath); newpath += string(PATH_SEP) + trash_dir_name + PATH_SEP; newpath += Glib::path_get_basename (_path); @@ -157,7 +163,7 @@ FileSource::move_to_trash (const ustring& trash_dir_name) snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version); newpath_v = buf; } - + if (version == 999) { PBD::error << string_compose ( _("there are already 1000 files with names like %1; versioning discontinued"), @@ -179,24 +185,25 @@ FileSource::move_to_trash (const ustring& trash_dir_name) rename (newpath.c_str(), _path.c_str()); return -1; } - + _path = newpath; - + /* file can not be removed twice, since the operation is not idempotent */ _flags = Flag (_flags & ~(RemoveAtDestroy|Removable|RemovableIfEmpty)); return 0; } -/** Find the actual source file based on \a path. - * - * If the source is embedded, \a path should be a filename (no slashes). - * If the source is external, \a path should be a full path. - * In either case, _path is set to the complete absolute path of the source file. +/** Find the actual source file based on \a filename. + * + * If the source is embedded, \a filename should be a simple filename (no slashes). + * If the source is external, \a filename should be a full path. + * In either case, found_path is set to the complete absolute path of the source file. * \return true iff the file was found. */ bool -FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isnew, uint16_t& chan) +FileSource::find (DataType type, const ustring& path, bool must_exist, + bool& isnew, uint16_t& chan, ustring& found_path) { Glib::ustring search_path = search_paths[type]; @@ -223,7 +230,7 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn split (search_path, dirs, ':'); cnt = 0; - + for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { fullpath = *i; if (fullpath[fullpath.length()-1] != '/') { @@ -235,24 +242,24 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn /* i (paul) made a nasty design error by using ':' as a special character in Ardour 0.99 .. this hack tries to make things sort of work. */ - + if ((pos = pathstr.find_last_of (':')) != ustring::npos) { - + if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { /* its a real file, no problem */ - + keeppath = fullpath; ++cnt; } else { - + if (must_exist) { - + /* might be an older session using file:channel syntax. see if the version without the :suffix exists */ - + ustring shorter = pathstr.substr (0, pos); fullpath = *i; @@ -267,12 +274,12 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn pathstr = shorter; keeppath = fullpath; ++cnt; - } - + } + } else { - + /* new derived file (e.g. for timefx) being created in a newer session */ - + } } @@ -281,7 +288,7 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { keeppath = fullpath; ++cnt; - } + } } } @@ -314,18 +321,18 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn } } - _path = keeppath; - + found_path = keeppath; + ret = true; } else { - + /* external files and/or very very old style sessions include full paths */ /* ugh, handle ':' situation */ if ((pos = pathstr.find_last_of (':')) != ustring::npos) { - + ustring shorter = pathstr.substr (0, pos); if (Glib::file_test (shorter, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { @@ -333,42 +340,38 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn pathstr = shorter; } } - - _path = pathstr; + + found_path = pathstr; if (!Glib::file_test (pathstr, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { /* file does not exist or we cannot read it */ - + if (must_exist) { error << string_compose( _("Filesource: cannot find required file (%1): %2"), - _path, strerror (errno)) << endmsg; + path, strerror (errno)) << endmsg; goto out; } - + if (errno != ENOENT) { error << string_compose( _("Filesource: cannot check for existing file (%1): %2"), - _path, strerror (errno)) << endmsg; + path, strerror (errno)) << endmsg; goto out; } - + /* a new file */ isnew = true; ret = true; } else { - + /* already exists */ ret = true; } } - - if (_is_embedded) { - _name = Glib::path_get_basename (_name); - } - + out: return ret; } @@ -379,13 +382,13 @@ FileSource::set_source_name (const ustring& newname, bool destructive) Glib::Mutex::Lock lm (_lock); ustring oldpath = _path; ustring newpath = Session::change_source_path_by_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. + // Test whether newpath exists, if yes notify the user but continue. if (access(newpath.c_str(),F_OK) == 0) { error << _("Programming error! Ardour tried to rename a file over another file! It's safe to continue working, but please report this to the developers.") << endmsg; return -1;