Enrico Forestieri wrote:
> Good work, Jürgen. However, there are still some issues. The ref inset
> is not updated when it is inside a \tag or \text inset, for example.

OK, we also need to implement updateLabels in InsetMathNest. The attached 
patch should fix this problem.

> Another problem is that I get a crash when I cut and paste an existing
> ref inset into a \text inset and then try to modify the referenced label. 

This is yet another uninitialized buffer_. No idea where that comes from.

Jürgen
Index: src/insets/InsetLabel.cpp
===================================================================
--- src/insets/InsetLabel.cpp	(Revision 33238)
+++ src/insets/InsetLabel.cpp	(Arbeitskopie)
@@ -32,6 +32,9 @@
 #include "TextClass.h"
 #include "TocBackend.h"
 
+#include "mathed/InsetMathHull.h"
+#include "mathed/InsetMathRef.h"
+
 #include "frontends/alert.h"
 
 #include "support/convert.h"
@@ -82,7 +85,15 @@
 		Buffer::References::iterator end = refs.end();
 		for (; it != end; ++it) {
 			buffer().undo().recordUndo(it->second);
-			it->first->setParam("reference", label);
+			if (it->first->lyxCode() == MATH_REF_CODE) {
+				InsetMathHull * mi =
+					static_cast<InsetMathHull *>(it->first);
+				mi->asRefInset()->changeTarget(label);
+			} else {
+				InsetCommand * ref =
+					static_cast<InsetCommand *>(it->first);
+				ref->setParam("reference", label);
+			}
 		}
 	}
 	buffer().undo().endUndoGroup();
@@ -150,7 +161,13 @@
 	Buffer::References::const_iterator end = refs.end();
 	for (; it != end; ++it) {
 		DocIterator const ref_pit(it->second);
-		toc.push_back(TocItem(ref_pit, 1, it->first->screenLabel()));
+		if (it->first->lyxCode() == MATH_REF_CODE)
+			toc.push_back(TocItem(ref_pit, 1,
+				static_cast<InsetMathHull *>(it->first)->asRefInset()
+					->screenLabel()));
+		else
+			toc.push_back(TocItem(ref_pit, 1,
+				static_cast<InsetRef *>(it->first)->screenLabel()));
 	}
 }
 
Index: src/mathed/InsetMathGrid.cpp
===================================================================
--- src/mathed/InsetMathGrid.cpp	(Revision 33238)
+++ src/mathed/InsetMathGrid.cpp	(Arbeitskopie)
@@ -634,6 +634,14 @@
 }
 
 
+void InsetMathGrid::updateLabels(ParIterator const & it, UpdateType utype)
+{
+	// pass down
+	for (idx_type idx = 0; idx < nargs(); ++idx)
+		cell(idx).updateLabels(it, utype);
+}
+
+
 docstring InsetMathGrid::eolString(row_type row, bool fragile) const
 {
 	docstring eol;
Index: src/mathed/InsetMathHull.cpp
===================================================================
--- src/mathed/InsetMathHull.cpp	(Revision 33238)
+++ src/mathed/InsetMathHull.cpp	(Arbeitskopie)
@@ -225,6 +225,8 @@
 		if (label_[i])
 			label_[i]->updateLabels(it, utype);
 	}
+	// pass down
+	InsetMathGrid::updateLabels(it, utype);
 }
 
 
Index: src/mathed/InsetMathGrid.h
===================================================================
--- src/mathed/InsetMathGrid.h	(Revision 33238)
+++ src/mathed/InsetMathGrid.h	(Arbeitskopie)
@@ -112,6 +112,8 @@
 	void metricsT(TextMetricsInfo const & mi, Dimension & dim) const;
 	///
 	void drawT(TextPainter & pi, int x, int y) const;
+	///
+	void updateLabels(ParIterator const &, UpdateType);
 	/// extract number of columns from alignment string
 	static col_type guessColumns(docstring const & halign);
 	/// accepts some LaTeX column codes: p,m,!,@,M,<,>
Index: src/mathed/MathData.h
===================================================================
--- src/mathed/MathData.h	(Revision 33238)
+++ src/mathed/MathData.h	(Arbeitskopie)
@@ -18,6 +18,8 @@
 #include "Dimension.h"
 #include "MathAtom.h"
 
+#include "OutputEnums.h"
+
 #include "support/strfwd.h"
 
 #include <vector>
@@ -35,6 +37,7 @@
 class MathMacro;
 class MetricsInfo;
 class PainterInfo;
+class ParIterator;
 class TextMetricsInfo;
 class TextPainter;
 
@@ -164,6 +167,8 @@
 	/// attach/detach arguments to macros, updating the cur to 
 	/// stay visually at the same position (cur==0 is allowed)
 	void updateMacros(Cursor * cur, MacroContext const & mc);
+	///
+	void updateLabels(ParIterator const &, UpdateType);
 
 protected:
 	/// cached values for super/subscript placement
Index: src/mathed/MathData.cpp
===================================================================
--- src/mathed/MathData.cpp	(Revision 33238)
+++ src/mathed/MathData.cpp	(Arbeitskopie)
@@ -377,6 +377,16 @@
 }
 
 
+void MathData::updateLabels(ParIterator const & it, UpdateType utype)
+{
+	// pass down
+	for (size_t i = 0, n = size(); i != n; ++i) {
+		MathAtom & at = operator[](i);
+		at.nucleus()->updateLabels(it, utype);
+	}
+}
+
+
 void MathData::updateMacros(Cursor * cur, MacroContext const & mc)
 {
 	// If we are editing a macro, we cannot update it immediately,
Index: src/mathed/InsetMathRef.cpp
===================================================================
--- src/mathed/InsetMathRef.cpp	(Revision 33238)
+++ src/mathed/InsetMathRef.cpp	(Arbeitskopie)
@@ -23,6 +23,7 @@
 #include "MathFactory.h"
 #include "MathSupport.h"
 #include "OutputParams.h"
+#include "ParIterator.h"
 #include "sgml.h"
 
 #include "insets/InsetCommand.h"
@@ -175,6 +176,17 @@
 }
 
 
+void InsetMathRef::updateLabels(ParIterator const & it, UpdateType /*utype*/)
+{
+	if (!buffer_) {
+		LYXERR0("InsetMathRef::updateLabels: no buffer_!");
+		return;
+	}
+	// register this inset into the buffer reference cache.
+	buffer().references(getTarget()).push_back(make_pair(this, it));
+}
+
+
 string const InsetMathRef::createDialogStr(string const & name) const
 {
 	InsetCommandParams icp(REF_CODE, to_ascii(commandname()));
@@ -185,6 +197,28 @@
 }
 
 
+docstring const InsetMathRef::getTarget() const
+{
+	return asString(cell(0));
+}
+
+
+void InsetMathRef::changeTarget(docstring const & target)
+{
+	InsetCommandParams icp(REF_CODE, to_ascii(commandname()));
+	icp["reference"] = target;
+	if (!cell(1).empty())
+		icp["name"] = asString(cell(1));
+	MathData ar;
+	Buffer & buf = buffer();
+	if (createInsetMath_fromDialogStr(
+	    from_utf8(InsetCommand::params2string("ref", icp)), ar)) {
+		*this = *ar[0].nucleus()->asRefInset();
+		setBuffer(buf);
+	}
+}
+
+
 InsetMathRef::ref_type_info InsetMathRef::types[] = {
 	{ from_ascii("ref"),       from_ascii(N_("Standard[[mathref]]")),   from_ascii(N_("Ref: "))},
 	{ from_ascii("eqref"),     from_ascii(N_("Equation")),              from_ascii(N_("EqRef: "))},
Index: src/mathed/InsetMathNest.cpp
===================================================================
--- src/mathed/InsetMathNest.cpp	(Revision 33238)
+++ src/mathed/InsetMathNest.cpp	(Arbeitskopie)
@@ -173,6 +173,14 @@
 }
 
 
+void InsetMathNest::updateLabels(ParIterator const & it, UpdateType utype)
+{
+	for (idx_type i = 0, n = nargs(); i != n; ++i)
+		cell(i).updateLabels(it, utype);
+}
+
+
+
 bool InsetMathNest::idxNext(Cursor & cur) const
 {
 	LASSERT(&cur.inset() == this, /**/);
Index: src/mathed/InsetMathRef.h
===================================================================
--- src/mathed/InsetMathRef.h	(Revision 33238)
+++ src/mathed/InsetMathRef.h	(Arbeitskopie)
@@ -27,6 +27,8 @@
 	///
 	explicit InsetMathRef(Buffer * buf, docstring const & data);
 	///
+	void updateLabels(ParIterator const &, UpdateType);
+	///
 	//void write(WriteStream & os) const;
 	///
 	void infoize(odocstream & os) const;
@@ -35,6 +37,8 @@
 	///
 	void validate(LaTeXFeatures & features) const;
 	///
+	void changeTarget(docstring const & target);
+	///
 	virtual InsetMathRef * asRefInset() { return this; }
 
 	/// docbook output
@@ -56,6 +60,8 @@
 	///
 	static docstring const & getName(int type);
 	///
+	docstring const getTarget() const;
+	///
 	InsetCode lyxCode() const { return MATH_REF_CODE; }
 
 protected:
Index: src/mathed/InsetMathNest.h
===================================================================
--- src/mathed/InsetMathNest.h	(Revision 33238)
+++ src/mathed/InsetMathNest.h	(Arbeitskopie)
@@ -43,6 +43,8 @@
 	/// draw decorations.
 	void drawDecoration(PainterInfo & pi, int x, int y) const
 	{ drawMarkers(pi, x, y); }
+	///
+	void updateLabels(ParIterator const &, UpdateType);
 	/// identifies NestInsets
 	InsetMathNest * asNestInset() { return this; }
 	/// identifies NestInsets
Index: src/Buffer.h
===================================================================
--- src/Buffer.h	(Revision 33238)
+++ src/Buffer.h	(Arbeitskopie)
@@ -528,7 +528,7 @@
 	bool isExportableFormat(std::string const & format) const;
 
 	///
-	typedef std::vector<std::pair<InsetRef *, ParIterator> > References;
+	typedef std::vector<std::pair<Inset *, ParIterator> > References;
 	References & references(docstring const & label);
 	References const & references(docstring const & label) const;
 	void clearReferenceCache() const;
Index: src/CutAndPaste.cpp
===================================================================
--- src/CutAndPaste.cpp	(Revision 33238)
+++ src/CutAndPaste.cpp	(Arbeitskopie)
@@ -49,6 +49,7 @@
 #include "mathed/MathData.h"
 #include "mathed/InsetMath.h"
 #include "mathed/InsetMathHull.h"
+#include "mathed/InsetMathRef.h"
 #include "mathed/MathSupport.h"
 
 #include "support/debug.h"
@@ -242,16 +243,21 @@
 				docstring const oldname = lab->getParam("name");
 				lab->updateCommand(oldname, false);
 				docstring const newname = lab->getParam("name");
-				if (oldname != newname) {
-					// adapt the references
-					for (InsetIterator itt = inset_iterator_begin(in);
-					     itt != i_end; ++itt) {
-						if (itt->lyxCode() == REF_CODE) {
-							InsetCommand & ref =
-								dynamic_cast<InsetCommand &>(*itt);
-							if (ref.getParam("reference") == oldname)
-								ref.setParam("reference", newname);
-						}
+				if (oldname == newname)
+					continue;
+				// adapt the references
+				for (InsetIterator itt = inset_iterator_begin(in);
+				      itt != i_end; ++itt) {
+					if (itt->lyxCode() == REF_CODE) {
+						InsetCommand & ref =
+							static_cast<InsetCommand &>(*itt);
+						if (ref.getParam("reference") == oldname)
+							ref.setParam("reference", newname);
+					} else if (itt->lyxCode() == MATH_REF_CODE) {
+						InsetMathHull & mi =
+							static_cast<InsetMathHull &>(*itt);
+						if (mi.asRefInset()->getTarget() == oldname)
+							mi.asRefInset()->changeTarget(newname);
 					}
 				}
 			}
@@ -264,14 +270,19 @@
 			docstring const oldname = lab.getParam("name");
 			lab.updateCommand(oldname, false);
 			docstring const newname = lab.getParam("name");
-			if (oldname != newname) {
-				// adapt the references
-				for (InsetIterator itt = inset_iterator_begin(in); itt != i_end; ++itt) {
-					if (itt->lyxCode() == REF_CODE) {
-						InsetCommand & ref = dynamic_cast<InsetCommand &>(*itt);
-						if (ref.getParam("reference") == oldname)
-							ref.setParam("reference", newname);
-					}
+			if (oldname == newname)
+				break;
+			// adapt the references
+			for (InsetIterator itt = inset_iterator_begin(in); itt != i_end; ++itt) {
+				if (itt->lyxCode() == REF_CODE) {
+					InsetCommand & ref = static_cast<InsetCommand &>(*itt);
+					if (ref.getParam("reference") == oldname)
+						ref.setParam("reference", newname);
+				} else if (itt->lyxCode() == MATH_REF_CODE) {
+					InsetMathHull & mi =
+						static_cast<InsetMathHull &>(*itt);
+					if (mi.asRefInset()->getTarget() == oldname)
+						mi.asRefInset()->changeTarget(newname);
 				}
 			}
 			break;
@@ -289,14 +300,16 @@
 			docstring const oldkey = bib.getParam("key");
 			bib.updateCommand(oldkey, false);
 			docstring const newkey = bib.getParam("key");
-			if (oldkey != newkey) {
-				// adapt the references
-				for (InsetIterator itt = inset_iterator_begin(in); itt != i_end; ++itt) {
-					if (itt->lyxCode() == CITE_CODE) {
-						InsetCommand & ref = dynamic_cast<InsetCommand &>(*itt);
-						if (ref.getParam("key") == oldkey)
-							ref.setParam("key", newkey);
-					}
+			if (oldkey == newkey)
+				break;
+			// adapt the references
+			for (InsetIterator itt = inset_iterator_begin(in);
+			     itt != i_end; ++itt) {
+				if (itt->lyxCode() == CITE_CODE) {
+					InsetCommand & ref =
+						static_cast<InsetCommand &>(*itt);
+					if (ref.getParam("key") == oldkey)
+						ref.setParam("key", newkey);
 				}
 			}
 			break;

Reply via email to