mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Correctly load documents moved elsewhere after save.
It is now possible opening documents that where manually moved to a different location after they were saved and still produce an output. Indeed, (hopefully) all needed included files are now still found. When the moved document is saved again, all paths are accordingly updated. Of course, for this to work, a document has to be saved in Format 490, at least. As an example, after converting the user guide to the last format, it can be copied anywhere and opened without the need of adapting the paths of included files or moving them to a proper place. There is one glitch I am aware of. When moving a child document (but not the master) the path to the master is correctly updated but it won't be recognized as such. This is because LyX checks that the parent actually includes this document but, of course, being the parent document not touched, it appears not including this child. Anyway, it will also occur when saving the child to a different location and the user is warned on the terminal about this fact when the moved child is loaded. However, there is no problem when it is the master that has been moved.
This commit is contained in:
parent
853283ca87
commit
62d36bf04d
@ -249,7 +249,8 @@ public:
|
||||
/// map from children inclusion positions to their scope and their buffer
|
||||
PositionScopeBufferMap position_to_children;
|
||||
|
||||
/// Keeps track of old buffer filePath() for save-as operations
|
||||
/// Contains the old buffer filePath() while saving-as, or the
|
||||
/// directory where the document was last saved while loading.
|
||||
string old_position;
|
||||
|
||||
/** Keeps track of the path of local layout files.
|
||||
@ -1030,7 +1031,9 @@ bool Buffer::readDocument(Lexer & lex)
|
||||
params().indiceslist().addDefault(B_("Index"));
|
||||
|
||||
// read main text
|
||||
d->old_position = originFilePath();
|
||||
bool const res = text().read(lex, errorList, d->inset);
|
||||
d->old_position.clear();
|
||||
|
||||
// inform parent buffer about local macros
|
||||
if (parent()) {
|
||||
@ -3027,6 +3030,15 @@ string Buffer::filePath() const
|
||||
}
|
||||
|
||||
|
||||
string Buffer::originFilePath() const
|
||||
{
|
||||
if (FileName::isAbsolute(params().origin))
|
||||
return params().origin;
|
||||
|
||||
return filePath();
|
||||
}
|
||||
|
||||
|
||||
string Buffer::layoutPos() const
|
||||
{
|
||||
return d->layout_position;
|
||||
|
10
src/Buffer.h
10
src/Buffer.h
@ -403,6 +403,13 @@ 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.
|
||||
*/
|
||||
std::string originFilePath() const;
|
||||
|
||||
/** Returns the path where a local layout file lives.
|
||||
* An empty string is returned for standard system and user layouts.
|
||||
* If possible, it is always relative to the buffer path.
|
||||
@ -731,6 +738,9 @@ public:
|
||||
/// In all other cases, this is a no-op and name is returned unchanged.
|
||||
/// If a non-empty ext is given, the existence of name.ext is checked
|
||||
/// but the returned path will not contain this extension.
|
||||
/// Similarly, when loading a document that was moved from the location
|
||||
/// where it was saved, return the correct path relative to the new
|
||||
/// location.
|
||||
std::string includedFilePath(std::string const & name,
|
||||
std::string const & ext = empty_string()) const;
|
||||
|
||||
|
@ -682,6 +682,19 @@ string BufferParams::readToken(Lexer & lex, string const & token,
|
||||
} else if (token == "\\master") {
|
||||
lex.eatLine();
|
||||
master = lex.getString();
|
||||
if (!filepath.empty() && FileName::isAbsolute(origin)) {
|
||||
bool const isabs = FileName::isAbsolute(master);
|
||||
FileName const abspath(isabs ? master : origin + master);
|
||||
bool const moved = filepath != FileName(origin);
|
||||
if (moved && abspath.exists()) {
|
||||
docstring const path = isabs
|
||||
? from_utf8(master)
|
||||
: from_utf8(abspath.realPath());
|
||||
docstring const refpath =
|
||||
from_utf8(filepath.absFileName());
|
||||
master = to_utf8(makeRelPath(path, refpath));
|
||||
}
|
||||
}
|
||||
} else if (token == "\\suppress_date") {
|
||||
lex >> suppress_date;
|
||||
} else if (token == "\\justification") {
|
||||
|
@ -538,7 +538,7 @@ Inset * readInset(Lexer & lex, Buffer * buf)
|
||||
//Worst case, we could put it in each case below. Better, we could
|
||||
//pass the lexer to the constructor and let the params be built there.
|
||||
InsetCommandParams inscmd(code);
|
||||
inscmd.read(lex);
|
||||
inscmd.read(lex, buf);
|
||||
|
||||
switch (code) {
|
||||
case BIBITEM_CODE:
|
||||
|
@ -195,7 +195,7 @@ void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
|
||||
|
||||
void InsetBibitem::read(Lexer & lex)
|
||||
{
|
||||
InsetCommand::read(lex);
|
||||
InsetCommand::read(lex, &buffer());
|
||||
|
||||
if (prefixIs(getParam("key"), key_prefix)) {
|
||||
int const key = convert<int>(getParam("key").substr(key_prefix.length()));
|
||||
|
@ -244,7 +244,7 @@ bool InsetCommand::string2params(string const & data,
|
||||
lex.setContext("InsetCommand::string2params");
|
||||
lex >> name.c_str(); // check for name
|
||||
lex >> "CommandInset";
|
||||
params.read(lex);
|
||||
params.read(lex, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
///
|
||||
void write(std::ostream & os) const { p_.write(os); }
|
||||
///
|
||||
void read(Lexer & lex) { p_.read(lex); }
|
||||
void read(Lexer & lex, Buffer const * buf) { p_.read(lex, buf); }
|
||||
///
|
||||
void doDispatch(Cursor & cur, FuncRequest & cmd);
|
||||
///
|
||||
|
@ -275,7 +275,7 @@ void InsetCommandParams::setCmdName(string const & name)
|
||||
}
|
||||
|
||||
|
||||
void InsetCommandParams::read(Lexer & lex)
|
||||
void InsetCommandParams::read(Lexer & lex, Buffer const * buffer)
|
||||
{
|
||||
lex.setContext("InsetCommandParams::read");
|
||||
lex >> insetName(insetCode_).c_str();
|
||||
@ -302,7 +302,25 @@ void InsetCommandParams::read(Lexer & lex)
|
||||
}
|
||||
if (info_.hasParam(token)) {
|
||||
lex.next(true);
|
||||
params_[token] = lex.getDocString();
|
||||
docstring data = lex.getDocString();
|
||||
if (buffer && token == "filename") {
|
||||
data = from_utf8(buffer->includedFilePath(to_utf8(data)));
|
||||
} else if (buffer && token == "bibfiles") {
|
||||
int i = 0;
|
||||
docstring newdata;
|
||||
docstring bib = support::token(data, ',', i);
|
||||
while (!bib.empty()) {
|
||||
bib = from_utf8(buffer->includedFilePath(to_utf8(bib), "bib"));
|
||||
if (!newdata.empty())
|
||||
newdata.append(1, ',');
|
||||
newdata.append(bib);
|
||||
bib = support::token(data, ',', ++i);
|
||||
}
|
||||
data = newdata;
|
||||
} else if (buffer && token == "options") {
|
||||
data = from_utf8(buffer->includedFilePath(to_utf8(data), "bst"));
|
||||
}
|
||||
params_[token] = data;
|
||||
} else {
|
||||
lex.printError("Unknown parameter name `$$Token' for command " + cmdName_);
|
||||
throw ExceptionMessage(WarningException,
|
||||
@ -353,6 +371,8 @@ void InsetCommandParams::Write(ostream & os, Buffer const * buffer) const
|
||||
bib = token(data, ',', ++i);
|
||||
}
|
||||
data = newdata;
|
||||
} else if (buffer && name == "options") {
|
||||
data = buffer->includedFilePath(data, "bst");
|
||||
}
|
||||
os << name << ' '
|
||||
<< Lexer::quoteString(data)
|
||||
|
@ -114,7 +114,7 @@ public:
|
||||
///
|
||||
InsetCode code() const { return insetCode_; }
|
||||
///
|
||||
void read(Lexer &);
|
||||
void read(Lexer &, Buffer const *);
|
||||
/// Parse the command
|
||||
///
|
||||
void write(std::ostream &) const;
|
||||
|
@ -293,7 +293,7 @@ void InsetGraphics::read(Lexer & lex)
|
||||
{
|
||||
lex.setContext("InsetGraphics::read");
|
||||
//lex >> "Graphics";
|
||||
readInsetGraphics(lex, buffer().filePath(), params_);
|
||||
readInsetGraphics(lex, buffer().originFilePath(), params_);
|
||||
graphic_->update(params().as_grfxParams());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user