X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetinclude.C;h=36d745ffaab50d50390a14dbced97131035e6018;hb=e28331ed63062dea10d0a21b9ec12034b4b17b9a;hp=ce51bc5eb105b229a07d2d15721497c8a419e8df;hpb=91d100b25f5ec3e16423d4a4fb2f6b785801ca9b;p=lyx.git diff --git a/src/insets/insetinclude.C b/src/insets/insetinclude.C index ce51bc5eb1..36d745ffaa 100644 --- a/src/insets/insetinclude.C +++ b/src/insets/insetinclude.C @@ -17,107 +17,89 @@ #include "bufferlist.h" #include "bufferparams.h" #include "BufferView.h" +#include "cursor.h" #include "debug.h" +#include "dispatchresult.h" +#include "exporter.h" #include "funcrequest.h" +#include "FuncStatus.h" #include "gettext.h" #include "LaTeXFeatures.h" -#include "latexrunparams.h" +#include "lyx_main.h" +#include "lyxrc.h" #include "lyxlex.h" #include "metricsinfo.h" +#include "outputparams.h" +#include "TocBackend.h" +#include "frontends/Alert.h" #include "frontends/Painter.h" -#include "graphics/PreviewedInset.h" #include "graphics/PreviewImage.h" +#include "graphics/PreviewLoader.h" + +#include "insets/render_preview.h" -#include "support/FileInfo.h" -#include "support/FileMonitor.h" #include "support/filetools.h" #include "support/lstrings.h" // contains -#include "support/tostr.h" +#include "support/lyxalgo.h" +#include "support/lyxlib.h" +#include "support/convert.h" #include - -#include "support/std_sstream.h" - -using lyx::support::AddName; -using lyx::support::ChangeExtension; -using lyx::support::contains; -using lyx::support::FileInfo; -using lyx::support::FileMonitor; -using lyx::support::GetFileContents; -using lyx::support::IsFileReadable; -using lyx::support::IsLyXFilename; -using lyx::support::MakeAbsPath; -using lyx::support::MakeDisplayPath; -using lyx::support::OnlyPath; -using lyx::support::subst; +#include + + +namespace lyx { + +using support::addName; +using support::absolutePath; +using support::bformat; +using support::changeExtension; +using support::contains; +using support::copy; +using support::DocFileName; +using support::FileName; +using support::getFileContents; +using support::isFileReadable; +using support::isLyXFilename; +using support::latex_path; +using support::makeAbsPath; +using support::makeDisplayPath; +using support::makeRelPath; +using support::onlyFilename; +using support::onlyPath; +using support::subst; +using support::sum; using std::endl; - +using std::string; using std::auto_ptr; using std::istringstream; using std::ostream; using std::ostringstream; - -extern BufferList bufferlist; - - -class InsetInclude::PreviewImpl : public lyx::graphics::PreviewedInset { -public: - /// - PreviewImpl(InsetInclude & p) : PreviewedInset(p) {} - - /// - bool previewWanted() const; - /// - string const latexString(Buffer const &) const; - /// - InsetInclude const & parent() const { - return dynamic_cast(inset()); - } - - /// - bool monitoring() const { return monitor_.get(); } - /// - void startMonitoring(); - /// - void stopMonitoring() { monitor_.reset(); } - -private: - /// Invoked by monitor_ should the parent file change. - void restartLoading(); - /// - boost::scoped_ptr monitor_; -}; +namespace Alert = frontend::Alert; +namespace fs = boost::filesystem; namespace { -string const uniqueID() +docstring const uniqueID() { static unsigned int seed = 1000; - return "file" + tostr(++seed); + return "file" + convert(++seed); } } // namespace anon -InsetInclude::InsetInclude(Params const & p) +InsetInclude::InsetInclude(InsetCommandParams const & p) : params_(p), include_label(uniqueID()), - preview_(new PreviewImpl(*this)), - set_label_(false) -{} - - -InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b) - : include_label(uniqueID()), - preview_(new PreviewImpl(*this)), + preview_(new RenderMonitoredPreview(this)), set_label_(false) { - params_.cparams = p; - params_.masterFilename_ = b.fileName(); + preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this)); } @@ -125,53 +107,66 @@ InsetInclude::InsetInclude(InsetInclude const & other) : InsetOld(other), params_(other.params_), include_label(other.include_label), - preview_(new PreviewImpl(*this)), - set_label_(other.set_label_) -{} + preview_(new RenderMonitoredPreview(this)), + set_label_(false) +{ + preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this)); +} InsetInclude::~InsetInclude() { - InsetIncludeMailer mailer(*this); - mailer.hideDialog(); + InsetIncludeMailer(*this).hideDialog(); } -dispatch_result InsetInclude::localDispatch(FuncRequest const & cmd) +void InsetInclude::doDispatch(LCursor & cur, FuncRequest & cmd) { switch (cmd.action) { case LFUN_INSET_MODIFY: { - InsetInclude::Params p; - InsetIncludeMailer::string2params(cmd.argument, p); - if (!p.cparams.getCmdName().empty()) { - p.masterFilename_ = cmd.view()->buffer()->fileName(); - set(p); - cmd.view()->updateInset(this); - } - return DISPATCHED; + InsetCommandParams p("include"); + InsetIncludeMailer::string2params(to_utf8(cmd.argument()), p); + if (!p.getCmdName().empty()) { + set(p, cur.buffer()); + cur.buffer().updateBibfilesCache(); + } else + cur.noUpdate(); + break; } case LFUN_INSET_DIALOG_UPDATE: - InsetIncludeMailer(*this).updateDialog(cmd.view()); - return DISPATCHED; + InsetIncludeMailer(*this).updateDialog(&cur.bv()); + break; case LFUN_MOUSE_RELEASE: - if (button_.box().contains(cmd.x, cmd.y)) - InsetIncludeMailer(*this).showDialog(cmd.view()); - return DISPATCHED; + InsetIncludeMailer(*this).showDialog(&cur.bv()); + break; - case LFUN_INSET_DIALOG_SHOW: - InsetIncludeMailer(*this).showDialog(cmd.view()); - return DISPATCHED; + default: + InsetBase::doDispatch(cur, cmd); + break; + } +} + + +bool InsetInclude::getStatus(LCursor & cur, FuncRequest const & cmd, + FuncStatus & flag) const +{ + switch (cmd.action) { + + case LFUN_INSET_MODIFY: + case LFUN_INSET_DIALOG_UPDATE: + flag.enabled(true); + return true; default: - return InsetOld::localDispatch(cmd); + return InsetBase::getStatus(cur, cmd, flag); } } -InsetInclude::Params const & InsetInclude::params() const +InsetCommandParams const & InsetInclude::params() const { return params_; } @@ -188,9 +183,9 @@ enum Types { }; -Types type(InsetInclude::Params const & params) +Types type(InsetCommandParams const & params) { - string const command_name = params.cparams.getCmdName(); + string const command_name = params.getCmdName(); if (command_name == "input") return INPUT; @@ -200,38 +195,57 @@ Types type(InsetInclude::Params const & params) return VERBAST; return INCLUDE; } - -bool isVerbatim(InsetInclude::Params const & params) + +bool isVerbatim(InsetCommandParams const & params) { - string const command_name = params.cparams.getCmdName(); + string const command_name = params.getCmdName(); return command_name == "verbatiminput" || command_name == "verbatiminput*"; } + +string const masterFilename(Buffer const & buffer) +{ + return buffer.getMasterBuffer()->fileName(); +} + + +string const parentFilename(Buffer const & buffer) +{ + return buffer.fileName(); +} + + +FileName const includedFilename(Buffer const & buffer, + InsetCommandParams const & params) +{ + return makeAbsPath(to_utf8(params["filename"]), + onlyPath(parentFilename(buffer))); +} + + +void add_preview(RenderMonitoredPreview &, InsetInclude const &, Buffer const &); + } // namespace anon -void InsetInclude::set(Params const & p) +void InsetInclude::set(InsetCommandParams const & p, Buffer const & buffer) { params_ = p; + set_label_ = false; if (preview_->monitoring()) preview_->stopMonitoring(); - if (lyx::graphics::PreviewedInset::activated() && - type(params_) == INPUT) - preview_->generatePreview(); + if (type(params_) == INPUT) + add_preview(*preview_, *this, buffer); } -auto_ptr InsetInclude::clone() const +auto_ptr InsetInclude::doClone() const { - //Params p(params_); - //p.masterFilename_ = buffer.fileName(); -#warning FIXME: broken cross-doc copy/paste - must fix - - return auto_ptr(new InsetInclude(params_)); + return auto_ptr(new InsetInclude(*this)); } @@ -243,8 +257,8 @@ void InsetInclude::write(Buffer const &, ostream & os) const void InsetInclude::write(ostream & os) const { - os << "Include " << params_.cparams.getCommand() << '\n' - << "preview " << tostr(params_.cparams.preview()) << '\n'; + os << "Include " << to_utf8(params_.getCommand()) << '\n' + << "preview " << convert(params_.preview()) << '\n'; } @@ -256,214 +270,283 @@ void InsetInclude::read(Buffer const &, LyXLex & lex) void InsetInclude::read(LyXLex & lex) { - params_.cparams.read(lex); + if (lex.isOK()) { + lex.next(); + string const command = lex.getString(); + params_.scanCommand(command); + } + string token; + while (lex.isOK()) { + lex.next(); + token = lex.getString(); + if (token == "\\end_inset") + break; + if (token == "preview") { + lex.next(); + params_.preview(lex.getBool()); + } else + lex.printError("Unknown parameter name `$$Token' for command " + params_.getCmdName()); + } + if (token != "\\end_inset") { + lex.printError("Missing \\end_inset at this point. " + "Read: `$$Token'"); + } } -string const InsetInclude::getScreenLabel(Buffer const &) const +docstring const InsetInclude::getScreenLabel(Buffer const &) const { - string temp; + docstring temp; switch (type(params_)) { - case INPUT: temp += _("Input"); break; - case VERB: temp += _("Verbatim Input"); break; - case VERBAST: temp += _("Verbatim Input*"); break; - case INCLUDE: temp += _("Include"); break; + case INPUT: + temp += _("Input"); + break; + case VERB: + temp += _("Verbatim Input"); + break; + case VERBAST: + temp += _("Verbatim Input*"); + break; + case INCLUDE: + temp += _("Include"); + break; } temp += ": "; - if (params_.cparams.getContents().empty()) + if (params_["filename"].empty()) temp += "???"; else - temp += params_.cparams.getContents(); + temp += from_utf8(onlyFilename(to_utf8(params_["filename"]))); return temp; } -string const InsetInclude::getFileName() const +namespace { + +/// return the child buffer if the file is a LyX doc and is loaded +Buffer * getChildBuffer(Buffer const & buffer, InsetCommandParams const & params) { - return MakeAbsPath(params_.cparams.getContents(), - OnlyPath(getMasterFilename())); -} + if (isVerbatim(params)) + return 0; + string const included_file = includedFilename(buffer, params).absFilename(); + if (!isLyXFilename(included_file)) + return 0; -string const InsetInclude::getMasterFilename() const -{ - return params_.masterFilename_; + return theBufferList().getBuffer(included_file); } -bool InsetInclude::loadIfNeeded() const +/// return true if the file is or got loaded. +bool loadIfNeeded(Buffer const & buffer, InsetCommandParams const & params) { - if (isVerbatim(params_)) + if (isVerbatim(params)) return false; - if (!IsLyXFilename(getFileName())) + FileName const included_file = includedFilename(buffer, params); + if (!isLyXFilename(included_file.absFilename())) return false; - if (bufferlist.exists(getFileName())) - return true; - - // the readonly flag can/will be wrong, not anymore I think. - FileInfo finfo(getFileName()); - if (!finfo.isOK()) - return false; - return loadLyXFile(bufferlist.newBuffer(getFileName()), - getFileName()); + Buffer * buf = theBufferList().getBuffer(included_file.absFilename()); + if (!buf) { + // the readonly flag can/will be wrong, not anymore I think. + if (!fs::exists(included_file.toFilesystemEncoding())) + return false; + buf = theBufferList().newBuffer(included_file.absFilename()); + if (!loadLyXFile(buf, included_file)) + return false; + } + if (buf) + buf->setParentName(parentFilename(buffer)); + return buf != 0; } -int InsetInclude::latex(Buffer const & buffer, ostream & os, - LatexRunParams const & runparams) const +} // namespace anon + + +int InsetInclude::latex(Buffer const & buffer, odocstream & os, + OutputParams const & runparams) const { - string incfile(params_.cparams.getContents()); + string incfile(to_utf8(params_["filename"])); // Do nothing if no file name has been specified if (incfile.empty()) return 0; - if (loadIfNeeded()) { - Buffer * tmp = bufferlist.getBuffer(getFileName()); - - // FIXME: this should be a GUI warning - if (tmp->params().textclass != buffer.params().textclass) { - lyxerr << "WARNING: Included file `" - << MakeDisplayPath(getFileName()) - << "' has textclass `" - << tmp->params().getLyXTextClass().name() - << "' while parent file has textclass `" - << buffer.params().getLyXTextClass().name() - << "'." << endl; + FileName const included_file(includedFilename(buffer, params_)); + Buffer const * const m_buffer = buffer.getMasterBuffer(); + + // if incfile is relative, make it relative to the master + // buffer directory. + if (!absolutePath(incfile)) { + incfile = makeRelPath(included_file.absFilename(), + m_buffer->filePath()); + } + + // write it to a file (so far the complete file) + string const exportfile = changeExtension(incfile, ".tex"); + string const mangled = DocFileName(changeExtension(included_file.absFilename(), + ".tex")).mangledFilename(); + FileName const writefile(makeAbsPath(mangled, m_buffer->temppath())); + + if (!runparams.nice) + incfile = mangled; + lyxerr[Debug::LATEX] << "incfile:" << incfile << endl; + lyxerr[Debug::LATEX] << "exportfile:" << exportfile << endl; + lyxerr[Debug::LATEX] << "writefile:" << writefile << endl; + + if (runparams.inComment || runparams.dryrun) + // Don't try to load or copy the file + ; + else if (loadIfNeeded(buffer, params_)) { + Buffer * tmp = theBufferList().getBuffer(included_file.absFilename()); + + if (tmp->params().textclass != m_buffer->params().textclass) { + // FIXME UNICODE + docstring text = bformat(_("Included file `%1$s'\n" + "has textclass `%2$s'\n" + "while parent file has textclass `%3$s'."), + makeDisplayPath(included_file.absFilename()), + from_utf8(tmp->params().getLyXTextClass().name()), + from_utf8(m_buffer->params().getLyXTextClass().name())); + Alert::warning(_("Different textclasses"), text); //return 0; } - // write it to a file (so far the complete file) - string writefile = ChangeExtension(getFileName(), ".tex"); + tmp->markDepClean(m_buffer->temppath()); - if (!buffer.temppath().empty() && !runparams.nice) { - incfile = subst(incfile, '/','@'); -#ifdef __EMX__ - incfile = subst(incfile, ':', '$'); +#ifdef WITH_WARNINGS +#warning handle non existing files +#warning Second argument is irrelevant! +// since only_body is true, makeLaTeXFile will not look at second +// argument. Should we set it to string(), or should makeLaTeXFile +// make use of it somehow? (JMarc 20031002) #endif - writefile = AddName(buffer.temppath(), incfile); - } else - writefile = getFileName(); - writefile = ChangeExtension(writefile, ".tex"); - lyxerr[Debug::LATEX] << "incfile:" << incfile << endl; - lyxerr[Debug::LATEX] << "writefile:" << writefile << endl; - - tmp->markDepClean(buffer.temppath()); - - tmp->makeLaTeXFile(writefile, OnlyPath(getMasterFilename()), + tmp->makeLaTeXFile(writefile, + onlyPath(masterFilename(buffer)), runparams, false); + } else { + // Copy the file to the temp dir, so that .aux files etc. + // are not created in the original dir. Files included by + // this file will be found via input@path, see ../buffer.C. + unsigned long const checksum_in = sum(included_file); + unsigned long const checksum_out = sum(writefile); + + if (checksum_in != checksum_out) { + if (!copy(included_file, writefile)) { + // FIXME UNICODE + lyxerr[Debug::LATEX] + << to_utf8(bformat(_("Could not copy the file\n%1$s\n" + "into the temporary directory."), + from_utf8(included_file.absFilename()))) + << endl; + return 0; + } + } } + string const tex_format = (runparams.flavor == OutputParams::LATEX) ? + "latex" : "pdflatex"; if (isVerbatim(params_)) { - os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}'; + incfile = latex_path(incfile); + // FIXME UNICODE + os << '\\' << from_ascii(params_.getCmdName()) << '{' + << from_utf8(incfile) << '}'; } else if (type(params_) == INPUT) { + runparams.exportdata->addExternalFile(tex_format, writefile, + exportfile); + // \input wants file with extension (default is .tex) - if (!IsLyXFilename(getFileName())) { - os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}'; + if (!isLyXFilename(included_file.absFilename())) { + incfile = latex_path(incfile); + // FIXME UNICODE + os << '\\' << from_ascii(params_.getCmdName()) + << '{' << from_utf8(incfile) << '}'; } else { - os << '\\' << params_.cparams.getCmdName() << '{' - << ChangeExtension(incfile, ".tex") - << '}'; + incfile = changeExtension(incfile, ".tex"); + incfile = latex_path(incfile); + // FIXME UNICODE + os << '\\' << from_ascii(params_.getCmdName()) + << '{' << from_utf8(incfile) << '}'; } } else { + runparams.exportdata->addExternalFile(tex_format, writefile, + exportfile); + // \include don't want extension and demands that the // file really have .tex - os << '\\' << params_.cparams.getCmdName() << '{' - << ChangeExtension(incfile, string()) - << '}'; + incfile = changeExtension(incfile, string()); + incfile = latex_path(incfile); + // FIXME UNICODE + os << '\\' << from_ascii(params_.getCmdName()) << '{' + << from_utf8(incfile) << '}'; } return 0; } -int InsetInclude::ascii(Buffer const &, ostream & os, int) const +int InsetInclude::plaintext(Buffer const & buffer, odocstream & os, + OutputParams const &) const { - if (isVerbatim(params_)) - os << GetFileContents(getFileName()); + if (isVerbatim(params_)) { + // FIXME: We don't know the encoding of the file + docstring const str = from_utf8( + getFileContents(includedFilename(buffer, params_))); + os << str; + // Return how many newlines we issued. + return int(lyx::count(str.begin(), str.end(), '\n')); + } return 0; } -int InsetInclude::linuxdoc(Buffer const & buffer, ostream & os) const +int InsetInclude::docbook(Buffer const & buffer, odocstream & os, + OutputParams const & runparams) const { - string incfile(params_.cparams.getContents()); + string incfile = to_utf8(params_["filename"]); // Do nothing if no file name has been specified if (incfile.empty()) return 0; - if (loadIfNeeded()) { - Buffer * tmp = bufferlist.getBuffer(getFileName()); + string const included_file = includedFilename(buffer, params_).absFilename(); - // write it to a file (so far the complete file) - string writefile = ChangeExtension(getFileName(), ".sgml"); - if (!buffer.temppath().empty() && !buffer.niceFile()) { - incfile = subst(incfile, '/','@'); - writefile = AddName(buffer.temppath(), incfile); - } else - writefile = getFileName(); - - if (IsLyXFilename(getFileName())) - writefile = ChangeExtension(writefile, ".sgml"); - - lyxerr[Debug::LATEX] << "incfile:" << incfile << endl; - lyxerr[Debug::LATEX] << "writefile:" << writefile << endl; + // write it to a file (so far the complete file) + string const exportfile = changeExtension(incfile, ".sgml"); + DocFileName writefile(changeExtension(included_file, ".sgml")); - tmp->makeLinuxDocFile(writefile, buffer.niceFile(), true); - } + if (loadIfNeeded(buffer, params_)) { + Buffer * tmp = theBufferList().getBuffer(included_file); - if (isVerbatim(params_)) { - os << ""; - } else - os << '&' << include_label << ';'; - - return 0; -} - - -int InsetInclude::docbook(Buffer const & buffer, ostream & os, - bool /*mixcont*/) const -{ - string incfile(params_.cparams.getContents()); - - // Do nothing if no file name has been specified - if (incfile.empty()) - return 0; - - if (loadIfNeeded()) { - Buffer * tmp = bufferlist.getBuffer(getFileName()); - - // write it to a file (so far the complete file) - string writefile = ChangeExtension(getFileName(), ".sgml"); - if (!buffer.temppath().empty() && !buffer.niceFile()) { - incfile = subst(incfile, '/','@'); - writefile = AddName(buffer.temppath(), incfile); - } else - writefile = getFileName(); - if (IsLyXFilename(getFileName())) - writefile = ChangeExtension(writefile, ".sgml"); + string const mangled = writefile.mangledFilename(); + writefile = makeAbsPath(mangled, + buffer.getMasterBuffer()->temppath()); + if (!runparams.nice) + incfile = mangled; lyxerr[Debug::LATEX] << "incfile:" << incfile << endl; + lyxerr[Debug::LATEX] << "exportfile:" << exportfile << endl; lyxerr[Debug::LATEX] << "writefile:" << writefile << endl; - tmp->makeDocBookFile(writefile, buffer.niceFile(), true); + tmp->makeDocBookFile(writefile, runparams, true); } + runparams.exportdata->addExternalFile("docbook", writefile, + exportfile); + runparams.exportdata->addExternalFile("docbook-xml", writefile, + exportfile); + if (isVerbatim(params_)) { os << ""; } else - os << '&' << include_label << ';'; + os << '&' << include_label << ';'; return 0; } @@ -471,19 +554,23 @@ int InsetInclude::docbook(Buffer const & buffer, ostream & os, void InsetInclude::validate(LaTeXFeatures & features) const { - string incfile(params_.cparams.getContents()); + string incfile(to_utf8(params_["filename"])); string writefile; - Buffer const & b = features.buffer(); + Buffer const & buffer = features.buffer(); - if (!b.temppath().empty() && !b.niceFile() && !isVerbatim(params_)) { - incfile = subst(incfile, '/','@'); - writefile = AddName(b.temppath(), incfile); - } else - writefile = getFileName(); + string const included_file = includedFilename(buffer, params_).absFilename(); - if (IsLyXFilename(getFileName())) - writefile = ChangeExtension(writefile, ".sgml"); + if (isLyXFilename(included_file)) + writefile = changeExtension(included_file, ".sgml"); + else + writefile = included_file; + + if (!features.runparams().nice && !isVerbatim(params_)) { + incfile = DocFileName(writefile).mangledFilename(); + writefile = makeAbsPath(incfile, + buffer.getMasterBuffer()->temppath()).absFilename(); + } features.includeFile(include_label, writefile); @@ -493,128 +580,217 @@ void InsetInclude::validate(LaTeXFeatures & features) const // Here we must do the fun stuff... // Load the file in the include if it needs // to be loaded: - if (loadIfNeeded()) { + if (loadIfNeeded(buffer, params_)) { // a file got loaded - Buffer * const tmp = bufferlist.getBuffer(getFileName()); + Buffer * const tmp = theBufferList().getBuffer(included_file); if (tmp) { - tmp->niceFile() = b.niceFile(); + // We must temporarily change features.buffer, + // otherwise it would always be the master buffer, + // and nested includes would not work. + features.setBuffer(*tmp); tmp->validate(features); + features.setBuffer(buffer); } } } -void InsetInclude::getLabelList(std::vector & list) const +void InsetInclude::getLabelList(Buffer const & buffer, + std::vector & list) const { - if (loadIfNeeded()) { - Buffer * tmp = bufferlist.getBuffer(getFileName()); + if (loadIfNeeded(buffer, params_)) { + string const included_file = includedFilename(buffer, params_).absFilename(); + Buffer * tmp = theBufferList().getBuffer(included_file); tmp->setParentName(""); tmp->getLabelList(list); - tmp->setParentName(getMasterFilename()); + tmp->setParentName(parentFilename(buffer)); } } -void InsetInclude::fillWithBibKeys(std::vector > & keys) const +void InsetInclude::fillWithBibKeys(Buffer const & buffer, + std::vector > & keys) const { - if (loadIfNeeded()) { - Buffer * tmp = bufferlist.getBuffer(getFileName()); + if (loadIfNeeded(buffer, params_)) { + string const included_file = includedFilename(buffer, params_).absFilename(); + Buffer * tmp = theBufferList().getBuffer(included_file); tmp->setParentName(""); tmp->fillWithBibKeys(keys); - tmp->setParentName(getMasterFilename()); + tmp->setParentName(parentFilename(buffer)); + } +} + + +void InsetInclude::updateBibfilesCache(Buffer const & buffer) +{ + Buffer * const tmp = getChildBuffer(buffer, params_); + if (tmp) { + tmp->setParentName(""); + tmp->updateBibfilesCache(); + tmp->setParentName(parentFilename(buffer)); + } +} + + +std::vector const & +InsetInclude::getBibfilesCache(Buffer const & buffer) const +{ + Buffer * const tmp = getChildBuffer(buffer, params_); + if (tmp) { + tmp->setParentName(""); + std::vector const & cache = tmp->getBibfilesCache(); + tmp->setParentName(parentFilename(buffer)); + return cache; } + static std::vector const empty; + return empty; } -void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const +bool InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const { - if (preview_->previewReady()) { - dim.asc = preview_->pimage()->ascent(); - dim.des = preview_->pimage()->descent(); - dim.wid = preview_->pimage()->width(); + BOOST_ASSERT(mi.base.bv && mi.base.bv->buffer()); + + bool use_preview = false; + if (RenderPreview::status() != LyXRC::PREVIEW_OFF) { + graphics::PreviewImage const * pimage = + preview_->getPreviewImage(*mi.base.bv->buffer()); + use_preview = pimage && pimage->image(); + } + + if (use_preview) { + preview_->metrics(mi, dim); } else { if (!set_label_) { set_label_ = true; button_.update(getScreenLabel(*mi.base.bv->buffer()), - editable() != NOT_EDITABLE); + true); } button_.metrics(mi, dim); } - int center_indent = type(params_) == INPUT ? - 0 : (mi.base.textwidth - dim.wid) / 2; - Box b(center_indent, center_indent + dim.wid, -dim.asc, dim.des); + + Box b(0, dim.wid, -dim.asc, dim.des); button_.setBox(b); - dim.wid = mi.base.textwidth; + bool const changed = dim_ != dim; dim_ = dim; + return changed; } void InsetInclude::draw(PainterInfo & pi, int x, int y) const { - cache(pi.base.bv); - if (!preview_->previewReady()) { - button_.draw(pi, x + button_.box().x1, y); - return; - } + setPosCache(pi, x, y); - if (!preview_->monitoring()) - preview_->startMonitoring(); + BOOST_ASSERT(pi.base.bv && pi.base.bv->buffer()); - pi.pain.image(x + button_.box().x1, y - dim_.asc, dim_.wid, dim_.height(), - *(preview_->pimage()->image())); -} + bool use_preview = false; + if (RenderPreview::status() != LyXRC::PREVIEW_OFF) { + graphics::PreviewImage const * pimage = + preview_->getPreviewImage(*pi.base.bv->buffer()); + use_preview = pimage && pimage->image(); + } + if (use_preview) + preview_->draw(pi, x, y); + else + button_.draw(pi, x, y); +} -BufferView * InsetInclude::view() const +bool InsetInclude::display() const { - return button_.view(); + return type(params_) != INPUT; } + // // preview stuff // -void InsetInclude::addPreview(lyx::graphics::PreviewLoader & ploader) const +void InsetInclude::fileChanged() const { - preview_->addPreview(ploader); + Buffer const * const buffer_ptr = LyX::cref().updateInset(this); + if (!buffer_ptr) + return; + + Buffer const & buffer = *buffer_ptr; + preview_->removePreview(buffer); + add_preview(*preview_.get(), *this, buffer); + preview_->startLoading(buffer); } -bool InsetInclude::PreviewImpl::previewWanted() const +namespace { + +bool preview_wanted(InsetCommandParams const & params, Buffer const & buffer) { - return type(parent().params_) == INPUT && - parent().params_.cparams.preview() && - IsFileReadable(parent().getFileName()); + FileName const included_file = includedFilename(buffer, params); + + return type(params) == INPUT && params.preview() && + isFileReadable(included_file); } -string const InsetInclude::PreviewImpl::latexString(Buffer const & buffer) const +docstring const latex_string(InsetInclude const & inset, Buffer const & buffer) { - ostringstream os; - LatexRunParams runparams; - runparams.flavor = LatexRunParams::LATEX; - parent().latex(buffer, os, runparams); + odocstringstream os; + OutputParams runparams; + runparams.flavor = OutputParams::LATEX; + inset.latex(buffer, os, runparams); return os.str(); } -void InsetInclude::PreviewImpl::startMonitoring() +void add_preview(RenderMonitoredPreview & renderer, InsetInclude const & inset, + Buffer const & buffer) { - monitor_.reset(new FileMonitor(parent().getFileName(), 2000)); - monitor_->connect(boost::bind(&PreviewImpl::restartLoading, this)); - monitor_->start(); + InsetCommandParams const & params = inset.params(); + if (RenderPreview::status() != LyXRC::PREVIEW_OFF && + preview_wanted(params, buffer)) { + renderer.setAbsFile(includedFilename(buffer, params)); + docstring const snippet = latex_string(inset, buffer); + renderer.addPreview(snippet, buffer); + } } +} // namespace anon + -void InsetInclude::PreviewImpl::restartLoading() +void InsetInclude::addPreview(graphics::PreviewLoader & ploader) const { - removePreview(); - if (view()) - view()->updateInset(&parent()); - generatePreview(); + Buffer const & buffer = ploader.buffer(); + if (preview_wanted(params(), buffer)) { + preview_->setAbsFile(includedFilename(buffer, params())); + docstring const snippet = latex_string(*this, buffer); + preview_->addPreview(snippet, ploader); + } +} + + +void InsetInclude::addToToc(TocList & toclist, Buffer const & buffer) const +{ + Buffer const * const childbuffer = getChildBuffer(buffer, params_); + if (!childbuffer) + return; + + TocList const & childtoclist = childbuffer->tocBackend().tocs(); + TocList::const_iterator it = childtoclist.begin(); + TocList::const_iterator const end = childtoclist.end(); + for(; it != end; ++it) + toclist[it->first].insert(toclist[it->first].end(), + it->second.begin(), it->second.end()); +} + + +void InsetInclude::updateLabels(Buffer const & buffer) const +{ + Buffer const * const childbuffer = getChildBuffer(buffer, params_); + if (!childbuffer) + return; + + lyx::updateLabels(*childbuffer, true); } @@ -632,10 +808,9 @@ string const InsetIncludeMailer::inset2string(Buffer const &) const void InsetIncludeMailer::string2params(string const & in, - InsetInclude::Params & params) + InsetCommandParams & params) { - params = InsetInclude::Params(); - + params.clear(); if (in.empty()) return; @@ -643,38 +818,34 @@ void InsetIncludeMailer::string2params(string const & in, LyXLex lex(0,0); lex.setStream(data); - if (lex.isOK()) { - lex.next(); - string const token = lex.getString(); - if (token != name_) - return; - } + string name; + lex >> name; + if (!lex || name != name_) + return print_mailer_error("InsetIncludeMailer", in, 1, name_); // This is part of the inset proper that is usually swallowed - // by Buffer::readInset - if (lex.isOK()) { - lex.next(); - string const token = lex.getString(); - if (token != "Include") - return; - } + // by LyXText::readInset + string id; + lex >> id; + if (!lex || id != "Include") + return print_mailer_error("InsetIncludeMailer", in, 2, "Include"); - if (lex.isOK()) { - InsetInclude inset(params); - inset.read(lex); - params = inset.params(); - } + InsetInclude inset(params); + inset.read(lex); + params = inset.params(); } string const -InsetIncludeMailer::params2string(InsetInclude::Params const & params) +InsetIncludeMailer::params2string(InsetCommandParams const & params) { InsetInclude inset(params); - inset.set(params); ostringstream data; data << name_ << ' '; inset.write(data); data << "\\end_inset\n"; return data.str(); } + + +} // namespace lyx