#include "buffer.h"
#include "author.h"
+#include "BranchList.h"
#include "buffer_funcs.h"
#include "bufferlist.h"
#include "bufferparams.h"
#include "graphics/Previews.h"
+#include "support/lyxalgo.h"
#include "support/filetools.h"
#include "support/fs_extras.h"
#ifdef USE_COMPRESSION
#include <boost/bind.hpp>
#include <boost/filesystem/operations.hpp>
-#include <utime.h>
+#if defined (HAVE_UTIME_H)
+# include <utime.h>
+#elif defined (HAVE_SYS_UTIME_H)
+# include <sys/utime.h>
+#endif
#include <iomanip>
#include <stack>
using lyx::support::getFormatFromContents;
using lyx::support::IsDirWriteable;
using lyx::support::LibFileSearch;
+using lyx::support::latex_path;
using lyx::support::ltrim;
using lyx::support::MakeAbsPath;
using lyx::support::MakeDisplayPath;
namespace {
-int const LYX_FORMAT = 241;
+int const LYX_FORMAT = 245;
} // namespace anon
}
-Buffer::Buffer(string const & file, bool ronly)
- : pimpl_(new Impl(*this, file, ronly))
+Buffer::Buffer(string const & file, bool readonly)
+ : pimpl_(new Impl(*this, file, readonly))
{
lyxerr[Debug::INFO] << "Buffer::Buffer()" << endl;
}
int line = -1;
int begin_header_line = -1;
+ // Initialize parameters that may be/go lacking in header:
+ params().branchlist().clear();
+ params().options.erase();
+ params().float_placement.erase();
+ params().paperwidth.erase();
+ params().paperheight.erase();
+ params().leftmargin.erase();
+ params().rightmargin.erase();
+ params().topmargin.erase();
+ params().bottommargin.erase();
+ params().headheight.erase();
+ params().headsep.erase();
+ params().footskip.erase();
+
while (lex.isOK()) {
lex.next();
string const token = lex.getString();
continue;
}
- lyxerr[Debug::PARSER] << "Handling header token: `"
+ lyxerr[Debug::PARSER] << "Handling document header token: `"
<< token << '\'' << endl;
string unknown = params().readToken(lex, token);
"%1$s %2$s\n"),
token,
lex.getString());
- error(ErrorItem(_("Header error"), s,
+ error(ErrorItem(_("Document header error"), s,
-1, 0, 0));
}
}
}
if (begin_header_line) {
string const s = _("\\begin_header is missing");
- error(ErrorItem(_("Header error"), s, -1, 0, 0));
+ error(ErrorItem(_("Document header error"), s, -1, 0, 0));
}
return unknown_tokens;
}
string const token = lex.getString();
if (token != "\\begin_document") {
string const s = _("\\begin_document is missing");
- error(ErrorItem(_("Header error"), s, -1, 0, 0));
+ error(ErrorItem(_("Document header error"), s, -1, 0, 0));
}
- if (paragraphs().empty()) {
- readHeader(lex);
- if (!params().getLyXTextClass().load()) {
- string theclass = params().getLyXTextClass().name();
- Alert::error(_("Can't load document class"), bformat(
- "Using the default document class, because the "
- " class %1$s could not be loaded.", theclass));
- params().textclass = 0;
- }
- } else {
- // We don't want to adopt the parameters from the
- // document we insert, so read them into a temporary buffer
- // and then discard it
+ // we are reading in a brand new document
+ BOOST_ASSERT(paragraphs().empty());
- Buffer tmpbuf("", false);
- tmpbuf.readHeader(lex);
+ readHeader(lex);
+ if (!params().getLyXTextClass().load()) {
+ string theclass = params().getLyXTextClass().name();
+ Alert::error(_("Can't load document class"), bformat(
+ "Using the default document class, because the "
+ " class %1$s could not be loaded.", theclass));
+ params().textclass = 0;
}
- return text().read(*this, lex);
+ bool const res = text().read(*this, lex);
+ for_each(text().paragraphs().begin(),
+ text().paragraphs().end(),
+ bind(&Paragraph::setInsetOwner, _1, &inset()));
+ return res;
}
{
LyXFont font = fn;
- pars[pit].checkInsertChar(font);
// insert the string, don't insert doublespace
bool space_inserted = true;
for (string::const_iterator cit = str.begin();
// remove dummy empty par
paragraphs().clear();
- bool ret = readFile(filename, paragraphs().size());
+ LyXLex lex(0, 0);
+ lex.setFile(filename);
+ bool ret = readFile(lex, filename);
// After we have read a file, we must ensure that the buffer
// language is set and used in the gui.
}
-bool Buffer::readFile(string const & filename, pit_type const pit)
-{
- LyXLex lex(0, 0);
- lex.setFile(filename);
- return readFile(lex, filename, pit);
-}
-
-
bool Buffer::fully_loaded() const
{
return pimpl_->file_fully_loaded;
}
-bool Buffer::readFile(LyXLex & lex, string const & filename, pit_type const pit)
+bool Buffer::readFile(LyXLex & lex, string const & filename)
{
BOOST_ASSERT(!filename.empty());
filename));
return false;
}
- string command =
- "python " + LibFileSearch("lyx2lyx", "lyx2lyx");
- if (command.empty()) {
+ string const lyx2lyx = LibFileSearch("lyx2lyx", "lyx2lyx");
+ if (lyx2lyx.empty()) {
Alert::error(_("Conversion script not found"),
bformat(_("%1$s is from an earlier"
" version of LyX, but the"
filename));
return false;
}
- command += " -t"
- + convert<string>(LYX_FORMAT)
- + " -o " + tmpfile + ' '
- + QuoteName(filename);
+ ostringstream command;
+ command << "python " << QuoteName(lyx2lyx)
+ << " -t " << convert<string>(LYX_FORMAT)
+ << " -o " << QuoteName(tmpfile) << ' '
+ << QuoteName(filename);
+ string const command_str = command.str();
+
lyxerr[Debug::INFO] << "Running '"
- << command << '\''
+ << command_str << '\''
<< endl;
- cmd_ret const ret = RunCommand(command);
+
+ cmd_ret const ret = RunCommand(command_str);
if (ret.first != 0) {
Alert::error(_("Conversion script failed"),
bformat(_("%1$s is from an earlier version"
filename));
return false;
} else {
- bool const ret = readFile(tmpfile, pit);
+ bool const ret = readFile(tmpfile);
// Do stuff with tmpfile name and buffer name here.
return ret;
}
//lyxerr << "removing " << MacroTable::localMacros().size()
// << " temporary macro entries" << endl;
//MacroTable::localMacros().clear();
- params().setPaperStuff();
pimpl_->file_fully_loaded = true;
return true;
// good enough. (Lgb)
// But to use this we need fs::copy_file to actually do a copy,
// even when the target file exists. (Lgb)
- if (fs::exists(fileName())) {
+ if (fs::exists(fileName()) && fs::is_writable(fs::path(fileName()).branch_path())) {
//try {
fs::copy_file(fileName(), s, false);
//}
texrow().newline();
texrow().newline();
}
- lyxerr[Debug::INFO] << "lyx header finished" << endl;
+ lyxerr[Debug::INFO] << "lyx document header finished" << endl;
// There are a few differences between nice LaTeX and usual files:
// usual is \batchmode and has a
// special input@path to allow the including of figures
texrow().newline();
}
if (!original_path.empty()) {
- string inputpath = os::external_path(original_path);
- subst(inputpath, "~", "\\string~");
- if (inputpath.find(' ') != string::npos)
- inputpath = '"' + inputpath + '"';
+ string const inputpath = latex_path(original_path);
os << "\\makeatletter\n"
<< "\\def\\input@path{{"
<< inputpath << "/}}\n"
pimpl_->macros = MacroTable::globalMacros();
// Now add our own.
- ParagraphList & pars = text().paragraphs();
+ ParagraphList const & pars = text().paragraphs();
for (size_t i = 0, n = pars.size(); i != n; ++i) {
//lyxerr << "searching main par " << i
// << " for macro definitions" << std::endl;
- InsetList::iterator it = pars[i].insetlist.begin();
- InsetList::iterator end = pars[i].insetlist.end();
+ InsetList const & insets = pars[i].insetlist;
+ InsetList::const_iterator it = insets.begin();
+ InsetList::const_iterator end = insets.end();
for ( ; it != end; ++it) {
//lyxerr << "found inset code " << it->inset->lyxCode() << std::endl;
if (it->inset->lyxCode() == InsetBase::MATHMACRO_CODE) {
- MathMacroTemplate & mac
- = static_cast<MathMacroTemplate &>(*it->inset);
+ MathMacroTemplate const & mac
+ = static_cast<MathMacroTemplate const &>(*it->inset);
insertMacro(mac.name(), mac.asMacroData());
}
}
}
}
+
+
+void Buffer::saveCursor(StableDocIterator cur, StableDocIterator anc)
+{
+ cursor_ = cur;
+ anchor_ = anc;
+}
+
+
+void Buffer::changeRefsIfUnique(string const & from, string const & to)
+{
+ // Check if the label 'from' appears more than once
+ vector<string> labels;
+ getLabelList(labels);
+
+ if (lyx::count(labels.begin(), labels.end(), from) > 1)
+ return;
+
+ InsetBase::Code code = InsetBase::REF_CODE;
+
+ ParIterator it = par_iterator_begin();
+ ParIterator end = par_iterator_end();
+ for ( ; it != end; ++it) {
+ bool changed_inset = false;
+ for (InsetList::iterator it2 = it->insetlist.begin();
+ it2 != it->insetlist.end(); ++it2) {
+ if (it2->inset->lyxCode() == code) {
+ InsetCommand * inset = static_cast<InsetCommand *>(it2->inset);
+ if (inset->getContents() == from) {
+ inset->setContents(to);
+ //inset->setButtonLabel();
+ changed_inset = true;
+ }
+ }
+ }
+ }
+}
+