* 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
This commit is contained in:
Jürgen Spitzmüller 2010-01-28 17:37:22 +00:00
parent c6784d708d
commit 7bbd67eb26
13 changed files with 161 additions and 30 deletions

View File

@ -528,7 +528,7 @@ public:
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;

View File

@ -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());
}

View File

@ -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<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.
// FIXME audit setBuffer/updateLabels calls
mi.setBuffer(const_cast<Buffer &>(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<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.
// FIXME audit setBuffer/updateLabels calls
mi.setBuffer(const_cast<Buffer &>(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<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;

View File

@ -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<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 @@ 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<InsetMathHull *>(it->first)->asRefInset()
->screenLabel()));
else
toc.push_back(TocItem(ref_pit, 1,
static_cast<InsetRef *>(it->first)->screenLabel()));
}
}

View File

@ -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;
}

View File

@ -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,<,>

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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: "))},

View File

@ -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:

View File

@ -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,

View File

@ -18,6 +18,8 @@
#include "Dimension.h"
#include "MathAtom.h"
#include "OutputEnums.h"
#include "support/strfwd.h"
#include <vector>
@ -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