]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/InsetMathNest.cpp
A little cleanup of the layout files.
[lyx.git] / src / mathed / InsetMathNest.cpp
index 9e1b63496bf540a15bf67c34e25229d5361d5ea5..c6e25b59945d0696f10b15e040631a79c724ae41 100644 (file)
 #include "InsetMathBig.h"
 #include "InsetMathBox.h"
 #include "InsetMathBrace.h"
+#include "InsetMathChar.h"
 #include "InsetMathColor.h"
 #include "InsetMathComment.h"
 #include "InsetMathDelim.h"
+#include "InsetMathEnsureMath.h"
 #include "InsetMathHull.h"
 #include "InsetMathRef.h"
 #include "InsetMathScript.h"
 #include "InsetMathSpace.h"
 #include "InsetMathSymbol.h"
 #include "InsetMathUnknown.h"
+#include "MathAutoCorrect.h"
 #include "MathCompletionList.h"
 #include "MathData.h"
 #include "MathFactory.h"
@@ -41,6 +44,7 @@
 #include "Cursor.h"
 #include "CutAndPaste.h"
 #include "DispatchResult.h"
+#include "Encoding.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
 #include "LyXFunc.h"
@@ -513,7 +517,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
        //lyxerr << "InsetMathNest: request: " << cmd << endl;
 
-       Parse::flags parseflg = Parse::QUIET;
+       Parse::flags parseflg = Parse::QUIET | Parse::USETEXT;
 
        switch (cmd.action) {
 
@@ -628,7 +632,6 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                }
                // Now that we know exactly what we want to do, let's do it!
                cur.selHandle(select);
-               cur.autocorrect() = false;
                cur.clearTargetX();
                cur.macroModeClose();
                // try moving forward or backwards as necessary...
@@ -814,8 +817,14 @@ 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())
-                       cur.recordUndoSelection();
+               if (!cur.inMacroMode()) {
+                       MathMacro const * macro = 0;
+                       if (cur.pos() > 0 && cmd.argument() != "\\")
+                               macro = cur.inset().asInsetMath()->asMacro();
+                       
+                       if (!macro)
+                               cur.recordUndoSelection();
+               }
 
                // spacial handling of space. If we insert an inset
                // via macro mode, we want to put the cursor inside it
@@ -835,7 +844,6 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                break;
 
        //case LFUN_SERVER_GET_XY:
-       //      sprintf(dispatch_buffer, "%d %d",);
        //      break;
 
        case LFUN_SERVER_SET_XY: {
@@ -947,7 +955,10 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                docstring const save_selection = grabAndEraseSelection(cur);
                selClearOrDel(cur);
                //cur.plainInsert(MathAtom(new InsetMathMBox(cur.bv())));
-               cur.plainInsert(MathAtom(new InsetMathBox(from_ascii("mbox"))));
+               if (currentMode() == Inset::TEXT_MODE)
+                       cur.plainInsert(MathAtom(new InsetMathEnsureMath));
+               else
+                       cur.plainInsert(MathAtom(new InsetMathBox(from_ascii("mbox"))));
                cur.posBackward();
                cur.pushBackward(*cur.nextInset());
                cur.niceInsert(save_selection);
@@ -964,6 +975,29 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_REGEXP_MODE: {
+               InsetMathHull * i = dynamic_cast<InsetMathHull *>(cur.inset().asInsetMath());
+               if (i && i->getType() == hullRegexp) {
+                       cur.message(_("Already in regexp mode"));
+                       break;
+               }
+               cur.macroModeClose();
+               docstring const save_selection = grabAndEraseSelection(cur);
+               selClearOrDel(cur);
+               cur.plainInsert(MathAtom(new InsetMathHull(hullRegexp)));
+               cur.posBackward();
+               cur.pushBackward(*cur.nextInset());
+               cur.niceInsert(save_selection);
+               cur.message(_("Regexp editor mode"));
+               break;
+       }
+
+       case LFUN_MATH_FONT_STYLE: {
+               FuncRequest fr = FuncRequest(LFUN_MATH_INSERT, '\\' + cmd.argument());
+               doDispatch(cur, fr);
+               break;
+       }
+
        case LFUN_MATH_SIZE: {
                FuncRequest fr = FuncRequest(LFUN_MATH_INSERT, cmd.argument());
                doDispatch(cur, fr);
@@ -1033,15 +1067,18 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_SPACE_INSERT:
                cur.recordUndoSelection();
-               cur.insert(MathAtom(new InsetMathSpace(from_ascii(","))));
+               cur.insert(MathAtom(new InsetMathSpace));
                break;
 
        case LFUN_MATH_SPACE:
                cur.recordUndoSelection();
                if (cmd.argument().empty())
-                       cur.insert(MathAtom(new InsetMathSpace(from_ascii(","))));
-               else
-                       cur.insert(MathAtom(new InsetMathSpace(cmd.argument())));
+                       cur.insert(MathAtom(new InsetMathSpace));
+               else {
+                       string const name = cmd.getArg(0);
+                       string const len = cmd.getArg(1);
+                       cur.insert(MathAtom(new InsetMathSpace(name, len)));
+               }
                break;
 
        case LFUN_ERT_INSERT:
@@ -1109,6 +1146,9 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                if (name == "ref") {
                        InsetMathRef tmp(name);
                        data = tmp.createDialogStr(to_utf8(name));
+               } else if (name == "mathspace") {
+                       InsetMathSpace tmp;
+                       data = tmp.createDialogStr();
                }
                cur.bv().showDialog(to_utf8(name), data);
                break;
@@ -1214,10 +1254,6 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_FONT_DEFAULT:
                flag.setEnabled(true);
                break;
-       case LFUN_MATH_MUTATE:
-               //flag.setOnOff(mathcursor::formula()->hullType() == to_utf8(cmd.argument()));
-               flag.setOnOff(false);
-               break;
 
        // we just need to be in math mode to enable that
        case LFUN_MATH_SIZE:
@@ -1231,18 +1267,22 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
                flag.setEnabled(currentMode() != TEXT_MODE);
                break;
 
-       case LFUN_MATH_INSERT: {
+       case LFUN_MATH_FONT_STYLE: {
                bool const textarg =
-                       arg == "\\textbf"   || arg == "\\textsf" ||
-                       arg == "\\textrm"   || arg == "\\textmd" ||
-                       arg == "\\textit"   || arg == "\\textsc" ||
-                       arg == "\\textsl"   || arg == "\\textup" ||
-                       arg == "\\texttt"   || arg == "\\textbb" ||
-                       arg == "\\textnormal";
+                       arg == "textbf"   || arg == "textsf" ||
+                       arg == "textrm"   || arg == "textmd" ||
+                       arg == "textit"   || arg == "textsc" ||
+                       arg == "textsl"   || arg == "textup" ||
+                       arg == "texttt"   || arg == "textbb" ||
+                       arg == "textnormal";
                flag.setEnabled(currentMode() != TEXT_MODE || textarg);
                break;
        }
 
+       case LFUN_MATH_INSERT:
+               flag.setEnabled(currentMode() != TEXT_MODE);
+               break;
+
        case LFUN_MATH_MATRIX:
                flag.setEnabled(currentMode() == MATH_MODE);
                break;
@@ -1252,7 +1292,7 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
                // getStatus is not called with a valid reference and the
                // dialog would not be applyable.
                string const name = cmd.getArg(0);
-               flag.setEnabled(name == "ref");
+               flag.setEnabled(name == "ref" || name == "mathspace");
                break;
        }
 
@@ -1420,7 +1460,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                MathWordList const & mwl = mathedWordList();
                bool star_macro = c == '*'
                        && (mwl.find(name.substr(1) + "*") != mwl.end()
-                           || cur.buffer().getMacro(name.substr(1) + "*", cur, true));
+                           || cur.buffer()->getMacro(name.substr(1) + "*", cur, true));
                if (isAlphaASCII(c) || star_macro) {
                        cur.activeMacro()->setName(name + docstring(1, c));
                        return true;
@@ -1485,7 +1525,13 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                }
 
                // leave macro mode and try again if necessary
-               cur.macroModeClose();
+               if (cur.macroModeClose()) {
+                       MathAtom const atom = cur.prevAtom();
+                       if (atom->asNestInset() && atom->isActive()) {
+                               cur.posBackward();
+                               cur.pushBackward(*cur.nextInset());
+                       }
+               }
                if (c == '{')
                        cur.niceInsert(MathAtom(new InsetMathBrace));
                else if (c != ' ')
@@ -1493,16 +1539,18 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                return true;
        }
 
-       // This is annoying as one has to press <space> far too often.
-       // Disable it.
 
-#if 0
-               // leave autocorrect mode if necessary
-               if (autocorrect() && c == ' ') {
-                       autocorrect() = false;
-                       return true;
-               }
-#endif
+       // leave autocorrect mode if necessary
+       if (lyxrc.autocorrection_math && c == ' ' && cur.autocorrect()) {
+               cur.autocorrect() = false;
+               cur.message(_("Autocorrect Off ('!' to enter)"));
+               return true;
+       } 
+       if (lyxrc.autocorrection_math && c == '!' && !cur.autocorrect()) {
+               cur.autocorrect() = true;
+               cur.message(_("Autocorrect On (<space> to exit)"));
+               return true;
+       }
 
        // just clear selection on pressing the space bar
        if (cur.selection() && c == ' ') {
@@ -1520,6 +1568,19 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                return true;
        }
 
+       if (cur.pos() > 0) {
+               MathMacro const * macro = cur.inset().asInsetMath()->asMacro();
+               if (macro) {
+                       // 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;    
+               }
+       }
+
        selClearOrDel(cur);
 
        if (c == '\n') {
@@ -1581,6 +1642,13 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                        cur.niceInsert(createInsetMath("sim"));
                        return true;
                }
+               if (!isAsciiOrMathAlpha(c)) {
+                       MathAtom at = createInsetMath("text");
+                       at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
+                       cur.niceInsert(at);
+                       cur.posForward();
+                       return true;
+               }
        } else {
                if (c == '^') {
                        cur.niceInsert(createInsetMath("textasciicircum"));
@@ -1600,12 +1668,18 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
 
 
        // try auto-correction
-       //if (autocorrect() && hasPrevAtom() && math_autocorrect(prevAtom(), c))
-       //      return true;
+       if (lyxrc.autocorrection_math && cur.autocorrect() && cur.pos() != 0
+                 && math_autocorrect(cur.prevAtom(), c))
+               return true;
 
        // no special circumstances, so insert the character without any fuss
        cur.insert(c);
-       cur.autocorrect() = true;
+       if (lyxrc.autocorrection_math) {
+               if (!cur.autocorrect())
+                       cur.message(_("Autocorrect Off ('!' to enter)"));
+               else
+                       cur.message(_("Autocorrect On (<space> to exit)"));
+       }
        return true;
 }
 
@@ -1827,10 +1901,10 @@ MathCompletionList::MathCompletionList(Cursor const & cur)
 {
        // fill it with macros from the buffer
        MacroNameSet macros;
-       cur.buffer().listMacroNames(macros);
+       cur.buffer()->listMacroNames(macros);
        MacroNameSet::const_iterator it;
        for (it = macros.begin(); it != macros.end(); ++it) {
-               if (cur.buffer().getMacro(*it, cur, false))
+               if (cur.buffer()->getMacro(*it, cur, false))
                        locals.push_back("\\" + *it);
        }
        sort(locals.begin(), locals.end());
@@ -1888,6 +1962,9 @@ MathCompletionList::MathCompletionList(Cursor const & cur)
        globals.push_back(from_ascii("\\color"));
        globals.push_back(from_ascii("\\normalcolor"));
        globals.push_back(from_ascii("\\textcolor"));
+       globals.push_back(from_ascii("\\cfrac"));
+       globals.push_back(from_ascii("\\cfracleft"));
+       globals.push_back(from_ascii("\\cfracright"));
        globals.push_back(from_ascii("\\dfrac"));
        globals.push_back(from_ascii("\\tfrac"));
        globals.push_back(from_ascii("\\dbinom"));