]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_cursor.C
activate row delete/insert for the 'cases' environment, too
[lyx.git] / src / mathed / math_cursor.C
index 25a86f1b7e6726df6b3c693d49093e4ec0368404..1cb978decbc0cca3aba45956a242b6ecbf88ed56 100644 (file)
 #include "debug.h"
 #include "LColor.h"
 #include "Painter.h"
-#include "support.h"
+#include "math_support.h"
 #include "formulabase.h"
 #include "math_cursor.h"
+#include "math_casesinset.h"
 #include "math_factory.h"
 #include "math_arrayinset.h"
+#include "math_braceinset.h"
 #include "math_charinset.h"
 #include "math_deliminset.h"
-#include "math_matrixinset.h"
+#include "math_hullinset.h"
 #include "math_scriptinset.h"
 #include "math_spaceinset.h"
 #include "math_specialcharinset.h"
+#include "math_mathmlstream.h"
 
 #define FILEDEBUG 0
 
@@ -786,7 +789,6 @@ void MathCursor::drawSelection(Painter & pain) const
        MathCursorPos i1;
        MathCursorPos i2;
        getSelection(i1, i2);
-
        //lyxerr << "selection from: " << i1 << " to " << i2 << "\n";
 
        if (i1.idx_ == i2.idx_) {
@@ -808,6 +810,18 @@ void MathCursor::drawSelection(Painter & pain) const
                        pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
                }
        }
+
+#if 0
+       // draw anchor if different from selection boundary
+       MathCursorPos anc = Anchor_.back();
+       if (anc != i1 && anc != i2) {
+               MathXArray & c = anc.xcell();
+               int x  = c.xo() + c.pos2x(anc.pos_);
+               int y1 = c.yo() - c.ascent();
+               int y2 = c.yo() + c.descent();
+               pain.line(x, y1, x, y2, LColor::mathline);
+       }
+#endif
 }
 
 
@@ -903,10 +917,10 @@ bool MathCursor::selection() const
 }
 
 
-MathArrayInset * MathCursor::enclosingArray(MathCursor::idx_type & idx) const
+MathGridInset * MathCursor::enclosingGrid(MathCursor::idx_type & idx) const
 {
        for (int i = Cursor_.size() - 1; i >= 0; --i) {
-               MathArrayInset * p = (*Cursor_[i].par_)->asArrayInset();
+               MathGridInset * p = (*Cursor_[i].par_)->asGridInset();
                if (p) {
                        idx = Cursor_[i].idx_;
                        return p;
@@ -961,7 +975,7 @@ void MathCursor::normalize() const
                lyxerr << "this should not really happen - 2: "
                        << pos() << " " << size() <<  " in idx: " << it->idx()
                        << " in atom: '";
-               MathWriteInfo wi(0, lyxerr, false);
+               WriteStream wi(0, lyxerr, false);
                it->par()->write(wi);
                lyxerr << "\n";
                dump("error 4");
@@ -1078,7 +1092,7 @@ void MathCursor::breakLine()
        while (popRight())
                ;
 
-       MathMatrixInset * p = formula()->par()->asMatrixInset();
+       MathHullInset * p = formula()->par()->asHullInset();
        if (!p)
                return;
 
@@ -1091,12 +1105,8 @@ void MathCursor::breakLine()
 
                // split line
                const row_type r = row();
-               for (col_type c = col() + 1; c < p->ncols(); ++c) {
-                       const MathMatrixInset::idx_type i1 = p->index(r, c);
-                       const MathMatrixInset::idx_type i2 = p->index(r + 1, c);        
-                       //lyxerr << "swapping cells " << i1 << " and " << i2 << "\n";
-                       p->cell(i1).swap(p->cell(i2));
-               }
+               for (col_type c = col() + 1; c < p->ncols(); ++c)
+                       p->cell(p->index(r, c)).swap(p->cell(p->index(r + 1, c)));
 
                // split cell
                splitCell();
@@ -1105,10 +1115,18 @@ void MathCursor::breakLine()
 }
 
 
+void MathCursor::readLine(MathArray & ar) const
+{
+       idx_type base = row() * par()->ncols();
+       for (idx_type off = 0; off < par()->ncols(); ++off)
+               ar.push_back(par()->cell(base + off));
+}
+
+
 char MathCursor::valign() const
 {
        idx_type idx;
-       MathArrayInset * p = enclosingArray(idx);
+       MathGridInset * p = enclosingGrid(idx);
        return p ? p->valign() : '\0';
 }
 
@@ -1116,7 +1134,7 @@ char MathCursor::valign() const
 char MathCursor::halign() const
 {
        idx_type idx;
-       MathArrayInset * p = enclosingArray(idx);
+       MathGridInset * p = enclosingGrid(idx);
        return p ? p->halign(idx % p->ncols()) : '\0';
 }
 
@@ -1253,22 +1271,29 @@ bool MathCursor::idxRight()
 }
 
 
-void MathCursor::interpret(string const & s)
+bool MathCursor::interpret(string const & s)
 {
        //lyxerr << "interpret 1: '" << s << "'\n";
        if (s.empty())
-               return;
+               return true;
 
-       if (s.size() == 1) {
-               interpret(s[0]);
-               return;
-       }
+       if (s.size() == 1)
+               return interpret(s[0]);
 
        //lyxerr << "char: '" << s[0] << "'  int: " << int(s[0]) << endl;
        //owner_->getIntl()->getTrans().TranslateAndInsert(s[0], lt);   
        //lyxerr << "trans: '" << s[0] << "'  int: " << int(s[0]) << endl;
 
-       if (s.size() > 7 && s.substr(0, 7) == "matrix ") {
+       if (s.size() >= 5 && s.substr(0, 5) == "cases") {
+               unsigned int n = 1;
+               istringstream is(s.substr(6).c_str());
+               is >> n;
+               n = std::max(1u, n);
+               niceInsert(MathAtom(new MathCasesInset(n)));
+               return true;
+       }
+
+       if (s.size() >= 6 && s.substr(0, 6) == "matrix") {
                unsigned int m = 1;
                unsigned int n = 1;
                string v_align;
@@ -1279,7 +1304,7 @@ void MathCursor::interpret(string const & s)
                n = std::max(1u, n);
                v_align += 'c';
                niceInsert(MathAtom(new MathArrayInset(m, n, v_align[0], h_align)));
-               return;
+               return true;
        }
 
        if (s == "\\over" || s == "\\choose" || s == "\\atop") {
@@ -1290,76 +1315,78 @@ void MathCursor::interpret(string const & s)
                niceInsert(t);
                popRight();
                left();
-               return;
+               return true;
        }
 
        niceInsert(createMathInset(s.substr(1)));
+       return true;
 }
 
 
-void MathCursor::interpret(char c)
+bool MathCursor::interpret(char c)
 {
        //lyxerr << "interpret 2: '" << c << "'\n";
+       if (c == '^' || c == '_') {
+               macroModeClose();
+               const bool up = (c == '^');
+               selCut();
+               if (hasPrevAtom() && prevAtom()->asScriptInset()) {
+                       prevAtom()->asScriptInset()->ensure(up);
+                       pushRight(prevAtom());
+                       idx() = up;
+                       pos() = size();
+               } else if (hasNextAtom() && nextAtom()->asScriptInset()) {
+                       nextAtom()->asScriptInset()->ensure(up);
+                       pushLeft(nextAtom());
+                       idx() = up;
+                       pos() = 0;
+               } else {
+                       plainInsert(MathAtom(new MathScriptInset(up)));
+                       prevAtom()->asScriptInset()->ensure(up);
+                       pushRight(prevAtom());
+                       idx() = up;
+                       pos() = 0;
+               }
+               selPaste();
+               dump("1");
+               return true;
+       }
+
 
+       // handle macroMode
        if (inMacroMode()) {
                string name = macroName();
 
                if (name == "\\" && c == '#') {
                        insert(c, LM_TC_TEX);
-                       return;
+                       return true;
                }
 
                if (name == "\\" && c == '\\') {
                        backspace();
                        interpret("\\backslash");
-                       return;
+                       return true;
                }
 
                if (name == "\\#" && '1' <= c && c <= '9') {
                        insert(c, LM_TC_TEX);
                        macroModeClose();
-                       return;
+                       return true;
                }
 
                if (isalpha(c)) {
                        insert(c, LM_TC_TEX);
-                       return;
+                       return true;
                }
 
                if (name == "\\") {
                        insert(c, LM_TC_TEX);
                        macroModeClose();
-                       return;
+                       return true;
                }
 
                macroModeClose();
-               return;
-       }
-
-       // no macro mode
-       if (c == '^' || c == '_') {
-               const bool up = (c == '^');
-               selCut();
-               if (hasPrevAtom() && prevAtom()->asScriptInset()) {
-                       prevAtom()->asScriptInset()->ensure(up);
-                       pushRight(prevAtom());
-                       idx() = up;
-                       pos() = size();
-               } else if (hasNextAtom() && nextAtom()->asScriptInset()) {
-                       nextAtom()->asScriptInset()->ensure(up);
-                       pushLeft(nextAtom());
-                       idx() = up;
-                       pos() = 0;
-               } else {
-                       plainInsert(MathAtom(new MathScriptInset(up)));
-                       prevAtom()->asScriptInset()->ensure(up);
-                       pushRight(prevAtom());
-                       idx() = up;
-                       pos() = 0;
-               }
-               selPaste();
-               dump("1");
-               return;
+               return true;
        }
 
        if (selection_)
@@ -1370,51 +1397,66 @@ void MathCursor::interpret(char c)
                // the still allows typing  '<space>a<space>' and deleting the 'a', but
                // it is better than nothing
                if (hasPrevAtom() && prevAtom()->getChar() == ' ')
-                       return;
+                       return true;
                insert(c, LM_TC_TEXTRM);
-               return;
+               return true;
        }
 
        if (c == ' ') {
                if (hasPrevAtom() && prevAtom()->asSpaceInset()) {
                        prevAtom()->asSpaceInset()->incSpace();
-                       return;
+                       return true;
                }
+       
+               if (mathcursor->popRight())
+                       return true;
 
-               mathcursor->popRight();
-               return;
+               // if are at the very end, leave the formula
+               return pos() != size();
        }
 
+/*
        if (strchr("{}", c)) {
                insert(c, LM_TC_TEX);
-               return;
+               return true;
+       }
+*/
+
+       if (c == '{') {
+               niceInsert(MathAtom(new MathBraceInset));
+               return true;
+       }
+
+       if (c == '}') {
+               return true;
        }
 
        if (strchr("#$%", c)) {
                insert(MathAtom(new MathSpecialCharInset(c)));  
                lastcode_ = LM_TC_VAR;
-               return;
+               return true;
        }
 
        if (isalpha(c) && lastcode_ == LM_TC_GREEK) {
                insert(c, LM_TC_VAR);
-               return
+               return true;
        }
 
        if (isalpha(c) && lastcode_ == LM_TC_GREEK1) {
                insert(c, LM_TC_VAR);
                lastcode_ = LM_TC_VAR;
-               return
+               return true;
        }
 
        if (c == '\\') {
                insert(c, LM_TC_TEX);
                //bv->owner()->message(_("TeX mode"));
-               return; 
+               return true;    
        }
 
        // no special circumstances, so insert the character without any fuss
        insert(c, LM_TC_MIN);
+       return true;
 }
 
 
@@ -1476,3 +1518,18 @@ MathCursorPos MathCursor::normalAnchor() const
 }
 
 
+void MathCursor::stripFromLastEqualSign()
+{
+       // find position of last '=' in the array
+       MathArray & ar = cursor().cell();
+       MathArray::const_iterator et = ar.end();
+       for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
+               if ((*it)->getChar() == '=')
+                       et = it;
+
+       // delete everything behind this position
+       ar.erase(et - ar.begin(), ar.size());
+       pos() = ar.size(); 
+}
+
+