X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetInclude.cpp;h=89f304db7ea84cb79243da885e46448ecbaee30c;hb=2c357c1d23b7b83839a9beb8225d4f1ae4f793b4;hp=b7708c14fa048e9df0bcd5001f26fac252571ed6;hpb=4064d2c468bff8e5d5f4cdd4442d52087d1b137e;p=lyx.git diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index b7708c14fa..89f304db7e 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -4,6 +4,7 @@ * Licence details can be found in the file COPYING. * * \author Lars Gullik Bjønnes + * \author Richard Heck (conversion to InsetCommand) * * Full author contact details are available in file CREDITS. */ @@ -18,18 +19,17 @@ #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 "LyX.h" #include "LyXRC.h" #include "Lexer.h" #include "MetricsInfo.h" #include "OutputParams.h" +#include "TextClass.h" #include "TocBackend.h" #include "frontends/alert.h" @@ -41,46 +41,23 @@ #include "insets/RenderPreview.h" #include "insets/InsetListingsParams.h" +#include "support/debug.h" +#include "support/docstream.h" +#include "support/ExceptionMessage.h" +#include "support/FileNameList.h" #include "support/filetools.h" +#include "support/gettext.h" #include "support/lstrings.h" // contains #include "support/lyxalgo.h" -#include "support/lyxlib.h" #include "support/convert.h" #include +using namespace std; +using namespace lyx::support; 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::getVectorFromString; -using support::isLyXFilename; -using support::isValidLaTeXFilename; -using support::latex_path; -using support::makeAbsPath; -using support::makeDisplayPath; -using support::makeRelPath; -using support::onlyFilename; -using support::onlyPath; -using support::prefixIs; -using support::subst; -using support::sum; - -using std::endl; -using std::find; -using std::string; -using std::istringstream; -using std::ostream; -using std::ostringstream; -using std::vector; - namespace Alert = frontend::Alert; @@ -95,27 +72,29 @@ docstring const uniqueID() /// the type of inclusion enum Types { - INCLUDE = 0, - VERB = 1, - INPUT = 2, - VERBAST = 3, - LISTINGS = 4, + INCLUDE, VERB, INPUT, VERBAST, LISTINGS, NONE }; -Types type(InsetCommandParams const & params) +Types type(string const & s) { - string const command_name = params.getCmdName(); - - if (command_name == "input") + if (s == "input") return INPUT; - if (command_name == "verbatiminput") + if (s == "verbatiminput") return VERB; - if (command_name == "verbatiminput*") + if (s == "verbatiminput*") return VERBAST; - if (command_name == "lstinputlisting") + if (s == "lstinputlisting") return LISTINGS; - return INCLUDE; + if (s == "include") + return INCLUDE; + return NONE; +} + + +Types type(InsetCommandParams const & params) +{ + return type(params.getCmdName()); } @@ -128,14 +107,42 @@ bool isListings(InsetCommandParams const & params) bool isVerbatim(InsetCommandParams const & params) { Types const t = type(params); - return (t == VERB) || (t == VERBAST); + return t == VERB || t == VERBAST; } bool isInputOrInclude(InsetCommandParams const & params) { Types const t = type(params); - return (t == INPUT) || (t == INCLUDE); + return t == INPUT || t == INCLUDE; +} + + +FileName const masterFileName(Buffer const & buffer) +{ + return buffer.masterBuffer()->fileName(); +} + + +void add_preview(RenderMonitoredPreview &, InsetInclude const &, Buffer const &); + + +string const parentFilename(Buffer const & buffer) +{ + return buffer.absFileName(); +} + + +EmbeddedFile const includedFilename(Buffer const & buffer, + InsetCommandParams const & params) +{ + // it is not a good idea to create this EmbeddedFile object + // each time, but there seems to be no easy way around. + EmbeddedFile file(to_utf8(params["filename"]), + onlyPath(parentFilename(buffer))); + file.setEmbed(!params["embed"].empty()); + file.enable(buffer.embedded(), &buffer); + return file; } } // namespace anon @@ -157,6 +164,24 @@ InsetInclude::InsetInclude(InsetInclude const & other) } +CommandInfo const * InsetInclude::findInfo(string const & /* cmdName */) +{ + // FIXME + // This is only correct for the case of listings, but it'll do for now. + // In the other cases, this second parameter should just be empty. + static const char * const paramnames[] = {"filename", "embed", "lstparams", ""}; + static const bool isoptional[] = {false, false, true}; + static const CommandInfo info = {3, paramnames, isoptional}; + return &info; +} + + +bool InsetInclude::isCompatibleCommand(string const & s) +{ + return type(s) != NONE; +} + + void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) { switch (cmd.action) { @@ -166,8 +191,8 @@ void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) InsetCommandMailer::string2params("include", to_utf8(cmd.argument()), p); if (!p.getCmdName().empty()) { if (isListings(p)){ - InsetListingsParams par_old(params().getOptions()); - InsetListingsParams par_new(p.getOptions()); + InsetListingsParams par_old(to_utf8(params()["lstparams"])); + InsetListingsParams par_new(to_utf8(p["lstparams"])); if (par_old.getParamValue("label") != par_new.getParamValue("label") && !par_new.getParamValue("label").empty()) @@ -176,6 +201,21 @@ void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) from_utf8(par_new.getParamValue("label")), REF_CODE); } + try { + // the embed parameter passed back from the dialog + // is "true" or "false", we need to change it. + if (p["embed"] == _("false")) + p["embed"].clear(); + else + p["embed"] = from_utf8(EmbeddedFile(to_utf8(p["filename"]), + onlyPath(parentFilename(cur.buffer()))).inzipName()); + // test parameter + includedFilename(cur.buffer(), p); + } catch (ExceptionMessage const & message) { + Alert::error(message.title_, message.details_); + // do not set parameter if an error happens + break; + } set(p, cur.buffer()); cur.buffer().updateBibfilesCache(); } else @@ -191,33 +231,6 @@ void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) } -namespace { - -string const masterFilename(Buffer const & buffer) -{ - return buffer.masterBuffer()->absFileName(); -} - - -string const parentFilename(Buffer const & buffer) -{ - return buffer.absFileName(); -} - - -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(InsetCommandParams const & p, Buffer const & buffer) { setParams(p); @@ -254,9 +267,11 @@ docstring const InsetInclude::getScreenLabel(Buffer const & buf) const case INCLUDE: temp = buf.B_("Include"); break; - case LISTINGS: { + case LISTINGS: temp = listings_label_; - } + break; + case NONE: + BOOST_ASSERT(false); } temp += ": "; @@ -266,13 +281,13 @@ docstring const InsetInclude::getScreenLabel(Buffer const & buf) const else temp += from_utf8(onlyFilename(to_utf8(params()["filename"]))); + if (!params()["embed"].empty()) + temp += _(" (embedded)"); return temp; } -namespace { - -/// return the child buffer if the file is a LyX doc and is loaded + /// return the child buffer if the file is a LyX doc and is loaded Buffer * getChildBuffer(Buffer const & buffer, InsetCommandParams const & params) { if (isVerbatim(params) || isListings(params)) @@ -291,9 +306,6 @@ Buffer * getChildBuffer(Buffer const & buffer, InsetCommandParams const & params return childBuffer; } -} // namespace anon - - /// return true if the file is or got loaded. Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params) { @@ -314,17 +326,52 @@ Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params) return 0; child = theBufferList().newBuffer(included_file.absFilename()); + if (!child) + // Buffer creation is not possible. + return 0; + if (!child->loadLyXFile(included_file)) { //close the buffer we just opened - theBufferList().close(child, false); + theBufferList().release(child); return 0; } } - child->setParentName(parent_filename); + child->setParent(&parent); return child; } +void resetParentBuffer(Buffer const * parent, InsetCommandParams const & params, + bool close_it) +{ + if (isVerbatim(params) || isListings(params)) + return; + + string const parent_filename = parent->absFileName(); + FileName const included_file = makeAbsPath(to_utf8(params["filename"]), + onlyPath(parent_filename)); + + if (!isLyXFilename(included_file.absFilename())) + return; + + Buffer * child = theBufferList().getBuffer(included_file.absFilename()); + // File not opened, nothing to close. + if (!child) + return; + + // Child document has a different parent, don't close it. + if (child->parent() != parent) + return; + + //close the buffer. + child->setParent(0); + if (close_it) + theBufferList().release(child); + else + updateLabels(*child); +} + + int InsetInclude::latex(Buffer const & buffer, odocstream & os, OutputParams const & runparams) const { @@ -334,7 +381,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, if (incfile.empty()) return 0; - FileName const included_file = includedFilename(buffer, params()); + FileName const included_file = includedFilename(buffer, params()).availableFile(); //Check we're not trying to include ourselves. //FIXME RECURSIVE INCLUDE @@ -353,7 +400,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, // if incfile is relative, make it relative to the master // buffer directory. - if (!absolutePath(incfile)) { + if (!FileName(incfile).isAbsolute()) { // FIXME UNICODE incfile = to_utf8(makeRelPath(from_utf8(included_file.absFilename()), from_utf8(masterBuffer->filePath()))); @@ -374,9 +421,9 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, "when running the exported file through LaTeX: ") + from_utf8(incfile)); } - LYXERR(Debug::LATEX) << "incfile:" << incfile << endl; - LYXERR(Debug::LATEX) << "exportfile:" << exportfile << endl; - LYXERR(Debug::LATEX) << "writefile:" << writefile << endl; + LYXERR(Debug::LATEX, "incfile:" << incfile); + LYXERR(Debug::LATEX, "exportfile:" << exportfile); + LYXERR(Debug::LATEX, "writefile:" << writefile); if (runparams.inComment || runparams.dryrun) { //Don't try to load or copy the file if we're @@ -395,7 +442,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, docstring text = bformat(_("Included file `%1$s'\n" "has textclass `%2$s'\n" "while parent file has textclass `%3$s'."), - makeDisplayPath(included_file.absFilename()), + included_file.displayName(), from_utf8(tmp->params().getTextClass().name()), from_utf8(masterBuffer->params().getTextClass().name())); Alert::warning(_("Different textclasses"), text); @@ -417,7 +464,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, docstring text = bformat(_("Included file `%1$s'\n" "uses module `%2$s'\n" "which is not used in parent file."), - makeDisplayPath(included_file.absFilename()), from_utf8(module)); + included_file.displayName(), from_utf8(module)); Alert::warning(_("Module not found"), text); } } @@ -433,7 +480,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, Encoding const * const oldEnc = runparams.encoding; runparams.encoding = &tmp->params().encoding(); tmp->makeLaTeXFile(writefile, - onlyPath(masterFilename(buffer)), + masterFileName(buffer).onlyPath().absFilename(), runparams, false); runparams.encoding = oldEnc; } else { @@ -441,17 +488,16 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, // 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.cpp. - unsigned long const checksum_in = sum(included_file); - unsigned long const checksum_out = sum(writefile); + unsigned long const checksum_in = included_file.checksum(); + unsigned long const checksum_out = writefile.checksum(); if (checksum_in != checksum_out) { - if (!copy(included_file, writefile)) { + if (!included_file.copyTo(writefile)) { // FIXME UNICODE - LYXERR(Debug::LATEX) - << to_utf8(bformat(_("Could not copy the file\n%1$s\n" + 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; + from_utf8(included_file.absFilename())))); return 0; } } @@ -483,7 +529,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, } } else if (type(params()) == LISTINGS) { os << '\\' << from_ascii(params().getCmdName()); - string opt = params().getOptions(); + string const opt = to_utf8(params()["lstparams"]); // opt is set in QInclude dialog and should have passed validation. InsetListingsParams params(opt); if (!params.params().empty()) @@ -511,10 +557,8 @@ int InsetInclude::plaintext(Buffer const & buffer, odocstream & os, { if (isVerbatim(params()) || isListings(params())) { os << '[' << getScreenLabel(buffer) << '\n'; - // FIXME: We don't know the encoding of the file - docstring const str = - from_utf8(includedFilename(buffer, params()).fileContents()); - os << str; + // FIXME: We don't know the encoding of the file, default to UTF-8. + os << includedFilename(buffer, params()).fileContents("UTF-8"); os << "\n]"; return PLAINTEXT_NEWLINE + 1; // one char on a separate line } else { @@ -560,9 +604,9 @@ int InsetInclude::docbook(Buffer const & buffer, odocstream & os, if (!runparams.nice) incfile = mangled; - LYXERR(Debug::LATEX) << "incfile:" << incfile << endl; - LYXERR(Debug::LATEX) << "exportfile:" << exportfile << endl; - LYXERR(Debug::LATEX) << "writefile:" << writefile << endl; + LYXERR(Debug::LATEX, "incfile:" << incfile); + LYXERR(Debug::LATEX, "exportfile:" << exportfile); + LYXERR(Debug::LATEX, "writefile:" << writefile); tmp->makeDocBookFile(writefile, runparams, true); } @@ -585,12 +629,12 @@ int InsetInclude::docbook(Buffer const & buffer, odocstream & os, void InsetInclude::validate(LaTeXFeatures & features) const { - string incfile(to_utf8(params()["filename"])); + string incfile = to_utf8(params()["filename"]); string writefile; Buffer const & buffer = features.buffer(); - string const included_file = includedFilename(buffer, params()).absFilename(); + string const included_file = includedFilename(buffer, params()).availableFile().absFilename(); if (isLyXFilename(included_file)) writefile = changeExtension(included_file, ".sgml"); @@ -633,10 +677,10 @@ void InsetInclude::validate(LaTeXFeatures & features) const void InsetInclude::getLabelList(Buffer const & buffer, - std::vector & list) const + vector & list) const { if (isListings(params())) { - InsetListingsParams p(params().getOptions()); + InsetListingsParams p(to_utf8(params()["lstparams"])); string label = p.getParamValue("label"); if (!label.empty()) list.push_back(from_utf8(label)); @@ -644,9 +688,9 @@ void InsetInclude::getLabelList(Buffer const & buffer, else if (loadIfNeeded(buffer, params())) { string const included_file = includedFilename(buffer, params()).absFilename(); Buffer * tmp = theBufferList().getBuffer(included_file); - tmp->setParentName(""); + tmp->setParent(0); tmp->getLabelList(list); - tmp->setParentName(parentFilename(buffer)); + tmp->setParent(const_cast(&buffer)); } } @@ -658,9 +702,9 @@ void InsetInclude::fillWithBibKeys(Buffer const & buffer, string const included_file = includedFilename(buffer, params()).absFilename(); Buffer * tmp = theBufferList().getBuffer(included_file); //FIXME This is kind of a dirty hack and should be made reasonable. - tmp->setParentName(""); + tmp->setParent(0); keys.fillWithBibKeys(tmp); - tmp->setParentName(parentFilename(buffer)); + tmp->setParent(&buffer); } } @@ -669,24 +713,24 @@ void InsetInclude::updateBibfilesCache(Buffer const & buffer) { Buffer * const tmp = getChildBuffer(buffer, params()); if (tmp) { - tmp->setParentName(""); + tmp->setParent(0); tmp->updateBibfilesCache(); - tmp->setParentName(parentFilename(buffer)); + tmp->setParent(&buffer); } } -std::vector const & +EmbeddedFileList 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)); + tmp->setParent(0); + EmbeddedFileList const & cache = tmp->getBibfilesCache(); + tmp->setParent(&buffer); return cache; } - static std::vector const empty; + static EmbeddedFileList const empty; return empty; } @@ -749,14 +793,13 @@ Inset::DisplayType InsetInclude::display() const void InsetInclude::fileChanged() const { - Buffer const * const buffer_ptr = LyX::cref().updateInset(this); - if (!buffer_ptr) + Buffer const * const buffer = updateFrontend(); + if (!buffer) return; - Buffer const & buffer = *buffer_ptr; - preview_->removePreview(buffer); - add_preview(*preview_.get(), *this, buffer); - preview_->startLoading(buffer); + preview_->removePreview(*buffer); + add_preview(*preview_.get(), *this, *buffer); + preview_->startLoading(*buffer); } @@ -767,7 +810,7 @@ bool preview_wanted(InsetCommandParams const & params, Buffer const & buffer) FileName const included_file = includedFilename(buffer, params); return type(params) == INPUT && params.preview() && - included_file.isFileReadable(); + included_file.isReadableFile(); } @@ -802,27 +845,27 @@ void add_preview(RenderMonitoredPreview & renderer, InsetInclude const & inset, void InsetInclude::addPreview(graphics::PreviewLoader & ploader) const { 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); - } + if (!preview_wanted(params(), buffer)) + return; + preview_->setAbsFile(includedFilename(buffer, params())); + docstring const snippet = latex_string(*this, buffer); + preview_->addPreview(snippet, ploader); } -void InsetInclude::addToToc(TocList & toclist, Buffer const & buffer, - ParConstIterator const & pit) const +void InsetInclude::addToToc(Buffer const & buffer, + ParConstIterator const & cpit) const { if (isListings(params())) { - InsetListingsParams p(params().getOptions()); + InsetListingsParams p(to_utf8(params()["lstparams"])); string caption = p.getParamValue("caption"); if (caption.empty()) return; - Toc & toc = toclist["listing"]; + Toc & toc = buffer.tocBackend().toc("listing"); docstring const str = convert(toc.size() + 1) + ". " + from_utf8(caption); - // This inset does not have a valid ParConstIterator - // so it has to use the iterator of its parent paragraph + ParConstIterator pit = cpit; + pit.push_back(*this); toc.push_back(TocItem(pit, 0, str)); return; } @@ -830,6 +873,7 @@ void InsetInclude::addToToc(TocList & toclist, Buffer const & buffer, if (!childbuffer) return; + TocList & toclist = buffer.tocBackend().tocs(); TocList const & childtoclist = childbuffer->tocBackend().tocs(); TocList::const_iterator it = childtoclist.begin(); TocList::const_iterator const end = childtoclist.end(); @@ -842,33 +886,43 @@ void InsetInclude::addToToc(TocList & toclist, Buffer const & buffer, void InsetInclude::updateLabels(Buffer const & buffer, ParIterator const &) { Buffer const * const childbuffer = getChildBuffer(buffer, params()); - if (childbuffer) + if (childbuffer) { lyx::updateLabels(*childbuffer, true); - else if (isListings(params())) { - InsetListingsParams const par = params().getOptions(); - if (par.getParamValue("caption").empty()) - listings_label_.clear(); - else { - Counters & counters = buffer.params().getTextClass().counters(); - docstring const cnt = from_ascii("listing"); - if (counters.hasCounter(cnt)) { - counters.step(cnt); - listings_label_ = buffer.B_("Program Listing ") - + convert(counters.value(cnt)); - } else - listings_label_ = buffer.B_("Program Listing"); - } + return; + } + if (!isListings(params())) + return; + + InsetListingsParams const par(to_utf8(params()["lstparams"])); + if (par.getParamValue("caption").empty()) { + listings_label_.clear(); + return; + } + Counters & counters = buffer.params().getTextClass().counters(); + docstring const cnt = from_ascii("listing"); + listings_label_ = buffer.B_("Program Listing"); + if (counters.hasCounter(cnt)) { + counters.step(cnt); + listings_label_ += " " + convert(counters.value(cnt)); } } void InsetInclude::registerEmbeddedFiles(Buffer const & buffer, - EmbeddedFiles & files) const + EmbeddedFileList & files) const +{ + files.registerFile(includedFilename(buffer, params()), this, buffer); +} + + +void InsetInclude::updateEmbeddedFile(Buffer const & buf, + EmbeddedFile const & file) { - // include and input are temprarily not considered. - if (isVerbatim(params()) || isListings(params())) - files.registerFile(includedFilename(buffer, params()).absFilename(), - false, this); + InsetCommandParams p = params(); + p["filename"] = from_utf8(file.outputFilename()); + p["embed"] = file.embedded() ? from_utf8(file.inzipName()) : docstring(); + set(p, buf); } + } // namespace lyx