X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetInclude.cpp;h=89f304db7ea84cb79243da885e46448ecbaee30c;hb=2c357c1d23b7b83839a9beb8225d4f1ae4f793b4;hp=4006bb1d0b97fdfde69b21f2e495d5da09315cbb;hpb=d95451ae5cf740e9f452417b248e0590f8100175;p=lyx.git diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 4006bb1d0b..89f304db7e 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -19,20 +19,18 @@ #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 "TocBackend.h" #include "TextClass.h" +#include "TocBackend.h" #include "frontends/alert.h" #include "frontends/Painter.h" @@ -43,45 +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::makeRelPath; -using support::onlyFilename; -using support::onlyPath; -using support::prefixIs; -using support::subst; -using support::sum; - -using std::find; -using std::string; -using std::istringstream; -using std::ostream; -using std::ostringstream; -using std::vector; - namespace Alert = frontend::Alert; @@ -100,7 +76,7 @@ enum Types { }; -Types type(std::string const & s) +Types type(string const & s) { if (s == "input") return INPUT; @@ -141,6 +117,34 @@ bool isInputOrInclude(InsetCommandParams const & params) 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 @@ -160,18 +164,19 @@ InsetInclude::InsetInclude(InsetInclude const & other) } -CommandInfo const * InsetInclude::findInfo(std::string const & /* cmdName */) +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", "lstparams", ""}; - static const bool isoptional[] = {false, true}; - static const CommandInfo info = {2, paramnames, isoptional}; + 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(std::string const & s) +bool InsetInclude::isCompatibleCommand(string const & s) { return type(s) != NONE; } @@ -196,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 @@ -211,33 +231,6 @@ void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) } -namespace { - -FileName const masterFileName(Buffer const & buffer) -{ - return buffer.masterBuffer()->fileName(); -} - - -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); @@ -288,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)) @@ -313,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) { @@ -336,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 { @@ -356,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 @@ -375,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()))); @@ -455,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, - masterFileName(buffer).onlyPath(), + masterFileName(buffer).onlyPath().absFilename(), runparams, false); runparams.encoding = oldEnc; } else { @@ -463,11 +488,11 @@ 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" @@ -532,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 { @@ -611,7 +634,7 @@ void InsetInclude::validate(LaTeXFeatures & features) const 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"); @@ -654,7 +677,7 @@ void InsetInclude::validate(LaTeXFeatures & features) const void InsetInclude::getLabelList(Buffer const & buffer, - std::vector & list) const + vector & list) const { if (isListings(params())) { InsetListingsParams p(to_utf8(params()["lstparams"])); @@ -665,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)); } } @@ -679,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); } } @@ -690,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; } @@ -822,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(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; } @@ -850,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(); @@ -862,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(to_utf8(params()["lstparams"])); - 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 { - // include and input are temprarily not considered. - if (isVerbatim(params()) || isListings(params())) - files.registerFile(includedFilename(buffer, params()).absFilename(), - false, this); + files.registerFile(includedFilename(buffer, params()), this, buffer); } + +void InsetInclude::updateEmbeddedFile(Buffer const & buf, + EmbeddedFile const & file) +{ + InsetCommandParams p = params(); + p["filename"] = from_utf8(file.outputFilename()); + p["embed"] = file.embedded() ? from_utf8(file.inzipName()) : docstring(); + set(p, buf); +} + + } // namespace lyx