]> git.lyx.org Git - lyx.git/blobdiff - src/Cursor.cpp
Fix functions that used functions but did not defined it
[lyx.git] / src / Cursor.cpp
index 074047f4901f634a21ff0ff70d9b25787ac17883..cab25022d7176cafc76db12683d5432597653ed4 100644 (file)
@@ -322,6 +322,7 @@ DocIterator CursorData::selectionEnd() const
        if (di.depth() > depth()) {
                di.resize(depth());
                ++di.pos();
+               di.boundary(true);
        }
        return di;
 }
@@ -713,6 +714,7 @@ bool CursorData::confirmDeletion(bool const before) const
 Cursor::Cursor(BufferView & bv)
        : CursorData(&bv.buffer()), bv_(&bv),
          x_target_(-1), textTargetOffset_(0),
+         x_clickpos_(-1), y_clickpos_(-1),
          beforeDispatchPosX_(0), beforeDispatchPosY_(0)
 {}
 
@@ -788,15 +790,15 @@ void Cursor::dispatch(FuncRequest const & cmd0)
 
        beginUndoGroup();
 
+       Inset * nextins = nextInset();
        // Is this a function that acts on inset at point?
-       if (lyxaction.funcHasFlag(cmd.action(), LyXAction::AtPoint)
-           && nextInset()) {
+       if (lyxaction.funcHasFlag(cmd.action(), LyXAction::AtPoint) && nextins) {
                disp_.dispatched(true);
                disp_.screenUpdate(Update::FitCursor | Update::Force);
                FuncRequest tmpcmd = cmd;
-               LYXERR(Debug::DEBUG, "Cursor::dispatch: (AtPoint) cmd: "
+               LYXERR(Debug::ACTION, "Cursor::dispatch: (AtPoint) cmd: "
                        << cmd0 << endl << *this);
-               nextInset()->dispatch(*this, tmpcmd);
+               nextins->dispatch(*this, tmpcmd);
                if (disp_.dispatched()) {
                        endUndoGroup();
                        return;
@@ -806,7 +808,7 @@ void Cursor::dispatch(FuncRequest const & cmd0)
        // store some values to be used inside of the handlers
        beforeDispatchCursor_ = *this;
        for (; depth(); pop(), boundary(false)) {
-               LYXERR(Debug::DEBUG, "Cursor::dispatch: cmd: "
+               LYXERR(Debug::ACTION, "Cursor::dispatch: cmd: "
                        << cmd0 << endl << *this);
 
                // In any of these cases, the cursor is invalid, and we should
@@ -828,7 +830,7 @@ void Cursor::dispatch(FuncRequest const & cmd0)
        // it completely to get a 'bomb early' behaviour in case this
        // object will be used again.
        if (!disp_.dispatched()) {
-               LYXERR(Debug::DEBUG, "RESTORING OLD CURSOR!");
+               LYXERR(Debug::ACTION, "RESTORING OLD CURSOR!");
                // We might have invalidated the cursor when removing an empty
                // paragraph while the cursor could not be moved out the inset
                // while we initially thought we could. This might happen when
@@ -901,7 +903,8 @@ void Cursor::pop()
 void Cursor::push(Inset & inset)
 {
        push_back(CursorSlice(inset));
-       inset.setBuffer(*buffer());
+       // See bug #13050
+       // inset.setBuffer(*buffer());
 }
 
 
@@ -1380,6 +1383,13 @@ void Cursor::updateTextTargetOffset()
 }
 
 
+void Cursor::setClickPos(int x, int y)
+{
+       x_clickpos_ = x;
+       y_clickpos_ = y;
+}
+
+
 bool Cursor::selHandle(bool selecting)
 {
        //lyxerr << "Cursor::selHandle" << endl;
@@ -1483,7 +1493,7 @@ void Cursor::insert(char_type c)
        LASSERT(!empty(), return);
        if (inMathed()) {
                cap::selClearOrDel(*this);
-               insert(new InsetMathChar(c));
+               insert(new InsetMathChar(buffer(), c));
        } else {
                text()->insertChar(*this, c);
        }
@@ -1567,7 +1577,7 @@ void Cursor::niceInsert(MathAtom const & t)
                docstring const name = t->asMacro()->name();
                MacroData const * data = buffer()->getMacro(name);
                if (data && data->numargs() - data->optionals() > 0) {
-                       plainInsert(MathAtom(new InsetMathBrace(ar)));
+                       plainInsert(MathAtom(new InsetMathBrace(buffer(), ar)));
                        posBackward();
                }
        }
@@ -1594,9 +1604,20 @@ bool Cursor::backspace(bool const force)
                        // [|], can not delete from inside
                        return false;
                } else {
-                       if (inMathed())
-                               pullArg();
-                       else
+                       if (inMathed()) {
+                               switch (inset().asInsetMath()->getType()) {
+                               case hullEqnArray:
+                               case hullAlign:
+                               case hullFlAlign: {
+                                       FuncRequest cmd(LFUN_CHAR_BACKWARD);
+                                       this->dispatch(cmd);
+                                       break;
+                               }
+                               default:
+                                       pullArg();
+                                       break;
+                               }
+                       } else
                                popBackward();
                        return true;
                }
@@ -1701,8 +1722,11 @@ void Cursor::handleNest(MathAtom const & a)
 {
        idx_type const idx = a.nucleus()->asNestInset()->firstIdx();
        //lyxerr << "Cursor::handleNest: " << idx << endl;
+       InsetMath const * im = selectionBegin().inset().asInsetMath();
+       Parse::flags const f = im && im->currentMode() != InsetMath::MATH_MODE
+               ? Parse::TEXTMODE : Parse::NORMAL;
        MathAtom t = a;
-       asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx));
+       asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx), f);
        insert(t);
        editInsertedInset();
 }
@@ -1789,6 +1813,7 @@ bool Cursor::macroModeClose(bool cancel)
        bool keep_mathmode = user_macro
                || (it != words.end() && (it->second.inset == "font"
                                          || it->second.inset == "oldfont"
+                                         || it->second.inset == "textsize"
                                          || it->second.inset == "mbox"));
        bool ert_macro = !user_macro && it == words.end() && atomAsMacro;
 
@@ -1812,7 +1837,7 @@ bool Cursor::macroModeClose(bool cancel)
        // finally put the macro argument behind, if needed
        if (macroArg) {
                if (selection.size() > 1 || selection[0]->asScriptInset())
-                       plainInsert(MathAtom(new InsetMathBrace(selection)));
+                       plainInsert(MathAtom(new InsetMathBrace(buffer(), selection)));
                else
                        insert(selection);
        }
@@ -1858,8 +1883,6 @@ void Cursor::pullArg()
                plainErase();
                cell().insert(pos(), ar);
                resetAnchor();
-       } else {
-               //formula()->mutateToText();
        }
 }
 
@@ -1983,6 +2006,8 @@ bool Cursor::upDownInMath(bool up)
                // try to find best position within this inset
                if (!selection())
                        setCursor(bruteFind(*this, xo, yo));
+               // FIXME : this is actually only needed for InsetMathMacro (bug #12952).
+               screenUpdateFlags(Update::SinglePar);
                return true;
        }
 
@@ -2026,20 +2051,39 @@ bool Cursor::mathForward(bool word)
                                        posForward();
                                while (pos() < lastpos() && mc == nextMath().mathClass());
                } else if (openable(nextAtom())) {
+                       InsetMathScript const * n = nextMath().asScriptInset();
+                       bool to_brace_deco = n && !n->nuc().empty()
+                               && n->nuc().back()->lyxCode() == MATH_DECORATION_CODE
+                               && n->nuc().back()->mathClass() == MC_OP;
                        // single step: try to enter the next inset
                        pushBackward(nextMath());
                        inset().idxFirst(*this);
+                       // Make sure the cursor moves directly to an
+                       // \overbrace or \underbrace inset (bug 2264)
+                       if (to_brace_deco) {
+                               pushBackward(nextMath());
+                               inset().idxFirst(*this);
+                       }
                } else
                        posForward();
                return true;
        }
        if (inset().idxForward(*this))
                return true;
+       InsetMath const * m = inset().asInsetMath();
+       bool from_brace_deco = m
+               && m->lyxCode() == MATH_DECORATION_CODE
+               && m->mathClass() == MC_OP;
        // try to pop forwards --- but don't pop out of math! leave that to
        // the FINISH lfuns
        int s = depth() - 2;
-       if (s >= 0 && operator[](s).inset().asInsetMath())
-               return popForward();
+       if (s >= 0 && operator[](s).inset().asInsetMath() && popForward()) {
+               // Make sure the cursor moves directly to an
+               // \overbrace or \underbrace inset (bug 2264)
+               bool to_script = inset().asInsetMath()
+                       && inset().asInsetMath()->asScriptInset();
+               return from_brace_deco && to_script ? mathForward(word) : true;
+       }
        return false;
 }
 
@@ -2061,26 +2105,46 @@ bool Cursor::mathBackward(bool word)
                                while (pos() > 0 && mc == prevMath().mathClass());
                        }
                } else if (openable(prevAtom())) {
+                       InsetMathScript const * p = prevMath().asScriptInset();
+                       bool to_brace_deco = p && !p->nuc().empty()
+                               && p->nuc().back()->lyxCode() == MATH_DECORATION_CODE
+                               && p->nuc().back()->mathClass() == MC_OP;
                        // single step: try to enter the preceding inset
                        posBackward();
                        push(nextMath());
                        inset().idxLast(*this);
+                       // Make sure the cursor moves directly to an
+                       // \overbrace or \underbrace inset (bug 2264)
+                       if (to_brace_deco) {
+                               posBackward();
+                               push(nextMath());
+                               inset().idxLast(*this);
+                       }
                } else
                        posBackward();
                return true;
        }
        if (inset().idxBackward(*this))
                return true;
+       InsetMath const * m = inset().asInsetMath();
+       bool from_brace_deco = m
+               && m->lyxCode() == MATH_DECORATION_CODE
+               && m->mathClass() == MC_OP;
        // try to pop backwards --- but don't pop out of math! leave that to
        // the FINISH lfuns
        int s = depth() - 2;
-       if (s >= 0 && operator[](s).inset().asInsetMath())
-               return popBackward();
+       if (s >= 0 && operator[](s).inset().asInsetMath() && popBackward()) {
+               // Make sure the cursor moves directly to an
+               // \overbrace or \underbrace inset (bug 2264)
+               bool to_script = inset().asInsetMath()
+                       && inset().asInsetMath()->asScriptInset();
+               return from_brace_deco && to_script ? mathBackward(word) : true;
+       }
        return false;
 }
 
 
-bool Cursor::upDownInText(bool up, bool & updateNeeded)
+bool Cursor::upDownInText(bool up)
 {
        LASSERT(text(), return false);
 
@@ -2090,6 +2154,9 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
        getPos(xo, yo);
        xo = beforeDispatchPosX_;
 
+       // Is a full repaint necessary?
+       bool updateNeeded = false;
+
        // update the targetX - this is here before the "return false"
        // to set a new target which can be used by InsetTexts above
        // if we cannot move up/down inside this inset anymore
@@ -2158,12 +2225,13 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                        dummy.pos() = dummy.pos() == 0 ? dummy.lastpos() : 0;
                        dummy.pit() = dummy.pit() == 0 ? dummy.lastpit() : 0;
 
-                       updateNeeded |= bv().checkDepm(dummy, *this);
-                       updateTextTargetOffset();
-                       if (updateNeeded)
+                       if (bv().checkDepm(dummy, *this)) {
+                               updateNeeded = true;
                                forceBufferUpdate();
+                       }
+                       updateTextTargetOffset();
                }
-               return false;
+               return updateNeeded;
        }
 
        // with and without selection are handled differently
@@ -2189,6 +2257,7 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                        ++dummy.pos();
                if (bv().checkDepm(dummy, old)) {
                        updateNeeded = true;
+                       forceBufferUpdate();
                        // Make sure that cur gets back whatever happened to dummy (Lgb)
                        operator=(dummy);
                }
@@ -2229,13 +2298,14 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                // When selection==false, this is done by TextMetrics::editXY
                setCurrentFont();
 
-               updateNeeded |= bv().checkDepm(*this, old);
+               if (bv().checkDepm(*this, old)) {
+                       updateNeeded = true;
+                       forceBufferUpdate();
+               }
        }
 
-       if (updateNeeded)
-               forceBufferUpdate();
        updateTextTargetOffset();
-       return true;
+       return updateNeeded;
 }