from_utf8(d->temppath.absFileName())));
}
- // Remove any previewed LaTeX snippets associated with this buffer.
if (!isClone())
- thePreviews().removeLoader(*this);
+ removePreviews();
delete d;
}
ErrorList & errorList = d->errorLists["Parse"];
errorList.clear();
+ // remove dummy empty par
+ paragraphs().clear();
+
if (!lex.checkFor("\\begin_document")) {
docstring const s = _("\\begin_document is missing");
errorList.push_back(ErrorItem(_("Document header error"),
s, -1, 0, 0));
}
- // we are reading in a brand new document
- LASSERT(paragraphs().empty(), /**/);
-
readHeader(lex);
if (params().outputChanges) {
{
params().compressed = false;
- // remove dummy empty par
- paragraphs().clear();
Lexer lex;
istringstream is(s);
lex.setStream(is);
- FileName const name = FileName::tempName("Buffer_readString");
- switch (readFile(lex, name, true)) {
- case failure:
- return false;
- case wrongversion: {
+ FileName const fn = FileName::tempName("Buffer_readString");
+
+ int file_format;
+ ReadStatus const ret_plf = parseLyXFormat(lex, fn, file_format);
+ if (ret_plf != ReadSuccess)
+ return ret_plf;
+
+ if (file_format != LYX_FORMAT) {
// We need to call lyx2lyx, so write the input to a file
- ofstream os(name.toFilesystemEncoding().c_str());
+ ofstream os(fn.toFilesystemEncoding().c_str());
os << s;
os.close();
- return readFile(name);
- }
- case success:
- break;
+ // lyxvc in readFile
+ return readFile(fn) == ReadSuccess;
}
+ if (readDocument(lex))
+ return false;
return true;
}
-bool Buffer::readFile(FileName const & filename)
+Buffer::ReadStatus Buffer::readFile(FileName const & fn)
{
- FileName fname(filename);
-
- params().compressed = fname.isZippedFile();
-
- // remove dummy empty par
- paragraphs().clear();
+ FileName fname(fn);
Lexer lex;
lex.setFile(fname);
- if (readFile(lex, fname) != success)
- return false;
- return true;
+ int file_format;
+ ReadStatus const ret_plf = parseLyXFormat(lex, fn, file_format);
+ if (ret_plf != ReadSuccess)
+ return ret_plf;
+
+ if (file_format != LYX_FORMAT) {
+ FileName tmpFile;
+ ReadStatus const ret_clf = convertLyXFormat(fn, tmpFile, file_format);
+ if (ret_clf != ReadSuccess)
+ return ret_clf;
+ return readFile(tmpFile);
+ }
+
+ // InsetInfo needs to know if file is under VCS
+ lyxvc().file_found_hook(fn);
+
+ if (readDocument(lex)) {
+ Alert::error(_("Document format failure"),
+ bformat(_("%1$s ended unexpectedly, which means"
+ " that it is probably corrupted."),
+ from_utf8(fn.absFileName())));
+ return ReadDocumentFailure;
+ }
+
+ d->file_fully_loaded = true;
+ d->read_only = !fname.isWritable();
+ params().compressed = fname.isZippedFile();
+ saveCheckSum();
+ return ReadSuccess;
}
}
-Buffer::ReadStatus Buffer::readFile(Lexer & lex, FileName const & filename,
- bool fromstring)
+void Buffer::updatePreviews() const
+{
+ if (graphics::Previews::status() != LyXRC::PREVIEW_OFF)
+ thePreviews().generateBufferPreviews(*this);
+}
+
+
+void Buffer::removePreviews() const
{
- LASSERT(!filename.empty(), /**/);
+ thePreviews().removeLoader(*this);
+}
+
- // the first (non-comment) token _must_ be...
- if (!lex.checkFor("\\lyxformat")) {
+Buffer::ReadStatus Buffer::parseLyXFormat(Lexer & lex,
+ FileName const & fn, int & file_format) const
+{
+ if(!lex.checkFor("\\lyxformat")) {
Alert::error(_("Document format failure"),
- bformat(_("%1$s is not a readable LyX document."),
- from_utf8(filename.absFileName())));
- return failure;
- }
+ bformat(_("%1$s is not a readable LyX document."),
+ from_utf8(fn.absFileName())));
+ return ReadNoLyXFormat;
+ }
string tmp_format;
lex >> tmp_format;
- //lyxerr << "LyX Format: `" << tmp_format << '\'' << endl;
- // if present remove ".," from string.
+
+ // LyX formats 217 and earlier were written as 2.17. This corresponds
+ // to files from LyX versions < 1.1.6.3. We just remove the dot in
+ // these cases. See also: www.lyx.org/trac/changeset/1313.
size_t dot = tmp_format.find_first_of(".,");
- //lyxerr << " dot found at " << dot << endl;
if (dot != string::npos)
- tmp_format.erase(dot, 1);
- int const file_format = convert<int>(tmp_format);
- //lyxerr << "format: " << file_format << endl;
-
- // save timestamp and checksum of the original disk file, making sure
- // to not overwrite them with those of the file created in the tempdir
- // when it has to be converted to the current format.
- if (!d->checksum_) {
- // Save the timestamp and checksum of disk file. If filename is an
- // emergency file, save the timestamp and checksum of the original lyx file
- // because isExternallyModified will check for this file. (BUG4193)
- string diskfile = filename.absFileName();
- if (suffixIs(diskfile, ".emergency"))
- diskfile = diskfile.substr(0, diskfile.size() - 10);
- saveCheckSum(FileName(diskfile));
- }
+ tmp_format.erase(dot, 1);
- if (file_format != LYX_FORMAT) {
+ file_format = convert<int>(tmp_format);
+ return ReadSuccess;
+}
- if (fromstring)
- // lyx2lyx would fail
- return wrongversion;
-
- FileName const tmpfile = FileName::tempName("Buffer_readFile");
- if (tmpfile.empty()) {
- Alert::error(_("Conversion failed"),
- bformat(_("%1$s is from a different"
- " version of LyX, but a temporary"
- " file for converting it could"
- " not be created."),
- from_utf8(filename.absFileName())));
- return failure;
- }
- FileName const lyx2lyx = libFileSearch("lyx2lyx", "lyx2lyx");
- if (lyx2lyx.empty()) {
- Alert::error(_("Conversion script not found"),
- bformat(_("%1$s is from a different"
- " version of LyX, but the"
- " conversion script lyx2lyx"
- " could not be found."),
- from_utf8(filename.absFileName())));
- return failure;
- }
- ostringstream command;
- command << os::python()
- << ' ' << quoteName(lyx2lyx.toFilesystemEncoding())
- << " -t " << convert<string>(LYX_FORMAT)
- << " -o " << quoteName(tmpfile.toFilesystemEncoding())
- << ' ' << quoteName(filename.toSafeFilesystemEncoding());
- string const command_str = command.str();
-
- LYXERR(Debug::INFO, "Running '" << command_str << '\'');
-
- cmd_ret const ret = runCommand(command_str);
- if (ret.first != 0) {
- if (file_format < LYX_FORMAT)
- Alert::error(_("Conversion script failed"),
- bformat(_("%1$s is from an older version"
- " of LyX, but the lyx2lyx script"
- " failed to convert it."),
- from_utf8(filename.absFileName())));
- else
- Alert::error(_("Conversion script failed"),
- bformat(_("%1$s is from a newer version"
- " of LyX and cannot be converted by the"
- " lyx2lyx script."),
- from_utf8(filename.absFileName())));
- return failure;
- } else {
- bool const ret = readFile(tmpfile);
- // Do stuff with tmpfile name and buffer name here.
- return ret ? success : failure;
- }
+Buffer::ReadStatus Buffer::convertLyXFormat(FileName const & fn,
+ FileName & tmpfile, int from_format)
+{
+ tmpfile = FileName::tempName("Buffer_convertLyXFormat");
+ if(tmpfile.empty()) {
+ Alert::error(_("Conversion failed"),
+ bformat(_("%1$s is from a different"
+ " version of LyX, but a temporary"
+ " file for converting it could"
+ " not be created."),
+ from_utf8(fn.absFileName())));
+ return LyX2LyXNoTempFile;
}
- if (readDocument(lex)) {
- Alert::error(_("Document format failure"),
- bformat(_("%1$s ended unexpectedly, which means"
- " that it is probably corrupted."),
- from_utf8(filename.absFileName())));
- return failure;
+ FileName const lyx2lyx = libFileSearch("lyx2lyx", "lyx2lyx");
+ if (lyx2lyx.empty()) {
+ Alert::error(_("Conversion script not found"),
+ bformat(_("%1$s is from a different"
+ " version of LyX, but the"
+ " conversion script lyx2lyx"
+ " could not be found."),
+ from_utf8(fn.absFileName())));
+ return LyX2LyXNotFound;
}
- d->file_fully_loaded = true;
- return success;
+ // Run lyx2lyx:
+ // $python$ "$lyx2lyx$" -t $LYX_FORMAT$ -o "$tempfile$" "$filetoread$"
+ ostringstream command;
+ command << os::python()
+ << ' ' << quoteName(lyx2lyx.toFilesystemEncoding())
+ << " -t " << convert<string>(LYX_FORMAT)
+ << " -o " << quoteName(tmpfile.toFilesystemEncoding())
+ << ' ' << quoteName(fn.toSafeFilesystemEncoding());
+ string const command_str = command.str();
+
+ LYXERR(Debug::INFO, "Running '" << command_str << '\'');
+
+ cmd_ret const ret = runCommand(command_str);
+ if (ret.first != 0) {
+ if (from_format < LYX_FORMAT) {
+ Alert::error(_("Conversion script failed"),
+ bformat(_("%1$s is from an older version"
+ " of LyX, but the lyx2lyx script"
+ " failed to convert it."),
+ from_utf8(fn.absFileName())));
+ return LyX2LyXOlderFormat;
+ } else {
+ Alert::error(_("Conversion script failed"),
+ bformat(_("%1$s is from an newer version"
+ " of LyX, but the lyx2lyx script"
+ " failed to convert it."),
+ from_utf8(fn.absFileName())));
+ return LyX2LyXNewerFormat;
+ }
+ }
+ return ReadSuccess;
}
// see bug 6587
// removeAutosaveFile();
- saveCheckSum(d->filename);
+ saveCheckSum();
message(str + _(" done."));
return true;
d->bibfiles_cache_.clear();
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
if (it->lyxCode() == BIBTEX_CODE) {
- InsetBibtex const & inset =
- static_cast<InsetBibtex const &>(*it);
+ InsetBibtex const & inset = static_cast<InsetBibtex const &>(*it);
support::FileNameList const bibfiles = inset.getBibFiles();
d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
bibfiles.begin(),
bibfiles.end());
} else if (it->lyxCode() == INCLUDE_CODE) {
- InsetInclude & inset =
- static_cast<InsetInclude &>(*it);
+ InsetInclude & inset = static_cast<InsetInclude &>(*it);
Buffer const * const incbuf = inset.getChildBuffer();
if (!incbuf)
continue;
bool success = false;
for (; it != end; ++it) {
if (it->lyxCode() == BRANCH_CODE) {
- InsetBranch & ins = dynamic_cast<InsetBranch &>(*it);
+ InsetBranch & ins = static_cast<InsetBranch &>(*it);
if (ins.branch() == oldname) {
undo().recordUndo(it);
ins.rename(newname);
}
-void Buffer::saveCheckSum(FileName const & file) const
+void Buffer::saveCheckSum() const
{
+ FileName const & file = d->filename;
if (file.exists()) {
d->timestamp_ = file.lastModified();
d->checksum_ = file.checksum();
continue;
}
- if (doing_export && iit->inset->asInsetMath()) {
- InsetMath * im = static_cast<InsetMath *>(iit->inset);
- if (im->asHullInset()) {
- InsetMathHull * hull = static_cast<InsetMathHull *>(im);
+ InsetMath * im = iit->inset->asInsetMath();
+ if (doing_export && im) {
+ InsetMathHull * hull = im->asHullInset();
+ if (hull)
hull->recordLocation(it);
- }
}
if (iit->inset->lyxCode() != MATHMACRO_CODE)
// get macro data
MathMacroTemplate & macroTemplate =
- static_cast<MathMacroTemplate &>(*iit->inset);
+ *iit->inset->asInsetMath()->asMacroTemplate();
MacroContext mc(owner_, it);
macroTemplate.updateToContext(mc);
InsetIterator const end = inset_iterator_end(inset());
for (; it != end; ++it) {
if (it->lyxCode() == BRANCH_CODE) {
- InsetBranch & br = dynamic_cast<InsetBranch &>(*it);
+ InsetBranch & br = static_cast<InsetBranch &>(*it);
docstring const name = br.branch();
if (!from_master && !params().branchlist().find(name))
result.push_back(name);
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
if (it->lyxCode() == code) {
- InsetCommand & inset = static_cast<InsetCommand &>(*it);
- docstring const oldValue = inset.getParam(paramName);
+ InsetCommand * inset = it->asInsetCommand();
+ if (!inset)
+ continue;
+ docstring const oldValue = inset->getParam(paramName);
if (oldValue == from)
- inset.setParam(paramName, to);
+ inset->setParam(paramName, to);
}
}
}
} // namespace anon
+FileName Buffer::getEmergencyFileName() const
+{
+ return getEmergencyFileNameFor(d->filename);
+}
+
+
+FileName Buffer::getEmergencyFileNameFor(FileName const & fn) const
+{
+ return FileName(fn.absFileName() + ".emergency");
+}
+
+
FileName Buffer::getAutosaveFileName() const
{
// if the document is unnamed try to save in the backup dir, else
if (!isUnnamed() || fpath.empty() || !FileName(fpath).exists())
fpath = filePath();
- string const fname = "#" + d->filename.onlyFileName() + "#";
- return makeAbsPath(fname, fpath);
+ string const fname = d->filename.onlyFileName();
+ return getAutosaveFileNameFor(makeAbsPath(fname, fpath));
+}
+
+
+FileName Buffer::getAutosaveFileNameFor(FileName const & fn) const
+{
+ string const fname = "#" + onlyFileName(fn.absFileName()) + "#";
+ return FileName(onlyPath(fn.absFileName()) + fname);
}
}
-bool Buffer::readFileHelper(FileName const & s)
+Buffer::ReadStatus Buffer::extractFromVC(FileName const & fn)
{
- // File information about normal file
- if (!s.exists()) {
- docstring const file = makeDisplayPath(s.absFileName(), 50);
- docstring text = bformat(_("The specified document\n%1$s"
- "\ncould not be read."), file);
- Alert::error(_("Could not read document"), text);
- return false;
- }
+ bool const found = LyXVC::file_not_found_hook(fn);
+ if (!found)
+ return ReadFileNotFound;
+ if (!fn.isReadableFile())
+ return ReadVCError;
+ return ReadSuccess;
+}
- // Check if emergency save file exists and is newer.
- FileName const e(s.absFileName() + ".emergency");
-
- if (e.exists() && s.exists() && e.lastModified() > s.lastModified()) {
- docstring const file = makeDisplayPath(s.absFileName(), 20);
- docstring const text =
- bformat(_("An emergency save of the document "
- "%1$s exists.\n\n"
- "Recover emergency save?"), file);
- switch (Alert::prompt(_("Load emergency save?"), text, 0, 2,
- _("&Recover"), _("&Load Original"),
- _("&Cancel")))
- {
- case 0: {
- // the file is not saved if we load the emergency file.
+
+Buffer::ReadStatus Buffer::loadEmergency(FileName const & fn)
+{
+ FileName const emergencyFile = getEmergencyFileNameFor(fn);
+ if (!emergencyFile.exists()
+ || emergencyFile.lastModified() <= fn.lastModified())
+ return ReadFileNotFound;
+
+ docstring const file = makeDisplayPath(fn.absFileName(), 20);
+ docstring const text = bformat(_("An emergency save of the document "
+ "%1$s exists.\n\nRecover emergency save?"), file);
+
+ int const load_emerg = Alert::prompt(_("Load emergency save?"), text,
+ 0, 2, _("&Recover"), _("&Load Original"), _("&Cancel"));
+
+ switch (load_emerg)
+ {
+ case 0: {
+ docstring str;
+ ReadStatus const ret_llf = loadThisLyXFile(emergencyFile);
+ bool const success = (ret_llf == ReadSuccess);
+ if (success) {
markDirty();
- docstring str;
- bool res;
-
- if ((res = readFile(e)) == success)
- str = _("Document was successfully recovered.");
- else
- str = _("Document was NOT successfully recovered.");
- str += "\n\n" + bformat(_("Remove emergency file now?\n(%1$s)"),
- makeDisplayPath(e.absFileName()));
-
- if (!Alert::prompt(_("Delete emergency file?"), str, 1, 1,
- _("&Remove"), _("&Keep it"))) {
- e.removeFile();
- if (res == success)
- Alert::warning(_("Emergency file deleted"),
- _("Do not forget to save your file now!"), true);
- }
- return res;
- }
- case 1:
- if (!Alert::prompt(_("Delete emergency file?"),
- _("Remove emergency file now?"), 1, 1,
- _("&Remove"), _("&Keep it")))
- e.removeFile();
- break;
- default:
- return false;
- }
+ lyxvc().file_found_hook(fn);
+ str = _("Document was successfully recovered.");
+ } else
+ str = _("Document was NOT successfully recovered.");
+ str += "\n\n" + bformat(_("Remove emergency file now?\n(%1$s)"),
+ makeDisplayPath(emergencyFile.absFileName()));
+
+ int const del_emerg =
+ Alert::prompt(_("Delete emergency file?"), str, 1, 1,
+ _("&Remove"), _("&Keep"));
+ if (del_emerg == 0) {
+ emergencyFile.removeFile();
+ if (success)
+ Alert::warning(_("Emergency file deleted"),
+ _("Do not forget to save your file now!"), true);
+ }
+ return success ? ReadSuccess : ReadEmergencyFailure;
+ }
+ case 1: {
+ int const del_emerg =
+ Alert::prompt(_("Delete emergency file?"),
+ _("Remove emergency file now?"), 1, 1,
+ _("&Remove"), _("&Keep"));
+ if (del_emerg == 0)
+ emergencyFile.removeFile();
+ return ReadOriginal;
}
+ default:
+ break;
+ }
+ return ReadCancel;
+}
+
+
+Buffer::ReadStatus Buffer::loadAutosave(FileName const & fn)
+{
// Now check if autosave file is newer.
- FileName const a(onlyPath(s.absFileName()) + '#' + onlyFileName(s.absFileName()) + '#');
-
- if (a.exists() && s.exists() && a.lastModified() > s.lastModified()) {
- docstring const file = makeDisplayPath(s.absFileName(), 20);
- docstring const text =
- bformat(_("The backup of the document "
- "%1$s is newer.\n\nLoad the "
- "backup instead?"), file);
- switch (Alert::prompt(_("Load backup?"), text, 0, 2,
- _("&Load backup"), _("Load &original"),
- _("&Cancel") ))
- {
- case 0:
- // the file is not saved if we load the autosave file.
+ FileName const autosaveFile = getAutosaveFileNameFor(fn);
+ if (!autosaveFile.exists()
+ || autosaveFile.lastModified() <= fn.lastModified())
+ return ReadFileNotFound;
+
+ docstring const file = makeDisplayPath(fn.absFileName(), 20);
+ docstring const text = bformat(_("The backup of the document %1$s "
+ "is newer.\n\nLoad the backup instead?"), file);
+ int const ret = Alert::prompt(_("Load backup?"), text, 0, 2,
+ _("&Load backup"), _("Load &original"), _("&Cancel"));
+
+ switch (ret)
+ {
+ case 0: {
+ ReadStatus const ret_llf = loadThisLyXFile(autosaveFile);
+ // the file is not saved if we load the autosave file.
+ if (ret_llf == ReadSuccess) {
markDirty();
- return readFile(a);
- case 1:
- // Here we delete the autosave
- a.removeFile();
- break;
- default:
- return false;
+ lyxvc().file_found_hook(fn);
+ return ReadSuccess;
}
+ return ReadAutosaveFailure;
}
- return readFile(s);
+ case 1:
+ // Here we delete the autosave
+ autosaveFile.removeFile();
+ return ReadOriginal;
+ default:
+ break;
+ }
+ return ReadCancel;
}
-bool Buffer::loadLyXFile(FileName const & s)
+Buffer::ReadStatus Buffer::loadLyXFile(FileName const & fn)
{
- // If the file is not readable, we try to
- // retrieve the file from version control.
- if (!s.isReadableFile()
- && !LyXVC::file_not_found_hook(s))
- return false;
-
- if (s.isReadableFile()){
- // InsetInfo needs to know if file is under VCS
- lyxvc().file_found_hook(s);
- if (readFileHelper(s)) {
- d->read_only = !s.isWritable();
- return true;
- }
+ if (!fn.isReadableFile()) {
+ ReadStatus const ret_rvc = extractFromVC(fn);
+ if (ret_rvc != ReadSuccess)
+ return ret_rvc;
}
- return false;
+
+ ReadStatus const ret_re = loadEmergency(fn);
+ if (ret_re == ReadSuccess || ret_re == ReadCancel)
+ return ret_re;
+
+ ReadStatus const ret_ra = loadAutosave(fn);
+ if (ret_ra == ReadSuccess || ret_ra == ReadCancel)
+ return ret_ra;
+
+ return loadThisLyXFile(fn);
+}
+
+
+Buffer::ReadStatus Buffer::loadThisLyXFile(FileName const & fn)
+{
+ return readFile(fn);
}
}
-bool Buffer::reload()
+Buffer::ReadStatus Buffer::reload()
{
setBusy(true);
// c.f. bug 6587
d->filename.refresh();
docstring const disp_fn = makeDisplayPath(d->filename.absFileName());
- bool const success = loadLyXFile(d->filename);
- if (success) {
+ ReadStatus const status = loadLyXFile(d->filename);
+ if (status == ReadSuccess) {
updateBuffer();
changed(true);
updateTitles();
markClean();
- saveCheckSum(d->filename);
message(bformat(_("Document %1$s reloaded."), disp_fn));
} else {
message(bformat(_("Could not reload document %1$s."), disp_fn));
}
setBusy(false);
- thePreviews().removeLoader(*this);
- if (graphics::Previews::status() != LyXRC::PREVIEW_OFF)
- thePreviews().generateBufferPreviews(*this);
+ removePreviews();
+ updatePreviews();
errors("Parse");
- return success;
+ return status;
}