The attached patch addresses but #7636, which concerns how branches
behave in child documents when they are compiled on their own.
Basically, all branches defined only in the master are treated as off,
because they aren't found. This seems bad.

The problem is that we cut the link to the master document when we
export such files. The patch allows us still to do this, but does it in
a less dramatic way, so that we can still recover the "true" master if
we need it. This seems a bit ugly, but I didn't have a better idea.

Comments?

Richard

>From 3b2be86e5e8769549b8acb61fd815d7b1bd1a3ad Mon Sep 17 00:00:00 2001
From: Richard Heck <rgh...@lyx.org>
Date: Mon, 20 Jun 2011 16:51:26 -0400
Subject: [PATCH] Fix bug #7636.

---
 src/Buffer.cpp             |   34 ++++++++++++++++++++++++++--------
 src/Buffer.h               |    5 +++++
 src/insets/InsetBranch.cpp |   17 +++++++++++++----
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 4fd9a4c..3cf5e83 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -266,10 +266,19 @@ public:
 
 	/// our Text that should be wrapped in an InsetText
 	InsetText * inset;
+	
+	/// if this is set to true, then 
+	bool cut_parent;
+
+	Buffer const * parent() const {
+		if (cut_parent)
+			return 0;
+		return realParent();
+	}
 
 	/// This is here to force the test to be done whenever parent_buffer
 	/// is accessed.
-	Buffer const * parent() const { 
+	Buffer const * realParent() const {
 		// if parent_buffer is not loaded, then it has been unloaded,
 		// which means that parent_buffer is an invalid pointer. So we
 		// set it to null in that case.
@@ -333,7 +342,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_,
 	  read_only(readonly_), filename(file), file_fully_loaded(false),
 	  toc_backend(owner), macro_lock(false), timestamp_(0),
 	  checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false),
-	  bibfile_cache_valid_(false), cite_labels_valid_(false),
+	  bibfile_cache_valid_(false), cite_labels_valid_(false), cut_parent(false), 
 	  cloned_buffer_(cloned_buffer), doing_export(false), parent_buffer(0)
 {
 	if (!cloned_buffer_) {
@@ -1474,18 +1483,15 @@ void Buffer::writeLaTeXSource(otexstream & os,
 	// if we are doing a real file with body, even if this is the
 	// child of some other buffer, let's cut the link here.
 	// This happens for example if only a child document is printed.
-	Buffer const * save_parent = 0;
-	if (output_preamble) {
-		save_parent = d->parent();
-		d->setParent(0);
-	}
+	if (output_preamble)
+		d->cut_parent = true;
 
 	// the real stuff
 	latexParagraphs(*this, text(), os, runparams);
 
 	// Restore the parenthood if needed
 	if (output_preamble)
-		d->setParent(save_parent);
+		d->cut_parent = false;
 
 	// add this just in case after all the paragraphs
 	os << endl;
@@ -2578,6 +2584,18 @@ Buffer const * Buffer::masterBuffer() const
 }
 
 
+Buffer const * Buffer::realMasterBuffer() const
+{
+	// FIXME Should be make sure we are not in some kind
+	// of recursive include? A -> B -> A will crash this.
+	Buffer const * const pbuf = d->realParent();
+	if (!pbuf)
+		return this;
+
+	return pbuf->realMasterBuffer();
+}
+
+
 bool Buffer::isChild(Buffer * child) const
 {
 	return d->children_positions.find(child) != d->children_positions.end();
diff --git a/src/Buffer.h b/src/Buffer.h
index 9701f31..6a49470 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -382,6 +382,11 @@ public:
 	    child document)
 	 */
 	Buffer const * masterBuffer() const;
+	
+	/// this one returns our master buffer, even if we are pretending
+	/// not to have one, as we may be during the export of a child document
+	/// as a standalone document.
+	Buffer const * realMasterBuffer() const;
 
 	/// \return true if \p child is a child of this \c Buffer.
 	bool isChild(Buffer * child) const;
diff --git a/src/insets/InsetBranch.cpp b/src/insets/InsetBranch.cpp
index 4888992..7367eb4 100644
--- a/src/insets/InsetBranch.cpp
+++ b/src/insets/InsetBranch.cpp
@@ -189,15 +189,24 @@ bool InsetBranch::getStatus(Cursor & cur, FuncRequest const & cmd,
 
 bool InsetBranch::isBranchSelected() const
 {
-	Buffer const & realbuffer = *buffer().masterBuffer();
-	BranchList const & branchlist = realbuffer.params().branchlist();
+	Buffer const * const master = buffer().masterBuffer();
+	BranchList const & branchlist = master->params().branchlist();
 	Branch const * ourBranch = branchlist.find(params_.branch);
 
+	// Let's see if we might have a different master buffer somewhere
 	if (!ourBranch) {
-		// this branch is defined in child only
+		Buffer const * const realmaster = buffer().realMasterBuffer();
+		if (master != realmaster)
+			ourBranch = realmaster->params().branchlist().find(params_.branch);
+	}
+	
+	if (!ourBranch) {
+		// this branch may be defined in child only
 		ourBranch = buffer().params().branchlist().find(params_.branch);
-		if (!ourBranch)
+		if (!ourBranch) {
+			LYXERR0("Unable to find branch `" << params_.branch << "'.");
 			return false;
+		}
 	}
 	return ourBranch->isSelected();
 }
-- 
1.7.4.4

Reply via email to