]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_cursor.C
fix #1073
[lyx.git] / src / mathed / math_cursor.C
index f31fc0bf416b626d1a26e462f24b735f3531b04e..3be9d00658da1bb0df79543da261d35b82d6b0c3 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "support/lstrings.h"
 #include "support/LAssert.h"
+#include "support/limited_stack.h"
 #include "debug.h"
 #include "frontends/Painter.h"
 #include "math_cursor.h"
@@ -58,7 +59,7 @@ using std::isalpha;
 
 
 // matheds own cut buffer
-string theCutBuffer;
+limited_stack<string> theCutBuffer;
 
 
 MathCursor::MathCursor(InsetFormulaBase * formula, bool front)
@@ -102,7 +103,7 @@ void MathCursor::pushRight(MathAtom & t)
 
 bool MathCursor::popLeft()
 {
-       //cerr << "Leaving atom to the left\n";
+       //lyxerr << "Leaving atom to the left\n";
        if (depth() <= 1) {
                if (depth() == 1)
                        par()->notifyCursorLeaves(idx());
@@ -116,7 +117,7 @@ bool MathCursor::popLeft()
 
 bool MathCursor::popRight()
 {
-       //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n";
+       //lyxerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n";
        if (depth() <= 1) {
                if (depth() == 1)
                        par()->notifyCursorLeaves(idx());
@@ -410,56 +411,67 @@ void MathCursor::paste(string const & data)
 }
 
 
-void MathCursor::backspace()
+bool MathCursor::backspace()
 {
        autocorrect_ = false;
 
        if (selection_) {
                selDel();
-               return;
+               return true;
        }
 
        if (pos() == 0) {
+               if (par()->ncols() == 1 &&
+                         par()->nrows() == 1 &&
+                         depth() == 1 &&
+                         size() == 0)
+                       return false;
                pullArg();
-               return;
+               return true;
        }
 
        if (inMacroMode()) {
                MathUnknownInset * p = activeMacro();
                if (p->name().size() > 1) {
                        p->setName(p->name().substr(0, p->name().size() - 1));
-                       return;
+                       return true;
                }
        }
 
        --pos();
        plainErase();
+       return true;
 }
 
 
-void MathCursor::erase()
+bool MathCursor::erase()
 {
        autocorrect_ = false;
        if (inMacroMode())
-               return;
+               return true;
 
        if (selection_) {
                selDel();
-               return;
+               return true;
        }
 
        // delete empty cells if possible
        if (array().empty())
                if (par()->idxDelete(idx()))
-                       return;
+                       return true;
 
        // old behaviour when in last position of cell
        if (pos() == size()) {
-               par()->idxGlue(idx());
-               return;
+               if (par()->ncols() == 1 && par()->nrows() == 1 && depth() == 1 && size() == 0)
+                       return false;
+               else{
+                       par()->idxGlue(idx());
+                       return true;
+               }
        }
 
        plainErase();
+       return true;
 }
 
 
@@ -533,10 +545,10 @@ void MathCursor::selCopy()
 {
        dump("selCopy");
        if (selection_) {
-               theCutBuffer = grabSelection();
+               theCutBuffer.push(grabSelection());
                selection_ = false;
        } else {
-               theCutBuffer.erase();
+               //theCutBuffer.erase();
        }
 }
 
@@ -544,7 +556,7 @@ void MathCursor::selCopy()
 void MathCursor::selCut()
 {
        dump("selCut");
-       theCutBuffer = grabAndEraseSelection();
+       theCutBuffer.push(grabAndEraseSelection());
 }
 
 
@@ -558,11 +570,12 @@ void MathCursor::selDel()
 }
 
 
-void MathCursor::selPaste()
+void MathCursor::selPaste(int n)
 {
        dump("selPaste");
        selClearOrDel();
-       paste(theCutBuffer);
+       if (n < theCutBuffer.size())
+               paste(theCutBuffer[n]);
        //grabSelection();
        selection_ = false;
 }
@@ -597,7 +610,7 @@ void MathCursor::selClearOrDel()
 }
 
 
-void MathCursor::drawSelection(MathPainterInfo & pi) const
+void MathCursor::drawSelection(PainterInfo & pi) const
 {
        if (!selection_)
                return;
@@ -954,7 +967,10 @@ bool MathCursor::goUpDown(bool up)
                }
        }
 
-       // try current cell
+       // try current cell for e.g. text insets
+       if (par()->idxUpDown2(idx(), pos(), up, targetx_))
+               return true;
+
        //xarray().boundingBox(xlow, xhigh, ylow, yhigh);
        //if (up)
        //      yhigh = yo - 4;
@@ -1011,6 +1027,7 @@ bool MathCursor::bruteFind
                        it.back().getPos(xo, yo);
                        if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
                                double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
+                               //lyxerr << "x: " << x << " y: " << y << " d: " << endl;
                                // '<=' in order to take the last possible position
                                // this is important for clicking behind \sum in e.g. '\sum_i a'
                                if (d <= best_dist) {
@@ -1039,12 +1056,13 @@ void MathCursor::bruteFind2(int x, int y)
        it.back().setPos(0);
        MathIterator et = Cursor_;
        et.back().setPos(it.cell().size());
-       while (1) {
+       for (int i = 0; ; ++i) {
                int xo, yo;
                it.back().getPos(xo, yo);
                double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
                // '<=' in order to take the last possible position
                // this is important for clicking behind \sum in e.g. '\sum_i a'
+               lyxerr << "i: " << i << " d: " << d << " best: " << best_dist << endl;
                if (d <= best_dist) {
                        best_dist = d;
                        Cursor_   = it;
@@ -1223,18 +1241,8 @@ bool MathCursor::interpret(char c)
                return pos() != size();
        }
 
-       if (c == '#') {
-               insert(c);
-               return true;
-       }
-
-       if (c == '{' || c == '}') {
-               niceInsert(createMathInset(string(1, c)));
-               return true;
-       }
-
-       if (c == '$') {
-               insert(createMathInset("$"));
+       if (c == '{' || c == '}' || c == '#' || c == '&' || c == '$') {
+               createMathInset(string(1, c));
                return true;
        }
 
@@ -1399,21 +1407,46 @@ MathCursorPos MathCursor::normalAnchor() const
 }
 
 
-MathInset::result_type MathCursor::dispatch(FuncRequest const & cmd)
-{
+dispatch_result MathCursor::dispatch(FuncRequest const & cmd)
+{
+       // mouse clicks are somewhat special 
+       // check
+       switch (cmd.action) {
+               case LFUN_MOUSE_PRESS:
+               case LFUN_MOUSE_MOTION:
+               case LFUN_MOUSE_RELEASE:
+               case LFUN_MOUSE_DOUBLE: {
+                       MathCursorPos & pos = Cursor_.back();
+                       dispatch_result res = UNDISPATCHED;
+                       int x = 0, y = 0;
+                       getPos(x, y);
+                       if (x < cmd.x && hasPrevAtom()) {
+                               res = prevAtom().nucleus()->dispatch(cmd, pos.idx_, pos.pos_);
+                               if (res != UNDISPATCHED)
+                                       return res;
+                       }
+                       if (x > cmd.x && hasNextAtom()) {
+                               res = nextAtom().nucleus()->dispatch(cmd, pos.idx_, pos.pos_);
+                               if (res != UNDISPATCHED)
+                                       return res;
+                       }
+               }
+               default:
+                       break;
+       }
+
        for (int i = Cursor_.size() - 1; i >= 0; --i) {
                MathCursorPos & pos = Cursor_[i];
-               MathInset::result_type
-                       res = pos.par_->dispatch(cmd, pos.idx_, pos.pos_);
-               if (res != MathInset::UNDISPATCHED) {
-                       if (res == MathInset::DISPATCHED_POP) {
+               dispatch_result res = pos.par_->dispatch(cmd, pos.idx_, pos.pos_);
+               if (res != UNDISPATCHED) {
+                       if (res == DISPATCHED_POP) {
                                Cursor_.shrink(i + 1);
                                selClear();
                        }
                        return res;
                }
        }
-       return MathInset::UNDISPATCHED;
+       return UNDISPATCHED;
 }