X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FMathData.cpp;h=edd808945721cd071b2209ddd29d2ef264a8d78d;hb=6de3c19fd63f810eed90ef3bc4469faf28e949c2;hp=679331228206b211db22ffa75ee30d6c49cb0da9;hpb=be444fafcbf239654b7ac2a229d381a1e7bb23dc;p=lyx.git diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp index 6793312282..edd8089457 100644 --- a/src/mathed/MathData.cpp +++ b/src/mathed/MathData.cpp @@ -3,7 +3,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author André Pönitz + * \author André Pönitz * \author Stefan Schimanski * * Full author contact details are available in file CREDITS. @@ -36,7 +36,8 @@ #include "frontends/FontMetrics.h" #include "frontends/Painter.h" -#include +#include "support/gettext.h" +#include "support/lassert.h" #include #include @@ -46,21 +47,21 @@ using namespace std; namespace lyx { -MathData::MathData(const_iterator from, const_iterator to) - : base_type(from, to) +MathData::MathData(Buffer * buf, const_iterator from, const_iterator to) + : base_type(from, to), buffer_(buf) {} MathAtom & MathData::operator[](pos_type pos) { - BOOST_ASSERT(pos < size()); + LBUFERR(pos < size()); return base_type::operator[](pos); } MathAtom const & MathData::operator[](pos_type pos) const { - BOOST_ASSERT(pos < size()); + LBUFERR(pos < size()); return base_type::operator[](pos); } @@ -73,7 +74,7 @@ void MathData::insert(size_type pos, MathAtom const & t) void MathData::insert(size_type pos, MathData const & ar) { - BOOST_ASSERT(pos <= size()); + LBUFERR(pos <= size()); base_type::insert(begin() + pos, ar.begin(), ar.end()); } @@ -215,6 +216,7 @@ void MathData::touch() const } +#if 0 namespace { bool isInside(DocIterator const & it, MathData const & ar, @@ -229,7 +231,7 @@ bool isInside(DocIterator const & it, MathData const & ar, } } - +#endif void MathData::metrics(MetricsInfo & mi, Dimension & dim) const @@ -252,7 +254,7 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const } Cursor & cur = mi.base.bv->cursor(); - const_cast(this)->updateMacros(&cur, mi.macrocontext); + const_cast(this)->updateMacros(&cur, mi.macrocontext, InternalUpdate); DocIterator const & inlineCompletionPos = mi.base.bv->inlineCompletionPos(); MathData const * inlineCompletionData = 0; @@ -280,7 +282,9 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const if (completion.length() == 0) continue; - dim.wid += mathed_string_width(mi.base.font, completion); + FontInfo font = mi.base.font; + augmentFont(font, from_ascii("mathnormal")); + dim.wid += mathed_string_width(font, completion); } // Cache the dimension. mi.base.bv->coordCache().arrays().add(this, dim); @@ -328,6 +332,7 @@ void MathData::draw(PainterInfo & pi, int x, int y) const if (completion.length() == 0) continue; FontInfo f = pi.base.font; + augmentFont(f, from_ascii("mathnormal")); // draw the unique and the non-unique completion part // Note: this is not time-critical as it is @@ -336,13 +341,13 @@ void MathData::draw(PainterInfo & pi, int x, int y) const docstring s1 = completion.substr(0, uniqueTo); docstring s2 = completion.substr(uniqueTo); - if (s1.size() > 0) { + if (!s1.empty()) { f.setColor(Color_inlinecompletion); pi.pain.text(x, y, s1, f); x += mathed_string_width(f, s1); } - if (s2.size() > 0) { + if (!s2.empty()) { f.setColor(Color_nonunique_inlinecompletion); pi.pain.text(x, y, s2, f); x += mathed_string_width(f, s2); @@ -377,14 +382,36 @@ void MathData::drawT(TextPainter & pain, int x, int y) const } -void MathData::updateMacros(Cursor * cur, MacroContext const & mc) +void MathData::updateBuffer(ParIterator const & it, UpdateType utype) +{ + // pass down + for (size_t i = 0, n = size(); i != n; ++i) { + MathAtom & at = operator[](i); + at.nucleus()->updateBuffer(it, utype); + } +} + + +void MathData::updateMacros(Cursor * cur, MacroContext const & mc, + UpdateType utype) { + // If we are editing a macro, we cannot update it immediately, + // otherwise wrong undo steps will be recorded (bug 6208). + InsetMath const * inmath = cur ? cur->inset().asInsetMath() : 0; + MathMacro const * inmacro = inmath ? inmath->asMacro() : 0; + docstring const edited_name = inmacro ? inmacro->name() : docstring(); + // go over the array and look for macros for (size_t i = 0; i < size(); ++i) { MathMacro * macroInset = operator[](i).nucleus()->asMacro(); - if (!macroInset) + if (!macroInset || macroInset->name_.empty() + || macroInset->name_[0] == '^' + || macroInset->name_[0] == '_' + || (macroInset->name() == edited_name + && macroInset->displayMode() == + MathMacro::DISPLAY_UNFOLDED)) continue; - + // get macro macroInset->updateMacro(mc); size_t macroNumArgs = 0; @@ -407,6 +434,9 @@ void MathData::updateMacros(Cursor * cur, MacroContext const & mc) || newDisplayMode == MathMacro::DISPLAY_UNFOLDED)) { detachMacroParameters(cur, i); + // FIXME: proper anchor handling, this removes the selection + if (cur) + cur->clearSelection(); } // the macro could have been copied while resizing this @@ -459,13 +489,13 @@ void MathData::updateMacros(Cursor * cur, MacroContext const & mc) InsetMath * inset = operator[](i).nucleus(); if (inset->asScriptInset()) inset = inset->asScriptInset()->nuc()[0].nucleus(); - BOOST_ASSERT(inset->asMacro()); - inset->asMacro()->updateRepresentation(); + LASSERT(inset->asMacro(), continue); + inset->asMacro()->updateRepresentation(cur, mc, utype); } } -void MathData::detachMacroParameters(Cursor * cur, const size_type macroPos) +void MathData::detachMacroParameters(DocIterator * cur, const size_type macroPos) { MathMacro * macroInset = operator[](macroPos).nucleus()->asMacro(); @@ -522,7 +552,7 @@ void MathData::detachMacroParameters(Cursor * cur, const size_type macroPos) for (size_t q = 0; q < arg.size(); ++q) { if (arg[q]->getChar() == ']') { // put brace - brace = new InsetMathBrace(); + brace = new InsetMathBrace(buffer_); break; } } @@ -583,11 +613,8 @@ void MathData::detachMacroParameters(Cursor * cur, const size_type macroPos) ++(*cur)[curMacroSlice - 1].pos(); } - if (cur) { - // FIXME: proper anchor handling, this removes the selection - cur->clearSelection(); + if (cur) cur->updateInsets(&cur->bottom().inset()); - } } @@ -603,7 +630,7 @@ void MathData::attachMacroParameters(Cursor * cur, size_t p = macroPos + 1; vector detachedArgs; MathAtom scriptToPutAround; - + // find cursor slice again of this MathData int thisSlice = -1; if (cur) @@ -611,7 +638,7 @@ void MathData::attachMacroParameters(Cursor * cur, int thisPos = -1; if (thisSlice != -1) thisPos = (*cur)[thisSlice].pos(); - + // find arguments behind the macro if (!interactiveInit) { collectOptionalParameters(cur, macroOptionals, detachedArgs, p, @@ -619,27 +646,34 @@ void MathData::attachMacroParameters(Cursor * cur, } collectParameters(cur, macroNumArgs, detachedArgs, p, scriptToPutAround, macroPos, thisPos, thisSlice, appetite); - + // attach arguments back to macro inset macroInset->attachArguments(detachedArgs, macroNumArgs, macroOptionals); - + // found tail script? E.g. \foo{a}b^x if (scriptToPutAround.nucleus()) { + InsetMathScript * scriptInset = + scriptToPutAround.nucleus()->asScriptInset(); + // In the math parser we remove empty braces in the base + // of a script inset, but we have to restore them here. + if (scriptInset->nuc().empty()) { + MathData ar; + scriptInset->nuc().push_back( + MathAtom(new InsetMathBrace(ar))); + } // put macro into a script inset - scriptToPutAround.nucleus()->asScriptInset()->nuc()[0] - = operator[](macroPos); + scriptInset->nuc()[0] = operator[](macroPos); operator[](macroPos) = scriptToPutAround; // go into the script inset nucleus if (cur && thisPos == int(macroPos)) cur->append(0, 0); - + // get pointer to "deep" copied macro inset - InsetMathScript * scriptInset - = operator[](macroPos).nucleus()->asScriptInset(); + scriptInset = operator[](macroPos).nucleus()->asScriptInset(); macroInset = scriptInset->nuc()[0].nucleus()->asMacro(); } - + // remove them from the MathData erase(begin() + macroPos + 1, begin() + p); @@ -650,7 +684,7 @@ void MathData::attachMacroParameters(Cursor * cur, // fix cursor if right of p if (thisPos >= int(p)) (*cur)[thisSlice].pos() -= p - (macroPos + 1); - + // was the macro inset just inserted interactively and was now folded // and the cursor is just behind? if ((*cur)[thisSlice].pos() == int(macroPos + 1) @@ -671,6 +705,7 @@ void MathData::collectOptionalParameters(Cursor * cur, size_t & pos, MathAtom & scriptToPutAround, const pos_type macroPos, const int thisPos, const int thisSlice) { + Buffer * buf = cur ? cur->buffer() : 0; // insert optional arguments? while (params.size() < numOptionalParams && pos < size() @@ -708,7 +743,7 @@ void MathData::collectOptionalParameters(Cursor * cur, } // add everything between [ and ] as optional argument - MathData optarg(begin() + pos + 1, begin() + right); + MathData optarg(buf, begin() + pos + 1, begin() + right); // a brace? bool brace = false;