From: Jürgen Spitzmüller Date: Thu, 28 Jan 2010 17:37:22 +0000 (+0000) Subject: * Implement updateLabels in mathed and add the MathRef insets to the references cache. X-Git-Tag: 2.0.0~4208 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=7bbd67eb267966d1deb655ea126bc25a64fdf34d;p=features.git * Implement updateLabels in mathed and add the MathRef insets to the references cache. This fixes bug #1560. The diverse setBuffer / updateLabels calls need auditing. See FIXMEs. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@33249 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/Buffer.h b/src/Buffer.h index dae42584f9..acf8bfd404 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -528,7 +528,7 @@ public: bool isExportableFormat(std::string const & format) const; /// - typedef std::vector > References; + typedef std::vector > References; References & references(docstring const & label); References const & references(docstring const & label) const; void clearReferenceCache() const; diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 100855e92f..acc3f0e8e5 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -1345,6 +1345,8 @@ void Cursor::insert(MathData const & ar) cap::eraseSelection(*this); cell().insert(pos(), ar); pos() += ar.size(); + // FIXME audit setBuffer/updateLabels calls + inset().setBuffer(bv_->buffer()); } diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 668d2b51ae..8a71efb774 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -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,25 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, 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(*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(*itt); + if (ref.getParam("reference") == oldname) + ref.setParam("reference", newname); + } else if (itt->lyxCode() == MATH_REF_CODE) { + InsetMathHull & mi = + static_cast(*itt); + // this is necessary to prevent an uninitialized + // buffer when the RefInset is in a MathBox. + // FIXME audit setBuffer/updateLabels calls + mi.setBuffer(const_cast(buffer)); + if (mi.asRefInset()->getTarget() == oldname) + mi.asRefInset()->changeTarget(newname); } } } @@ -264,14 +274,23 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, 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(*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(*itt); + if (ref.getParam("reference") == oldname) + ref.setParam("reference", newname); + } else if (itt->lyxCode() == MATH_REF_CODE) { + InsetMathHull & mi = + static_cast(*itt); + // this is necessary to prevent an uninitialized + // buffer when the RefInset is in a MathBox. + // FIXME audit setBuffer/updateLabels calls + mi.setBuffer(const_cast(buffer)); + if (mi.asRefInset()->getTarget() == oldname) + mi.asRefInset()->changeTarget(newname); } } break; @@ -289,14 +308,16 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, 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(*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(*itt); + if (ref.getParam("key") == oldkey) + ref.setParam("key", newkey); } } break; diff --git a/src/insets/InsetLabel.cpp b/src/insets/InsetLabel.cpp index fd196cfd77..3eaa89f3f9 100644 --- a/src/insets/InsetLabel.cpp +++ b/src/insets/InsetLabel.cpp @@ -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 @@ void InsetLabel::updateCommand(docstring const & new_label, bool updaterefs) 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(it->first); + mi->asRefInset()->changeTarget(label); + } else { + InsetCommand * ref = + static_cast(it->first); + ref->setParam("reference", label); + } } } buffer().undo().endUndoGroup(); @@ -150,7 +161,13 @@ void InsetLabel::addToToc(DocIterator const & cpit) 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(it->first)->asRefInset() + ->screenLabel())); + else + toc.push_back(TocItem(ref_pit, 1, + static_cast(it->first)->screenLabel())); } } diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp index 2256a08f60..8629568037 100644 --- a/src/mathed/InsetMathGrid.cpp +++ b/src/mathed/InsetMathGrid.cpp @@ -18,6 +18,7 @@ #include "MathStream.h" #include "MetricsInfo.h" +#include "Buffer.h" #include "BufferView.h" #include "CutAndPaste.h" #include "FuncStatus.h" @@ -634,6 +635,14 @@ void InsetMathGrid::drawT(TextPainter & /*pain*/, int /*x*/, int /*y*/) const } +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; @@ -1322,6 +1331,10 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) cell(i).append(grid.cell(grid.index(r, c))); } cur.clearSelection(); // bug 393 + // FIXME audit setBuffer/updateLabels calls + cur.inset().setBuffer(*buffer_); + // FIXME audit setBuffer/updateLabels calls + cur.buffer()->updateLabels(); cur.finishUndo(); break; } diff --git a/src/mathed/InsetMathGrid.h b/src/mathed/InsetMathGrid.h index 926216ea1c..40408bd879 100644 --- a/src/mathed/InsetMathGrid.h +++ b/src/mathed/InsetMathGrid.h @@ -112,6 +112,8 @@ public: 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,<,> diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 79ac46e52f..eaaa94757d 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -225,6 +225,8 @@ void InsetMathHull::updateLabels(ParIterator const & it, UpdateType utype) if (label_[i]) label_[i]->updateLabels(it, utype); } + // pass down + InsetMathGrid::updateLabels(it, utype); } diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 2b23fb15ac..98bc13fc09 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -173,6 +173,14 @@ void InsetMathNest::metrics(MetricsInfo const & mi) const } +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, /**/); @@ -530,7 +538,7 @@ void InsetMathNest::handleFont2(Cursor & cur, docstring const & arg) void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) { - //lyxerr << "InsetMathNest: request: " << cmd << endl; + //LYXERR0("InsetMathNest: request: " << cmd); Parse::flags parseflg = Parse::QUIET | Parse::USETEXT; @@ -556,6 +564,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) } cur.niceInsert(topaste, parseflg, false); cur.clearSelection(); // bug 393 + // FIXME audit setBuffer/updateLabels calls + cur.buffer()->updateLabels(); cur.finishUndo(); break; } @@ -567,6 +577,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) // Prevent stale position >= size crash // Probably not necessary anymore, see eraseSelection (gb 2005-10-09) cur.normalize(); + // FIXME audit setBuffer/updateLabels calls + cur.buffer()->updateLabels(); break; case LFUN_COPY: @@ -976,6 +988,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) cur.posBackward(); cur.pushBackward(*cur.nextInset()); cur.niceInsert(save_selection); + // FIXME audit setBuffer/updateLabels calls + cur.buffer()->updateLabels(); #else if (currentMode() == Inset::TEXT_MODE) { cur.recordUndoSelection(); @@ -1190,6 +1204,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) if (createInsetMath_fromDialogStr(cmd.argument(), ar)) { cur.recordUndoSelection(); cur.insert(ar); + // FIXME audit setBuffer/updateLabels calls + cur.buffer()->updateLabels(); } else cur.undispatched(); break; diff --git a/src/mathed/InsetMathNest.h b/src/mathed/InsetMathNest.h index 659a1156fc..ac95fbb353 100644 --- a/src/mathed/InsetMathNest.h +++ b/src/mathed/InsetMathNest.h @@ -43,6 +43,8 @@ public: /// 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 diff --git a/src/mathed/InsetMathRef.cpp b/src/mathed/InsetMathRef.cpp index 9df6eaa04d..1fa076fd44 100644 --- a/src/mathed/InsetMathRef.cpp +++ b/src/mathed/InsetMathRef.cpp @@ -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 @@ int InsetMathRef::docbook(odocstream & os, OutputParams const & runparams) const } +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,29 @@ string const InsetMathRef::createDialogStr(string const & name) const } +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(); + // FIXME audit setBuffer/updateLabels calls + 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: "))}, diff --git a/src/mathed/InsetMathRef.h b/src/mathed/InsetMathRef.h index 7b788c7814..a93d910594 100644 --- a/src/mathed/InsetMathRef.h +++ b/src/mathed/InsetMathRef.h @@ -27,6 +27,8 @@ public: /// 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 @@ public: /// void validate(LaTeXFeatures & features) const; /// + void changeTarget(docstring const & target); + /// virtual InsetMathRef * asRefInset() { return this; } /// docbook output @@ -56,6 +60,8 @@ public: /// static docstring const & getName(int type); /// + docstring const getTarget() const; + /// InsetCode lyxCode() const { return MATH_REF_CODE; } protected: diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp index 0c41fb634e..03602106c0 100644 --- a/src/mathed/MathData.cpp +++ b/src/mathed/MathData.cpp @@ -377,6 +377,16 @@ void MathData::drawT(TextPainter & pain, int x, int y) const } +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, diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h index d238696a57..9fa63a86f3 100644 --- a/src/mathed/MathData.h +++ b/src/mathed/MathData.h @@ -18,6 +18,8 @@ #include "Dimension.h" #include "MathAtom.h" +#include "OutputEnums.h" + #include "support/strfwd.h" #include @@ -35,6 +37,7 @@ class MacroContext; class MathMacro; class MetricsInfo; class PainterInfo; +class ParIterator; class TextMetricsInfo; class TextPainter; @@ -164,6 +167,8 @@ public: /// 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