]> git.lyx.org Git - features.git/blobdiff - src/mathed/InsetMathNest.cpp
* InsetTabular cleanup:
[features.git] / src / mathed / InsetMathNest.cpp
index 413d32efded532f7ffaf1eb5640e69d89ebad53f..0a7810784acb6520c0380ce029f6ef7a23588263 100644 (file)
@@ -13,6 +13,7 @@
 #include "InsetMathNest.h"
 
 #include "InsetMathArray.h"
+#include "InsetMathAMSArray.h"
 #include "InsetMathBig.h"
 #include "InsetMathBox.h"
 #include "InsetMathBrace.h"
@@ -47,7 +48,7 @@
 #include "Encoding.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
-#include "LyXFunc.h"
+#include "LyX.h"
 #include "LyXRC.h"
 #include "OutputParams.h"
 #include "Text.h"
@@ -78,9 +79,11 @@ using cap::replaceSelection;
 using cap::selClearOrDel;
 
 
-InsetMathNest::InsetMathNest(idx_type nargs)
-       : cells_(nargs), lock_(false), mouse_hover_(false)
-{}
+InsetMathNest::InsetMathNest(Buffer * buf, idx_type nargs)
+       : InsetMath(buf), cells_(nargs), lock_(false), mouse_hover_(false)
+{
+       setBuffer(*buf);
+}
 
 
 InsetMathNest::InsetMathNest(InsetMathNest const & inset)
@@ -99,6 +102,17 @@ InsetMathNest & InsetMathNest::operator=(InsetMathNest const & inset)
 }
 
 
+void InsetMathNest::setBuffer(Buffer & buffer)
+{
+       InsetMath::setBuffer(buffer);
+       for (idx_type i = 0, n = nargs(); i != n; ++i) {
+               MathData & data = cell(i);
+               for (size_t j = 0; j != data.size(); ++j)
+                       data[j].nucleus()->setBuffer(buffer);
+       }
+}
+
+
 InsetMath::idx_type InsetMathNest::nargs() const
 {
        return cells_.size();
@@ -159,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, /**/);
@@ -365,8 +387,9 @@ void InsetMathNest::normalize(NormalStream & os) const
 
 int InsetMathNest::latex(odocstream & os, OutputParams const & runparams) const
 {
-       WriteStream wi(os, runparams.moving_arg, true, runparams.dryrun,
-                       runparams.encoding);
+       WriteStream wi(os, runparams.moving_arg, true,
+                      runparams.dryrun ? WriteStream::wsDryrun : WriteStream::wsDefault,
+                      runparams.encoding);
        write(wi);
        return wi.line();
 }
@@ -427,7 +450,7 @@ void InsetMathNest::handleFont(Cursor & cur, docstring const & arg,
        if (cur.inset().asInsetMath()->name() == font)
                cur.handleFont(to_utf8(font));
        else
-               handleNest(cur, createInsetMath(font), arg);
+               handleNest(cur, createInsetMath(font, cur.buffer()), arg);
 }
 
 
@@ -507,7 +530,7 @@ void InsetMathNest::handleFont2(Cursor & cur, docstring const & arg)
        font.fromString(to_utf8(arg), b);
        if (font.fontInfo().color() != Color_inherit &&
            font.fontInfo().color() != Color_ignore)
-               handleNest(cur, MathAtom(new InsetMathColor(true, font.fontInfo().color())));
+               handleNest(cur, MathAtom(new InsetMathColor(buffer_, true, font.fontInfo().color())));
 
        // FIXME: support other font changes here as well?
 }
@@ -515,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;
 
@@ -539,8 +562,10 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                        is >> n;
                        topaste = cap::selection(n);
                }
-               cur.niceInsert(topaste, parseflg);
+               cur.niceInsert(topaste, parseflg, false);
                cur.clearSelection(); // bug 393
+               // FIXME audit setBuffer/updateLabels calls
+               cur.buffer()->updateLabels();
                cur.finishUndo();
                break;
        }
@@ -552,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:
@@ -808,7 +835,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                                cur.insert(arg);
                        break;
                }
-               // Don't record undo steps if we are in macro mode and
+               // Don't record undo steps if we are in macro mode and thus
                // cmd.argument is the next character of the macro name.
                // Otherwise we'll get an invalid cursor if we undo after
                // the macro was finished and the macro is a known command,
@@ -817,14 +844,9 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                // InsetMathFrac -> a pos value > 0 is invalid.
                // A side effect is that an undo before the macro is finished
                // undoes the complete macro, not only the last character.
-               if (!cur.inMacroMode()) {
-                       MathMacro const * macro = 0;
-                       if (cur.pos() > 0 && cmd.argument() != "\\")
-                               macro = cur.inset().asInsetMath()->asMacro();
-                       
-                       if (!macro)
-                               cur.recordUndoSelection();
-               }
+               // At the time we hit '\' we are not in macro mode, still.
+               if (!cur.inMacroMode())
+                       cur.recordUndoSelection();
 
                // spacial handling of space. If we insert an inset
                // via macro mode, we want to put the cursor inside it
@@ -945,6 +967,10 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                handleFont(cur, cmd.argument(), "textnormal");
                break;
 
+       case LFUN_FONT_UNDERLINE:
+               cur.recordUndo();
+               cur.handleNest(createInsetMath("underline", cur.buffer()));
+               break;
        case LFUN_MATH_MODE: {
 #if 1
                // ignore math-mode on when already in math mode
@@ -956,16 +982,18 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                selClearOrDel(cur);
                //cur.plainInsert(MathAtom(new InsetMathMBox(cur.bv())));
                if (currentMode() <= Inset::TEXT_MODE)
-                       cur.plainInsert(MathAtom(new InsetMathEnsureMath));
+                       cur.plainInsert(MathAtom(new InsetMathEnsureMath(buffer_)));
                else
-                       cur.plainInsert(MathAtom(new InsetMathBox(from_ascii("mbox"))));
+                       cur.plainInsert(MathAtom(new InsetMathBox(buffer_, from_ascii("mbox"))));
                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();
-                       cur.niceInsert(MathAtom(new InsetMathHull("simple")));
+                       cur.niceInsert(MathAtom(new InsetMathHull("simple", cur.buffer())));
                        cur.message(_("create new math text environment ($...$)"));
                } else {
                        handleFont(cur, cmd.argument(), "textrm");
@@ -978,17 +1006,17 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_REGEXP_MODE: {
                InsetMathHull * i = dynamic_cast<InsetMathHull *>(cur.inset().asInsetMath());
                if (i && i->getType() == hullRegexp) {
-                       cur.message(_("Already in regexp mode"));
+                       cur.message(_("Already in regular expression mode"));
                        break;
                }
                cur.macroModeClose();
                docstring const save_selection = grabAndEraseSelection(cur);
                selClearOrDel(cur);
-               cur.plainInsert(MathAtom(new InsetMathHull(hullRegexp)));
+               cur.plainInsert(MathAtom(new InsetMathHull(buffer_, hullRegexp)));
                cur.posBackward();
                cur.pushBackward(*cur.nextInset());
                cur.niceInsert(save_selection);
-               cur.message(_("Regexp editor mode"));
+               cur.message(_("Regular expression editor mode"));
                break;
        }
 
@@ -1017,8 +1045,24 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                if (n < 1)
                        n = 1;
                v_align += 'c';
+               cur.niceInsert(MathAtom(new InsetMathArray(buffer_,
+                       from_ascii("array"), m, n, (char)v_align[0], h_align)));
+               break;
+       }
+
+       case LFUN_MATH_AMS_MATRIX: {
+               cur.recordUndo();
+               unsigned int m = 1;
+               unsigned int n = 1;
+               docstring name;
+               idocstringstream is(cmd.argument());
+               is >> m >> n >> name;
+               if (m < 1)
+                       m = 1;
+               if (n < 1)
+                       n = 1;
                cur.niceInsert(
-                       MathAtom(new InsetMathArray(from_ascii("array"), m, n, (char)v_align[0], h_align)));
+                       MathAtom(new InsetMathAMSArray(buffer_, name, m, n)));
                break;
        }
 
@@ -1031,7 +1075,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                if (rs.empty())
                        rs = ')';
                cur.recordUndo();
-               cur.handleNest(MathAtom(new InsetMathDelim(ls, rs)));
+               cur.handleNest(MathAtom(new InsetMathDelim(buffer_, ls, rs)));
                break;
        }
 
@@ -1145,7 +1189,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                docstring const & name = cmd.argument();
                string data;
                if (name == "ref") {
-                       InsetMathRef tmp(name);
+                       InsetMathRef tmp(buffer_, name);
                        data = tmp.createDialogStr(to_utf8(name));
                } else if (name == "mathspace") {
                        InsetMathSpace tmp;
@@ -1160,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;
@@ -1220,11 +1266,11 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
        bool ret = true;
        string const arg = to_utf8(cmd.argument());
        switch (cmd.action) {
-       case LFUN_TABULAR_FEATURE:
+       case LFUN_INSET_MODIFY:
                flag.setEnabled(false);
                break;
 #if 0
-       case LFUN_TABULAR_FEATURE:
+       case LFUN_INSET_MODIFY:
                // FIXME: check temporarily disabled
                // valign code
                char align = mathcursor::valign();
@@ -1264,6 +1310,7 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
                flag.setEnabled(true);
                break;
 
+       case LFUN_FONT_UNDERLINE:
        case LFUN_FONT_FRAK:
                flag.setEnabled(currentMode() != TEXT_MODE);
                break;
@@ -1284,6 +1331,7 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
                flag.setEnabled(currentMode() != TEXT_MODE);
                break;
 
+       case LFUN_MATH_AMS_MATRIX:
        case LFUN_MATH_MATRIX:
                flag.setEnabled(currentMode() == MATH_MODE);
                break;
@@ -1443,6 +1491,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                save_selection = grabAndEraseSelection(cur);
 
        cur.clearTargetX();
+       Buffer * buf = cur.buffer();
 
        // handle macroMode
        if (cur.inMacroMode()) {
@@ -1473,24 +1522,24 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                        if (c == '\\') {
                                cur.backspace();
                                if (currentMode() <= InsetMath::TEXT_MODE)
-                                       cur.niceInsert(createInsetMath("textbackslash"));
+                                       cur.niceInsert(createInsetMath("textbackslash", buf));
                                else
-                                       cur.niceInsert(createInsetMath("backslash"));
+                                       cur.niceInsert(createInsetMath("backslash", buf));
                        } else if (c == '^' && currentMode() == InsetMath::MATH_MODE) {
                                cur.backspace();
-                               cur.niceInsert(createInsetMath("mathcircumflex"));
+                               cur.niceInsert(createInsetMath("mathcircumflex", buf));
                        } else if (c == '{') {
                                cur.backspace();
-                               cur.niceInsert(MathAtom(new InsetMathBrace));
+                               cur.niceInsert(MathAtom(new InsetMathBrace(buf)));
                        } else if (c == '%') {
                                cur.backspace();
-                               cur.niceInsert(MathAtom(new InsetMathComment));
+                               cur.niceInsert(MathAtom(new InsetMathComment(buf)));
                        } else if (c == '#') {
                                LASSERT(cur.activeMacro(), /**/);
                                cur.activeMacro()->setName(name + docstring(1, c));
                        } else {
                                cur.backspace();
-                               cur.niceInsert(createInsetMath(docstring(1, c)));
+                               cur.niceInsert(createInsetMath(docstring(1, c), buf));
                        }
                        return true;
                }
@@ -1534,7 +1583,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                        }
                }
                if (c == '{')
-                       cur.niceInsert(MathAtom(new InsetMathBrace));
+                       cur.niceInsert(MathAtom(new InsetMathBrace(buf)));
                else if (c != ' ')
                        interpretChar(cur, c);
                return true;
@@ -1571,17 +1620,6 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
 
        selClearOrDel(cur);
 
-       MathMacro const * macro = cur.inset().asInsetMath()->asMacro();
-       if (macro && macro->displayMode() == MathMacro::DISPLAY_UNFOLDED) {
-               // resume macro_mode
-               docstring const & s = macro->name();
-               cur.leaveInset(*macro);
-               cur.plainErase();
-               docstring safe = grabAndEraseSelection(cur);
-               cur.insert(MathAtom(new InsetMathUnknown("\\" + s + c, safe, false)));
-               return true;    
-       }
-
        if (c == '\n') {
                if (currentMode() <= InsetMath::TEXT_MODE)
                        cur.insert(c);
@@ -1638,11 +1676,11 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                        return true;
                }
                if (c == '~') {
-                       cur.niceInsert(createInsetMath("sim"));
+                       cur.niceInsert(createInsetMath("sim", buf));
                        return true;
                }
                if (currentMode() == InsetMath::MATH_MODE && !isAsciiOrMathAlpha(c)) {
-                       MathAtom at = createInsetMath("text");
+                       MathAtom at = createInsetMath("text", buf);
                        at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
                        cur.niceInsert(at);
                        cur.posForward();
@@ -1650,18 +1688,18 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                }
        } else {
                if (c == '^') {
-                       cur.niceInsert(createInsetMath("textasciicircum"));
+                       cur.niceInsert(createInsetMath("textasciicircum", buf));
                        return true;
                }
                if (c == '~') {
-                       cur.niceInsert(createInsetMath("textasciitilde"));
+                       cur.niceInsert(createInsetMath("textasciitilde", buf));
                        return true;
                }
        }
 
        if (c == '{' || c == '}' || c == '&' || c == '$' || c == '#' ||
            c == '%' || c == '_') {
-               cur.niceInsert(createInsetMath(docstring(1, c)));
+               cur.niceInsert(createInsetMath(docstring(1, c), buf));
                return true;
        }
 
@@ -1719,7 +1757,7 @@ bool InsetMathNest::script(Cursor & cur, bool up,
        //lyxerr << "handling script: up: " << up << endl;
        if (cur.inMacroMode() && cur.macroName() == "\\") {
                if (up)
-                       cur.niceInsert(createInsetMath("mathcircumflex"));
+                       cur.niceInsert(createInsetMath("mathcircumflex", cur.buffer()));
                else
                        interpretChar(cur, '_');
                return true;
@@ -1745,10 +1783,10 @@ bool InsetMathNest::script(Cursor & cur, bool up,
                // one if in the very first position of the array
                if (cur.pos() == 0) {
                        //lyxerr << "new scriptinset" << endl;
-                       cur.insert(new InsetMathScript(up));
+                       cur.insert(new InsetMathScript(buffer_, up));
                } else {
                        //lyxerr << "converting prev atom " << endl;
-                       cur.prevAtom() = MathAtom(new InsetMathScript(cur.prevAtom(), up));
+                       cur.prevAtom() = MathAtom(new InsetMathScript(buffer_, cur.prevAtom(), up));
                }
                --cur.pos();
                InsetMathScript * inset = cur.nextAtom().nucleus()->asScriptInset();
@@ -1862,10 +1900,6 @@ bool InsetMathNest::cursorMathForward(Cursor & cur)
        if (cur.pos() != cur.lastpos() && cur.openable(cur.nextAtom())) {
                cur.pushBackward(*cur.nextAtom().nucleus());
                cur.inset().idxFirst(cur);
-               MathMacro const * macro = cur.inset().asInsetMath()->asMacro();
-               if (macro && macro->displayMode() == MathMacro::DISPLAY_UNFOLDED)
-                       // editing macros is only possible at lastpos
-                       cur.pos() = cur.lastpos();
                return true;
        }
        if (cur.posForward() || idxForward(cur))
@@ -1887,17 +1921,11 @@ bool InsetMathNest::cursorMathBackward(Cursor & cur)
                cur.inset().idxLast(cur);
                return true;
        }
-       MathMacro const * macro = cur.inset().asInsetMath()->asMacro();
-       int s = cur.depth() - 2;
-       if (macro && macro->displayMode() == MathMacro::DISPLAY_UNFOLDED
-                 && s >= 0 && cur[s].inset().asInsetMath())
-               // editing macros is only possible at lastpos
-               return cur.popBackward();
-
        if (cur.posBackward() || idxBackward(cur))
                return true;
        // try to pop backwards --- but don't pop out of math! leave that to
        // the FINISH lfuns
+       int s = cur.depth() - 2;
        if (s >= 0 && cur[s].inset().asInsetMath())
                return cur.popBackward();
        return false;