Sorry for opening a new thread, but gmane did already expire the old thread 
in the nntp interface, and I do not keep lyx-devel mails.

The attached patch implements the third option I described in the starting 
message of the original thread:

> - Do not change the paths in general if the files can be found using the
> relative paths. Has the additional benefit that this is also the wanted
> behaviour if I copy a whole directory of LyX files (including referenced
> graphics) to a new location. Disadvantage would be that the machinery does
> now depend on the presence of external files, and it is not guaranteed
> that the file that is found is the correct one.

It does not address Jean-Marcs concerns about the implicit behaviour:

> I really do not like that this /systemlyxdir thing has to be set on
> install by mofiying the file and that this setting is not accessible from
> the GUI. I'd prefer a scheme where the document is explicitly marked as
> lyxdoc and is handled differently depending on whether it is in its
> natural place or not. That would smell less like black magick.

This is something we should think of for a later release IMHO. For 2.2.0, we 
should ensure that /systemlyxdir is already set for all files in the source 
tar ball (at install time it is too late IMHO). It is easy to create a 
script doing that.

The patch does also make improve the behaviour for non-LyX-doc documents 
(imagine a user copying a whole project directory conataining LyX files with 
relative paths inside the project directory). These paths are damaged 
without the patch as well. Therefore it will not be obsolete if we introduce 
an explicit LyX_doc setting later.

I do not like that there are two similar methods Buffer::includedFilePath() 
and Buffer::getReferencedFileName(). All insets should use the same method, 
and the other one should be ditched, but the difference was already there 
before, and changing this now is too dangerous IMHO, so it is something for 
later as well.

OK to go in?


Georg
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index eac9821..b0f9ee9 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -1029,7 +1029,10 @@ bool Buffer::readDocument(Lexer & lex)
 	params().indiceslist().addDefault(B_("Index"));
 
 	// read main text
-	d->old_position = originFilePath();
+	if (FileName::isAbsolute(params().origin))
+		d->old_position = params().origin;
+	else
+		d->old_position = filePath();
 	bool const res = text().read(lex, errorList, d->inset);
 	d->old_position.clear();
 
@@ -3025,12 +3028,21 @@ string Buffer::filePath() const
 }
 
 
-string Buffer::originFilePath() const
+DocFileName Buffer::getReferencedFileName(string const & fn) const
 {
-	if (FileName::isAbsolute(params().origin))
-		return params().origin;
+	DocFileName result;
+	if (FileName::isAbsolute(fn) || !FileName::isAbsolute(params().origin))
+		result.set(fn, filePath());
+	else {
+		// filePath() ends with a path separator
+		FileName const test(filePath() + fn);
+		if (test.exists())
+			result.set(fn, filePath());
+		else
+			result.set(fn, params().origin);
+	}
 
-	return filePath();
+	return result;
 }
 
 
@@ -5067,13 +5079,23 @@ void Buffer::checkMasterBuffer()
 
 string Buffer::includedFilePath(string const & name, string const & ext) const
 {
+	if (d->old_position.empty() ||
+	    equivalent(FileName(d->old_position), FileName(filePath())))
+		return name;
+
 	bool isabsolute = FileName::isAbsolute(name);
-	// old_position already contains a trailing path separator
-	string const absname = isabsolute ? name : d->old_position + name;
+	// both old_position and filePath() end with a path separator
+	string absname = isabsolute ? name : d->old_position + name;
+
+	// if old_position is set to origin, we need to do the equivalent of
+	// getReferencedFileName() (see readDocument())
+	if (!isabsolute && d->old_position == params().origin) {
+		FileName const test(addExtension(filePath() + name, ext));
+		if (test.exists())
+			absname = filePath() + name;
+	}
 
-	if (d->old_position.empty()
-	    || equivalent(FileName(d->old_position), FileName(filePath()))
-	    || !FileName(addExtension(absname, ext)).exists())
+	if (!FileName(addExtension(absname, ext)).exists())
 		return name;
 
 	if (isabsolute)
diff --git a/src/Buffer.h b/src/Buffer.h
index 7450790..3f5ab22 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -66,6 +66,7 @@ class WorkAreaManager;
 }
 
 namespace support {
+class DocFileName;
 class FileName;
 class FileNameList;
 }
@@ -405,12 +406,14 @@ public:
 	/// It is always an absolute path.
 	std::string filePath() const;
 
-	/** Returns the path where the document was last saved.
-	 *  It may be different from filePath() if the document was later
-	 *  manually moved to a different location.
-	 *  It is always an absolute path.
+	/** Contructs a file name of a referenced file (child doc, included graphics etc).
+	 *  Absolute names are returned as is. If the name is relative, it is
+	 *  interpreted relative to filePath() if the file exists, otherwise
+	 *  relative to the original path where the document was last saved.
+	 *  The original path may be different from filePath() if the document was
+	 *  later manually moved to a different location.
 	 */
-	std::string originFilePath() const;
+	support::DocFileName getReferencedFileName(std::string const & fn) const;
 
 	/** Returns the path where a local layout file lives.
 	 *  An empty string is returned for standard system and user layouts.
diff --git a/src/insets/InsetExternal.cpp b/src/insets/InsetExternal.cpp
index cb86df4..8b0f00c 100644
--- a/src/insets/InsetExternal.cpp
+++ b/src/insets/InsetExternal.cpp
@@ -273,7 +273,7 @@ bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex)
 		case EX_FILENAME: {
 			lex.eatLine();
 			string const name = lex.getString();
-			filename.set(name, buffer.originFilePath());
+			filename = buffer.getReferencedFileName(name);
 			break;
 		}
 		
diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp
index c20f031..555ece1 100644
--- a/src/insets/InsetGraphics.cpp
+++ b/src/insets/InsetGraphics.cpp
@@ -139,7 +139,7 @@ string findTargetFormat(string const & format, OutputParams const & runparams)
 }
 
 
-void readInsetGraphics(Lexer & lex, string const & bufpath,
+void readInsetGraphics(Lexer & lex, Buffer const & buf, bool allowOrigin,
 	InsetGraphicsParams & params)
 {
 	bool finished = false;
@@ -156,7 +156,7 @@ void readInsetGraphics(Lexer & lex, string const & bufpath,
 		if (token == "\\end_inset") {
 			finished = true;
 		} else {
-			if (!params.Read(lex, token, bufpath))
+			if (!params.Read(lex, token, buf, allowOrigin))
 				lyxerr << "Unknown token, "
 				       << token
 				       << ", skipping."
@@ -299,7 +299,7 @@ void InsetGraphics::read(Lexer & lex)
 {
 	lex.setContext("InsetGraphics::read");
 	//lex >> "Graphics";
-	readInsetGraphics(lex, buffer().originFilePath(), params_);
+	readInsetGraphics(lex, buffer(), true, params_);
 	graphic_->update(params().as_grfxParams());
 }
 
@@ -1054,7 +1054,7 @@ void InsetGraphics::string2params(string const & in, Buffer const & buffer,
 	lex.setContext("InsetGraphics::string2params");
 	lex >> "graphics";
 	params = InsetGraphicsParams();
-	readInsetGraphics(lex, buffer.filePath(), params);
+	readInsetGraphics(lex, buffer, false, params);
 }
 
 
diff --git a/src/insets/InsetGraphicsParams.cpp b/src/insets/InsetGraphicsParams.cpp
index e158e81..03ca0d6 100644
--- a/src/insets/InsetGraphicsParams.cpp
+++ b/src/insets/InsetGraphicsParams.cpp
@@ -177,11 +177,15 @@ void InsetGraphicsParams::Write(ostream & os, Buffer const & buffer) const
 }
 
 
-bool InsetGraphicsParams::Read(Lexer & lex, string const & token, string const & bufpath)
+bool InsetGraphicsParams::Read(Lexer & lex, string const & token,
+                               Buffer const & buf, bool allowOrigin)
 {
 	if (token == "filename") {
 		lex.eatLine();
-		filename.set(lex.getString(), bufpath);
+		if (allowOrigin)
+			filename = buf.getReferencedFileName(lex.getString());
+		else
+			filename.set(lex.getString(), buf.filePath());
 	} else if (token == "lyxscale") {
 		lex.next();
 		lyxscale = lex.getInteger();
diff --git a/src/insets/InsetGraphicsParams.h b/src/insets/InsetGraphicsParams.h
index 4fa54d7..315f4c7 100644
--- a/src/insets/InsetGraphicsParams.h
+++ b/src/insets/InsetGraphicsParams.h
@@ -73,7 +73,8 @@ public:
 	/// Buffer is needed to figure out if a figure is embedded.
 	void Write(std::ostream & os, Buffer const & buf) const;
 	/// If the token belongs to our parameters, read it.
-	bool Read(Lexer & lex, std::string const & token, std::string const & bufpath);
+	bool Read(Lexer & lex, std::string const & token, Buffer const & buf,
+	          bool allowOrigin);
 	/// convert
 	// Only a subset of InsetGraphicsParams is needed for display purposes.
 	// This function also interrogates lyxrc to ascertain whether

Reply via email to