37 #include <glibmm/miscutils.h>
38 #include <glibmm/fileutils.h>
39 #include <glibmm/threads.h>
45 #include "ardour/utils.h"
54 PBD::Signal2<int,std::string,std::vector<std::string> > FileSource::AmbiguousFileName;
57 :
Source(session, type, path, flag)
59 , _file_is_new (!origin.empty())
63 set_within_session_from_path (path);
68 , _file_is_new (false)
87 if (Glib::file_test (
_path, Glib::FILE_TEST_EXISTS)) {
132 if (!Glib::file_test (
_path, Glib::FILE_TEST_EXISTS)) {
145 if ((prop = node.
property (
X_(
"channel"))) != 0) {
151 if ((prop = node.
property (
X_(
"origin"))) != 0) {
178 v.push_back (Glib::path_get_dirname (Glib::path_get_dirname (
_path)));
179 v.push_back (trash_dir_name);
180 v.push_back (Glib::path_get_basename (
_path));
182 string newpath = Glib::build_filename (v);
186 if (Glib::file_test (newpath.c_str(), Glib::FILE_TEST_EXISTS)) {
191 snprintf (buf,
sizeof (buf),
"%s.%d", newpath.c_str(), version);
194 while (Glib::file_test (newpath_v, Glib::FILE_TEST_EXISTS) && version < 999) {
195 snprintf (buf,
sizeof (buf),
"%s.%d", newpath.c_str(), ++version);
199 if (version == 999) {
201 _(
"there are already 1000 files with names like %1; versioning discontinued"),
208 if (::
rename (
_path.c_str(), newpath.c_str()) != 0) {
210 _(
"cannot rename file source from %1 to %2 (%3)"),
238 bool& isnew, uint16_t& ,
string& found_path)
245 if (!Glib::path_is_absolute (path)) {
250 if (dirs.size() == 0) {
251 error <<
_(
"FileSource: search path not set") <<
endmsg;
255 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
257 fullpath = Glib::build_filename (*i, path);
259 if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
261 hits.push_back (fullpath);
271 vector<string> de_duped_hits;
273 for (vector<string>::iterator i = hits.begin(); i != hits.end(); ++i) {
275 vector<string>::iterator j = i;
278 while (j != hits.end()) {
287 if (j == hits.end ()) {
288 de_duped_hits.push_back (*i);
292 if (de_duped_hits.size() > 1) {
301 keeppath = de_duped_hits[which];
304 }
else if (de_duped_hits.size() == 0) {
320 keeppath = de_duped_hits[0];
331 if (keeppath.empty()) {
333 error <<
"FileSource::find(), keeppath = \"\", but the file must exist" << endl;
339 found_path = keeppath;
355 bool& isnew, uint16_t& chan,
string& found_path)
357 string pathstr =
path;
358 string::size_type pos;
363 if (!Glib::path_is_absolute (pathstr)) {
373 if (dirs.size() == 0) {
374 error <<
_(
"FileSource: search path not set") <<
endmsg;
380 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
382 fullpath = Glib::build_filename (*i, pathstr);
388 if ((pos = pathstr.find_last_of (
':')) != string::npos) {
390 if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
405 string shorter = pathstr.substr (0, pos);
406 fullpath = Glib::build_filename (*i, shorter);
408 if (Glib::file_test (pathstr, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
409 chan =
atoi (pathstr.substr (pos+1));
424 if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
434 _(
"FileSource: \"%1\" is ambigous when searching\n\t"), pathstr) <<
endmsg;
437 }
else if (cnt == 0) {
441 _(
"Filesource: cannot find required file (%1)"), pathstr) <<
endmsg;
450 if (keeppath ==
"") {
452 error <<
"FileSource::find(), keeppath = \"\", but the file must exist" << endl;
458 found_path = keeppath;
468 if ((pos = pathstr.find_last_of (
':')) != string::npos) {
470 string shorter = pathstr.substr (0, pos);
472 if (Glib::file_test (shorter, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
473 chan =
atoi (pathstr.substr (pos+1));
478 found_path = pathstr;
480 if (!Glib::file_test (pathstr, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
486 _(
"Filesource: cannot find required file (%1): %2"),
487 path, strerror (errno)) <<
endmsg;
491 #ifndef PLATFORM_WINDOWS
492 if (errno != ENOENT) {
494 _(
"Filesource: cannot check for existing file (%1): %2"),
495 path, strerror (errno)) <<
endmsg;
551 _origin = Glib::path_get_basename (newpath);
574 if (Glib::file_test (
_path, Glib::FILE_TEST_EXISTS)) {
585 string oldpath =
_path;
588 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
589 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;
593 if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) {
595 if (::
rename (oldpath.c_str(), newpath.c_str()) != 0) {
601 _name = Glib::path_get_basename (newpath);
ARDOUR::Session & _session
int atoi(const string &s)
virtual void prevent_deletion()
const std::string & value() const
static PBD::Signal2< int, std::string, std::vector< std::string > > AmbiguousFileName
virtual void inc_use_count()
void mark_immutable_except_write()
int rename(const std::string &name)
int move_to_trash(const std::string &trash_dir_name)
LIBPBD_API Transmitter error
framepos_t _timeline_position
std::ostream & endmsg(std::ostream &ostr)
virtual bool empty() const =0
bool path_is_within_session(const std::string &)
bool within_session() const
static bool find_2X(Session &, DataType type, const std::string &path, bool must_exist, bool &is_new, uint16_t &chan, std::string &found_path)
FileSource(Session &session, DataType type, const std::string &path, const std::string &origin, Source::Flag flags=Source::Flag(0))
XMLProperty * property(const char *)
int set_state(const XMLNode &, int version)
const PBD::ID & id() const
void mark_take(const std::string &id)
static int loading_state_version
PBD::Property< std::string > _name
virtual int init(const std::string &idstr, bool must_exist)
virtual int move_dependents_to_trash()
const std::string & path() const
std::vector< std::string > source_search_path(DataType) const
static bool find(Session &, DataType type, const std::string &path, bool must_exist, bool &is_new, uint16_t &chan, std::string &found_path)
virtual void set_path(const std::string &)
bool equivalent_paths(const std::string &a, const std::string &b)
Glib::Threads::Mutex _lock
void set_within_session_from_path(const std::string &)
std::string string_compose(const std::string &fmt, const T1 &o1)