X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Finsets%2FInsetInclude.cpp;h=62804ffd167e48adbcae7999af6e462fc8e70584;hb=700c3dc0ef81de871787a698a0949fb7c26444ca;hp=f50241795e12dc28adb24e761cabc82520eee6ad;hpb=ded962802e5198405dc267542873fb76d4726820;p=lyx.git diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index f50241795e..62804ffd16 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -3,9 +3,8 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Lars Gullik Bjønnes + * \author Lars Gullik Bjønnes * \author Richard Heck (conversion to InsetCommand) - * \author Bo Peng (embedding stuff) * * Full author contact details are available in file CREDITS. */ @@ -14,7 +13,6 @@ #include "InsetInclude.h" -#include "LayoutFile.h" #include "Buffer.h" #include "buffer_funcs.h" #include "BufferList.h" @@ -24,13 +22,17 @@ #include "DispatchResult.h" #include "ErrorList.h" #include "Exporter.h" +#include "Format.h" #include "FuncRequest.h" #include "FuncStatus.h" #include "LaTeXFeatures.h" +#include "LayoutFile.h" +#include "LayoutModuleList.h" #include "LyX.h" #include "LyXRC.h" #include "Lexer.h" #include "MetricsInfo.h" +#include "output_xhtml.h" #include "OutputParams.h" #include "TextClass.h" #include "TocBackend.h" @@ -45,16 +47,17 @@ #include "insets/InsetListingsParams.h" #include "insets/RenderPreview.h" +#include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" #include "support/FileNameList.h" #include "support/filetools.h" #include "support/gettext.h" +#include "support/lassert.h" #include "support/lstrings.h" // contains #include "support/lyxalgo.h" -#include "support/convert.h" -#include +#include "support/bind.h" using namespace std; using namespace lyx::support; @@ -130,55 +133,52 @@ FileName const masterFileName(Buffer const & buffer) void add_preview(RenderMonitoredPreview &, InsetInclude const &, Buffer const &); -string const parentFilename(Buffer const & buffer) +string const parentFileName(Buffer const & buffer) { return buffer.absFileName(); } -EmbeddedFile const includedFilename(Buffer const & buffer, +FileName 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.setInzipName(to_utf8(params["embed"])); - file.enable(buffer.embedded(), &buffer, false); - return file; + return makeAbsPath(to_utf8(params["filename"]), + onlyPath(parentFileName(buffer))); } -InsetLabel * createLabel(docstring const & label_str) + +InsetLabel * createLabel(Buffer * buf, docstring const & label_str) { if (label_str.empty()) return 0; InsetCommandParams icp(LABEL_CODE); icp["name"] = label_str; - return new InsetLabel(icp); + return new InsetLabel(buf, icp); } } // namespace anon -InsetInclude::InsetInclude(InsetCommandParams const & p) - : InsetCommand(p, "include"), include_label(uniqueID()), - preview_(new RenderMonitoredPreview(this)), set_label_(false), label_(0) +InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p) + : InsetCommand(buf, p, "include"), include_label(uniqueID()), + preview_(new RenderMonitoredPreview(this)), failedtoload_(false), + set_label_(false), label_(0), child_buffer_(0) { - preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this)); + preview_->fileChanged(bind(&InsetInclude::fileChanged, this)); if (isListings(params())) { InsetListingsParams listing_params(to_utf8(p["lstparams"])); - label_ = createLabel(from_utf8(listing_params.getParamValue("label"))); + label_ = createLabel(buffer_, from_utf8(listing_params.getParamValue("label"))); } } InsetInclude::InsetInclude(InsetInclude const & other) : InsetCommand(other), include_label(other.include_label), - preview_(new RenderMonitoredPreview(this)), set_label_(false), label_(0) + preview_(new RenderMonitoredPreview(this)), failedtoload_(false), + set_label_(false), label_(0), child_buffer_(0) { - preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this)); + preview_->fileChanged(bind(&InsetInclude::fileChanged, this)); if (other.label_) label_ = new InsetLabel(*other.label_); @@ -187,38 +187,23 @@ InsetInclude::InsetInclude(InsetInclude const & other) InsetInclude::~InsetInclude() { + if (isBufferLoaded()) + buffer_->invalidateBibfileCache(); delete label_; - if (isVerbatim(params()) || isListings(params())) - return; - - - string const parent_filename = buffer().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() != &buffer()) - return; - - //close the buffer. - theBufferList().release(child); } void InsetInclude::setBuffer(Buffer & buffer) { - buffer_ = &buffer; + InsetCommand::setBuffer(buffer); if (label_) label_->setBuffer(buffer); +} + +void InsetInclude::setChildBuffer(Buffer * buffer) +{ + child_buffer_ = buffer; } @@ -231,7 +216,6 @@ ParamInfo const & InsetInclude::findInfo(string const & /* cmdName */) if (param_info_.empty()) { param_info_.add("filename", ParamInfo::LATEX_REQUIRED); param_info_.add("lstparams", ParamInfo::LATEX_OPTIONAL); - param_info_.add("embed", ParamInfo::LYX_INTERNAL); } return param_info_; } @@ -245,31 +229,56 @@ bool InsetInclude::isCompatibleCommand(string const & s) void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) { - BOOST_ASSERT(&cur.buffer() == &buffer()); - switch (cmd.action) { + switch (cmd.action()) { + + case LFUN_INSET_EDIT: { + editIncluded(to_utf8(params()["filename"])); + break; + } case LFUN_INSET_MODIFY: { + // It should be OK just to invalidate the cache in setParams() + // If not.... + // child_buffer_ = 0; InsetCommandParams p(INCLUDE_CODE); - InsetCommandMailer::string2params("include", to_utf8(cmd.argument()), p); + if (cmd.getArg(0) == "changetype") { + InsetCommand::doDispatch(cur, cmd); + p = params(); + } else + InsetCommand::string2params("include", to_utf8(cmd.argument()), p); if (!p.getCmdName().empty()) { - Buffer const & buf = cur.buffer(); if (isListings(p)){ InsetListingsParams new_params(to_utf8(p["lstparams"])); - docstring const label_str = from_utf8(new_params.getParamValue("label")); - if (label_str.empty()) + docstring const new_label = + from_utf8(new_params.getParamValue("label")); + + if (new_label.empty()) { delete label_; - else if (label_) - label_->updateCommand(label_str); - else { - label_ = createLabel(label_str); - label_->setBuffer(buffer()); - label_->initView(); + label_ = 0; + } else { + docstring old_label; + if (label_) + old_label = label_->getParam("name"); + else { + label_ = createLabel(buffer_, new_label); + label_->setBuffer(buffer()); + } + + if (new_label != old_label) { + label_->updateCommand(new_label); + // the label might have been adapted (duplicate) + if (new_label != label_->getParam("name")) { + new_params.addParam("label", "{" + + to_utf8(label_->getParam("name")) + "}", true); + p["lstparams"] = from_utf8(new_params.params()); + } + } } } setParams(p); - buffer().updateBibfilesCache(); + cur.forceBufferUpdate(); } else - cur.noUpdate(); + cur.noScreenUpdate(); break; } @@ -281,8 +290,47 @@ void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd) } +void InsetInclude::editIncluded(string const & file) +{ + string const ext = support::getExtension(file); + if (ext == "lyx") { + FuncRequest fr(LFUN_BUFFER_CHILD_OPEN, file); + lyx::dispatch(fr); + } else + // tex file or other text file in verbatim mode + formats.edit(buffer(), + support::makeAbsPath(file, support::onlyPath(buffer().absFileName())), + "text"); +} + + +bool InsetInclude::getStatus(Cursor & cur, FuncRequest const & cmd, + FuncStatus & flag) const +{ + switch (cmd.action()) { + + case LFUN_INSET_EDIT: + flag.setEnabled(true); + return true; + + case LFUN_INSET_MODIFY: + if (cmd.getArg(0) == "changetype") + return InsetCommand::getStatus(cur, cmd, flag); + else + flag.setEnabled(true); + return true; + + default: + return InsetCommand::getStatus(cur, cmd, flag); + } +} + + void InsetInclude::setParams(InsetCommandParams const & p) { + // invalidate the cache + child_buffer_ = 0; + InsetCommand::setParams(p); set_label_ = false; @@ -291,6 +339,20 @@ void InsetInclude::setParams(InsetCommandParams const & p) if (type(params()) == INPUT) add_preview(*preview_, *this, buffer()); + + buffer().invalidateBibfileCache(); +} + + +bool InsetInclude::isChildIncluded() const +{ + std::list includeonlys = + buffer().params().getIncludedChildren(); + if (includeonlys.empty()) + return true; + return (std::find(includeonlys.begin(), + includeonlys.end(), + to_utf8(params()["filename"])) != includeonlys.end()); } @@ -309,13 +371,16 @@ docstring InsetInclude::screenLabel() const temp = buffer().B_("Verbatim Input*"); break; case INCLUDE: - temp = buffer().B_("Include"); + if (isChildIncluded()) + temp = buffer().B_("Include"); + else + temp += buffer().B_("Include (excluded)"); break; case LISTINGS: temp = listings_label_; break; case NONE: - BOOST_ASSERT(false); + LASSERT(false, /**/); } temp += ": "; @@ -323,56 +388,60 @@ docstring InsetInclude::screenLabel() const if (params()["filename"].empty()) temp += "???"; else - temp += from_utf8(onlyFilename(to_utf8(params()["filename"]))); + temp += from_utf8(onlyFileName(to_utf8(params()["filename"]))); - if (!params()["embed"].empty()) - temp += _(" (embedded)"); return temp; } -/// return the child buffer if the file is a LyX doc and is loaded -Buffer * getChildBuffer(Buffer const & buffer, InsetCommandParams const & params) +Buffer * InsetInclude::getChildBuffer() const { - if (isVerbatim(params) || isListings(params)) - return 0; - - string const included_file = includedFilename(buffer, params).absFilename(); - if (!isLyXFilename(included_file)) - return 0; - - Buffer * childBuffer = loadIfNeeded(buffer, params); + Buffer * childBuffer = loadIfNeeded(); // FIXME: recursive includes - return (childBuffer == &buffer) ? 0 : childBuffer; + return (childBuffer == &buffer()) ? 0 : childBuffer; } -/// return true if the file is or got loaded. -Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params) +Buffer * InsetInclude::loadIfNeeded() const { - if (isVerbatim(params) || isListings(params)) + // This is for background export and preview. We don't even want to + // try to load the cloned child document again. + if (buffer().isClone()) + return child_buffer_; + + // Don't try to load it again if we failed before. + if (failedtoload_ || isVerbatim(params()) || isListings(params())) return 0; - string const parent_filename = parent.absFileName(); - FileName const included_file = makeAbsPath(to_utf8(params["filename"]), - onlyPath(parent_filename)); + FileName const included_file = includedFileName(buffer(), params()); + // Use cached Buffer if possible. + if (child_buffer_ != 0) { + if (theBufferList().isLoaded(child_buffer_) + // additional sanity check: make sure the Buffer really is + // associated with the file we want. + && child_buffer_ == theBufferList().getBuffer(included_file)) + return child_buffer_; + // Buffer vanished, so invalidate cache and try to reload. + child_buffer_ = 0; + } - if (!isLyXFilename(included_file.absFilename())) + if (!isLyXFileName(included_file.absFileName())) return 0; - Buffer * child = theBufferList().getBuffer(included_file.absFilename()); + Buffer * child = theBufferList().getBuffer(included_file); if (!child) { // the readonly flag can/will be wrong, not anymore I think. if (!included_file.exists()) return 0; - child = theBufferList().newBuffer(included_file.absFilename()); + child = theBufferList().newBuffer(included_file.absFileName()); if (!child) // Buffer creation is not possible. return 0; if (!child->loadLyXFile(included_file)) { + failedtoload_ = true; //close the buffer we just opened theBufferList().release(child); return 0; @@ -382,7 +451,9 @@ Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params) // FIXME: Do something. } } - child->setParent(&parent); + child->setParent(&buffer()); + // Cache the child buffer. + child_buffer_ = child; return child; } @@ -395,15 +466,14 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const if (incfile.empty()) return 0; - FileName const included_file = - includedFilename(buffer(), params()).availableFile(); + FileName const included_file = includedFileName(buffer(), params()); // Check we're not trying to include ourselves. // FIXME RECURSIVE INCLUDE // This isn't sufficient, as the inclusion could be downstream. // But it'll have to do for now. if (isInputOrInclude(params()) && - buffer().absFileName() == included_file.absFilename()) + buffer().absFileName() == included_file.absFileName()) { Alert::error(_("Recursive input"), bformat(_("Attempted to include file %1$s in itself! " @@ -415,22 +485,30 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const // if incfile is relative, make it relative to the master // buffer directory. - if (!FileName(incfile).isAbsolute()) { + if (!FileName::isAbsolute(incfile)) { // FIXME UNICODE - incfile = to_utf8(makeRelPath(from_utf8(included_file.absFilename()), + incfile = to_utf8(makeRelPath(from_utf8(included_file.absFileName()), from_utf8(masterBuffer->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(); + string exportfile; + string mangled; + // bug 5681 + if (type(params()) == LISTINGS) { + exportfile = incfile; + mangled = DocFileName(included_file).mangledFileName(); + } else { + exportfile = changeExtension(incfile, ".tex"); + mangled = DocFileName(changeExtension(included_file.absFileName(), ".tex")). + mangledFileName(); + } + FileName const writefile(makeAbsPath(mangled, masterBuffer->temppath())); if (!runparams.nice) incfile = mangled; - else if (!isValidLaTeXFilename(incfile)) { + else if (!isValidLaTeXFileName(incfile)) { frontend::Alert::warning(_("Invalid filename"), _("The following filename is likely to cause trouble " "when running the exported file through LaTeX: ") + @@ -444,14 +522,14 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const //Don't try to load or copy the file if we're //in a comment or doing a dryrun } else if (isInputOrInclude(params()) && - isLyXFilename(included_file.absFilename())) { - //if it's a LyX file and we're inputting or including, - //try to load it so we can write the associated latex - if (!loadIfNeeded(buffer(), params())) + isLyXFileName(included_file.absFileName())) { + // if it's a LyX file and we're inputting or including, + // try to load it so we can write the associated latex + + Buffer * tmp = loadIfNeeded(); + if (!tmp) return false; - Buffer * tmp = theBufferList().getBuffer(included_file.absFilename()); - if (tmp->params().baseClass() != masterBuffer->params().baseClass()) { // FIXME UNICODE docstring text = bformat(_("Included file `%1$s'\n" @@ -460,21 +538,21 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const included_file.displayName(), from_utf8(tmp->params().documentClass().name()), from_utf8(masterBuffer->params().documentClass().name())); - Alert::warning(_("Different textclasses"), text); + Alert::warning(_("Different textclasses"), text, true); } // Make sure modules used in child are all included in master - //FIXME It might be worth loading the children's modules into the master - //over in BufferParams rather than doing this check. - vector const masterModules = masterBuffer->params().getModules(); - vector const childModules = tmp->params().getModules(); - vector::const_iterator it = childModules.begin(); - vector::const_iterator end = childModules.end(); + // FIXME It might be worth loading the children's modules into the master + // over in BufferParams rather than doing this check. + LayoutModuleList const masterModules = masterBuffer->params().getModules(); + LayoutModuleList const childModules = tmp->params().getModules(); + LayoutModuleList::const_iterator it = childModules.begin(); + LayoutModuleList::const_iterator end = childModules.end(); for (; it != end; ++it) { string const module = *it; - vector::const_iterator found = + LayoutModuleList::const_iterator found = find(masterModules.begin(), masterModules.end(), module); - if (found != masterModules.end()) { + if (found == masterModules.end()) { docstring text = bformat(_("Included file `%1$s'\n" "uses module `%2$s'\n" "which is not used in parent file."), @@ -485,18 +563,22 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const tmp->markDepClean(masterBuffer->temppath()); -// FIXME: handle non existing files -// FIXME: 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) + // FIXME: handle non existing files + // FIXME: 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) // The included file might be written in a different encoding + // and language. Encoding const * const oldEnc = runparams.encoding; + Language const * const oldLang = runparams.master_language; runparams.encoding = &tmp->params().encoding(); + runparams.master_language = buffer().params().language; tmp->makeLaTeXFile(writefile, - masterFileName(buffer()).onlyPath().absFilename(), + masterFileName(buffer()).onlyPath().absFileName(), runparams, false); runparams.encoding = oldEnc; + runparams.master_language = oldLang; } else { // In this case, it's not a LyX file, so we copy the file // to the temp dir, so that .aux files etc. are not created @@ -511,7 +593,7 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const LYXERR(Debug::LATEX, to_utf8(bformat(_("Could not copy the file\n%1$s\n" "into the temporary directory."), - from_utf8(included_file.absFilename())))); + from_utf8(included_file.absFileName())))); return 0; } } @@ -519,17 +601,21 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const string const tex_format = (runparams.flavor == OutputParams::LATEX) ? "latex" : "pdflatex"; - if (isVerbatim(params())) { + switch (type(params())) { + case VERB: + case VERBAST: { incfile = latex_path(incfile); // FIXME UNICODE os << '\\' << from_ascii(params().getCmdName()) << '{' << from_utf8(incfile) << '}'; - } else if (type(params()) == INPUT) { + break; + } + case INPUT: { runparams.exportdata->addExternalFile(tex_format, writefile, exportfile); // \input wants file with extension (default is .tex) - if (!isLyXFilename(included_file.absFilename())) { + if (!isLyXFileName(included_file.absFileName())) { incfile = latex_path(incfile); // FIXME UNICODE os << '\\' << from_ascii(params().getCmdName()) @@ -541,7 +627,9 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const os << '\\' << from_ascii(params().getCmdName()) << '{' << from_utf8(incfile) << '}'; } - } else if (type(params()) == LISTINGS) { + break; + } + case LISTINGS: { os << '\\' << from_ascii(params().getCmdName()); string const opt = to_utf8(params()["lstparams"]); // opt is set in QInclude dialog and should have passed validation. @@ -549,7 +637,9 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const if (!params.params().empty()) os << "[" << from_utf8(params.params()) << "]"; os << '{' << from_utf8(incfile) << '}'; - } else { + break; + } + case INCLUDE: { runparams.exportdata->addExternalFile(tex_format, writefile, exportfile); @@ -560,18 +650,71 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const // FIXME UNICODE os << '\\' << from_ascii(params().getCmdName()) << '{' << from_utf8(incfile) << '}'; + break; + } + case NONE: + break; } return 0; } +docstring InsetInclude::xhtml(XHTMLStream & xs, OutputParams const &rp) const +{ + if (rp.inComment) + return docstring(); + + // For verbatim and listings, we just include the contents of the file as-is. + // In the case of listings, we wrap it in
.
+	bool const listing = isListings(params());
+	if (listing || isVerbatim(params())) {
+		if (listing)
+			xs << html::StartTag("pre");
+		// FIXME: We don't know the encoding of the file, default to UTF-8.
+		xs << includedFileName(buffer(), params()).fileContents("UTF-8");
+		if (listing)
+			xs << html::EndTag("pre");
+		return docstring();
+	}
+
+	// We don't (yet) know how to Input or Include non-LyX files.
+	// (If we wanted to get really arcane, we could run some tex2html
+	// converter on the included file. But that's just masochistic.)
+	FileName const included_file = includedFileName(buffer(), params());
+	if (!isLyXFileName(included_file.absFileName())) {
+		frontend::Alert::warning(_("Unsupported Inclusion"),
+					 bformat(_("LyX does not know how to include non-LyX files when "
+					           "generating HTML output. Offending file:\n%1$s"),
+					            params()["filename"]));
+		return docstring();
+	}
+
+	// In the other cases, we will generate the HTML and include it.
+
+	// Check we're not trying to include ourselves.
+	// FIXME RECURSIVE INCLUDE
+	if (buffer().absFileName() == included_file.absFileName()) {
+		Alert::error(_("Recursive input"),
+			       bformat(_("Attempted to include file %1$s in itself! "
+			       "Ignoring inclusion."), params()["filename"]));
+		return docstring();
+	}
+
+	Buffer const * const ibuf = loadIfNeeded();
+	if (!ibuf)
+		return docstring();
+	ibuf->writeLyXHTMLSource(xs.os(), rp, true);
+	return docstring();
+}
+
+
 int InsetInclude::plaintext(odocstream & os, OutputParams const &) const
 {
 	if (isVerbatim(params()) || isListings(params())) {
 		os << '[' << screenLabel() << '\n';
 		// FIXME: We don't know the encoding of the file, default to UTF-8.
-		os << includedFilename(buffer(), params()).fileContents("UTF-8");
+		os << includedFileName(buffer(), params()).fileContents("UTF-8");
 		os << "\n]";
 		return PLAINTEXT_NEWLINE + 1; // one char on a separate line
 	} else {
@@ -590,7 +733,7 @@ int InsetInclude::docbook(odocstream & os, OutputParams const & runparams) const
 	if (incfile.empty())
 		return 0;
 
-	string const included_file = includedFilename(buffer(), params()).absFilename();
+	string const included_file = includedFileName(buffer(), params()).absFileName();
 
 	// Check we're not trying to include ourselves.
 	// FIXME RECURSIVE INCLUDE
@@ -607,10 +750,9 @@ int InsetInclude::docbook(odocstream & os, OutputParams const & runparams) const
 	string const exportfile = changeExtension(incfile, ".sgml");
 	DocFileName writefile(changeExtension(included_file, ".sgml"));
 
-	if (loadIfNeeded(buffer(), params())) {
-		Buffer * tmp = theBufferList().getBuffer(included_file);
-
-		string const mangled = writefile.mangledFilename();
+	Buffer * tmp = loadIfNeeded();
+	if (tmp) {
+		string const mangled = writefile.mangledFileName();
 		writefile = makeAbsPath(mangled,
 					buffer().masterBuffer()->temppath());
 		if (!runparams.nice)
@@ -644,20 +786,20 @@ void InsetInclude::validate(LaTeXFeatures & features) const
 	string incfile = to_utf8(params()["filename"]);
 	string writefile;
 
-	BOOST_ASSERT(&buffer() == &features.buffer());
+	LASSERT(&buffer() == &features.buffer(), /**/);
 
 	string const included_file =
-		includedFilename(buffer(), params()).availableFile().absFilename();
+		includedFileName(buffer(), params()).absFileName();
 
-	if (isLyXFilename(included_file))
+	if (isLyXFileName(included_file))
 		writefile = changeExtension(included_file, ".sgml");
 	else
 		writefile = included_file;
 
 	if (!features.runparams().nice && !isVerbatim(params()) && !isListings(params())) {
-		incfile = DocFileName(writefile).mangledFilename();
+		incfile = DocFileName(writefile).mangledFileName();
 		writefile = makeAbsPath(incfile,
-					buffer().masterBuffer()->temppath()).absFilename();
+					buffer().masterBuffer()->temppath()).absFileName();
 	}
 
 	features.includeFile(include_label, writefile);
@@ -670,9 +812,9 @@ 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(buffer(), params())) {
-		// a file got loaded
-		Buffer * const tmp = theBufferList().getBuffer(included_file);
+	Buffer * const tmp = loadIfNeeded();
+	if (tmp) {
+		// the file is loaded
 		// make sure the buffer isn't us
 		// FIXME RECURSIVE INCLUDES
 		// This is not sufficient, as recursive includes could be
@@ -692,46 +834,16 @@ void InsetInclude::validate(LaTeXFeatures & features) const
 void InsetInclude::fillWithBibKeys(BiblioInfo & keys,
 	InsetIterator const & /*di*/) const
 {
-	if (loadIfNeeded(buffer(), params())) {
-		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->setParent(0);
-		keys.fillWithBibKeys(tmp);
-		tmp->setParent(&buffer());
-	}
-}
-
-
-void InsetInclude::updateBibfilesCache()
-{
-	Buffer * const tmp = getChildBuffer(buffer(), params());
-	if (tmp) {
-		tmp->setParent(0);
-		tmp->updateBibfilesCache();
-		tmp->setParent(&buffer());
-	}
-}
-
-
-EmbeddedFileList const &
-InsetInclude::getBibfilesCache(Buffer const & buffer) const
-{
-	Buffer * const tmp = getChildBuffer(buffer, params());
-	if (tmp) {
-		tmp->setParent(0);
-		EmbeddedFileList const & cache = tmp->getBibfilesCache();
-		tmp->setParent(&buffer);
-		return cache;
-	}
-	static EmbeddedFileList const empty;
-	return empty;
+	Buffer * child = loadIfNeeded();
+	if (!child)
+		return;
+	child->fillWithBibKeys(keys);
 }
 
 
 void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-	BOOST_ASSERT(mi.base.bv);
+	LASSERT(mi.base.bv, /**/);
 
 	bool use_preview = false;
 	if (RenderPreview::status() != LyXRC::PREVIEW_OFF) {
@@ -757,7 +869,7 @@ void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetInclude::draw(PainterInfo & pi, int x, int y) const
 {
-	BOOST_ASSERT(pi.base.bv);
+	LASSERT(pi.base.bv, /**/);
 
 	bool use_preview = false;
 	if (RenderPreview::status() != LyXRC::PREVIEW_OFF) {
@@ -773,6 +885,12 @@ void InsetInclude::draw(PainterInfo & pi, int x, int y) const
 }
 
 
+docstring InsetInclude::contextMenu(BufferView const &, int, int) const
+{
+	return from_ascii("context-include");
+}
+
+
 Inset::DisplayType InsetInclude::display() const
 {
 	return type(params()) == INPUT ? Inline : AlignCenter;
@@ -800,7 +918,7 @@ namespace {
 
 bool preview_wanted(InsetCommandParams const & params, Buffer const & buffer)
 {
-	FileName const included_file = includedFilename(buffer, params);
+	FileName const included_file = includedFileName(buffer, params);
 
 	return type(params) == INPUT && params.preview() &&
 		included_file.isReadableFile();
@@ -826,7 +944,7 @@ void add_preview(RenderMonitoredPreview & renderer, InsetInclude const & inset,
 	InsetCommandParams const & params = inset.params();
 	if (RenderPreview::status() != LyXRC::PREVIEW_OFF &&
 	    preview_wanted(params, buffer)) {
-		renderer.setAbsFile(includedFilename(buffer, params));
+		renderer.setAbsFile(includedFileName(buffer, params));
 		docstring const snippet = latexString(inset);
 		renderer.addPreview(snippet, buffer);
 	}
@@ -835,20 +953,20 @@ void add_preview(RenderMonitoredPreview & renderer, InsetInclude const & inset,
 } // namespace anon
 
 
-void InsetInclude::addPreview(graphics::PreviewLoader & ploader) const
+void InsetInclude::addPreview(DocIterator const & /*inset_pos*/,
+	graphics::PreviewLoader & ploader) const
 {
 	Buffer const & buffer = ploader.buffer();
 	if (!preview_wanted(params(), buffer))
 		return;
-	preview_->setAbsFile(includedFilename(buffer, params()));
+	preview_->setAbsFile(includedFileName(buffer, params()));
 	docstring const snippet = latexString(*this);
 	preview_->addPreview(snippet, ploader);
 }
 
 
-void InsetInclude::addToToc(ParConstIterator const & cpit) const
+void InsetInclude::addToToc(DocIterator const & cpit)
 {
-	bool const embedded_status = !params()["embed"].empty();
 	TocBackend & backend = buffer().tocBackend();
 
 	if (isListings(params())) {
@@ -862,33 +980,20 @@ void InsetInclude::addToToc(ParConstIterator const & cpit) const
 		Toc & toc = backend.toc("listing");
 		docstring str = convert(toc.size() + 1)
 			+ ". " +  from_utf8(caption);
-		if (embedded_status) {
-			backend.toc("embedded").push_back(TocItem(cpit, 0, str));
-			str += _(" (embedded)");
-		}
-		ParConstIterator pit = cpit;
-		pit.push_back(*this);
+		DocIterator pit = cpit;
 		toc.push_back(TocItem(pit, 0, str));
 		return;
 	}
-	Buffer const * const childbuffer = getChildBuffer(buffer(), params());
-	if (!childbuffer) {
-		if (embedded_status) 
-			// Add it to the embedded list nonetheless.
-			backend.toc("embedded").push_back(TocItem(cpit, 0,
-				params()["filename"]));
+	Buffer const * const childbuffer = getChildBuffer();
+	if (!childbuffer)
 		return;
-	}
 
 	Toc & toc = backend.toc("child");
 	docstring str = childbuffer->fileName().displayName();
-	if (embedded_status) {
-		backend.toc("embedded").push_back(TocItem(cpit, 0, str));
-		str += _(" (embedded)");
-	}
 	toc.push_back(TocItem(cpit, 0, str));
 
 	TocList & toclist = backend.tocs();
+	childbuffer->tocBackend().update();
 	TocList const & childtoclist = childbuffer->tocBackend().tocs();
 	TocList::const_iterator it = childtoclist.begin();
 	TocList::const_iterator const end = childtoclist.end();
@@ -898,47 +1003,54 @@ void InsetInclude::addToToc(ParConstIterator const & cpit) const
 }
 
 
-void InsetInclude::updateLabels(ParIterator const & it)
+void InsetInclude::updateCommand()
 {
-	Buffer const * const childbuffer = getChildBuffer(buffer(), params());
+	if (!label_)
+		return;
+
+	docstring old_label = label_->getParam("name");
+	label_->updateCommand(old_label, false);
+	// the label might have been adapted (duplicate)
+	docstring new_label = label_->getParam("name");
+	if (old_label == new_label)
+		return;
+
+	// update listings parameters...
+	InsetCommandParams p(INCLUDE_CODE);
+	p = params();
+	InsetListingsParams par(to_utf8(params()["lstparams"]));
+	par.addParam("label", "{" + to_utf8(new_label) + "}", true);
+	p["lstparams"] = from_utf8(par.params());
+	setParams(p);	
+}
+
+void InsetInclude::updateBuffer(ParIterator const & it, UpdateType utype)
+{
+	Buffer const * const childbuffer = getChildBuffer();
 	if (childbuffer) {
-		lyx::updateLabels(*childbuffer, true);
+		childbuffer->updateBuffer(Buffer::UpdateChildOnly, utype);
 		return;
 	}
 	if (!isListings(params()))
 		return;
 
 	if (label_)
-		label_->updateLabels(it);
+		label_->updateBuffer(it, utype);
 
 	InsetListingsParams const par(to_utf8(params()["lstparams"]));
 	if (par.getParamValue("caption").empty()) {
-		listings_label_.clear();
+		listings_label_ = buffer().B_("Program Listing");
 		return;
 	}
-	Counters & counters = buffer().params().documentClass().counters();
+	Buffer const & master = *buffer().masterBuffer();
+	Counters & counters = master.params().documentClass().counters();
 	docstring const cnt = from_ascii("listing");
-	listings_label_ = buffer().B_("Program Listing");
+	listings_label_ = master.B_("Program Listing");
 	if (counters.hasCounter(cnt)) {
-		counters.step(cnt);
+		counters.step(cnt, utype);
 		listings_label_ += " " + convert(counters.value(cnt));
 	}
 }
 
 
-void InsetInclude::registerEmbeddedFiles(EmbeddedFileList & files) const
-{
-	files.registerFile(includedFilename(buffer(), params()), this, buffer());
-}
-
-
-void InsetInclude::updateEmbeddedFile(EmbeddedFile const & file)
-{
-	InsetCommandParams p = params();
-	p["filename"] = from_utf8(file.outputFilename());
-	p["embed"] = file.embedded() ? from_utf8(file.inzipName()) : docstring();
-	setParams(p);
-}
-
-
 } // namespace lyx