Jürgen Spitzmüller wrote:
> > 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.
If I add another manual setBuffer call in the paste helper, the problem
disappears. This is pretty scary.
Enrico, could you test this patch?
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,24 @@
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);
+ // this is necessary to prevent an uninitialized
+ // buffer when the RefInset is in a MathBox.
+ mi.setBuffer(const_cast<Buffer &>(buffer));
+ if (mi.asRefInset()->getTarget() == oldname)
+ mi.asRefInset()->changeTarget(newname);
}
}
}
@@ -264,14 +273,22 @@
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);
+ // this is necessary to prevent an uninitialized
+ // buffer when the RefInset is in a MathBox.
+ mi.setBuffer(const_cast<Buffer &>(buffer));
+ if (mi.asRefInset()->getTarget() == oldname)
+ mi.asRefInset()->changeTarget(newname);
}
}
break;
@@ -289,14 +306,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;