]> git.lyx.org Git - features.git/commitdiff
* the old cursor is stored before dispatch and then used after moving
authorStefan Schimanski <sts@lyx.org>
Thu, 14 Jun 2007 20:32:28 +0000 (20:32 +0000)
committerStefan Schimanski <sts@lyx.org>
Thu, 14 Jun 2007 20:32:28 +0000 (20:32 +0000)
  up/down to tell the insets that the cursor left them. The
  notifyCursorLeaves methods can set updateFlags to trigger a redraw.
* leave mathed with cursor up/down and get the math redrawn for the
  decorations

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18773 a592a061-630c-0410-9148-cb99ea01b6c8

src/Cursor.cpp
src/Cursor.h
src/Text3.cpp
src/insets/Inset.h
src/mathed/InsetMathNest.cpp

index bfb2338b0b71cfda5876714d3b18212f125f16bb..a603ed2a19a7c1352d48fcd91510b6fb799a9bc5 100644 (file)
@@ -301,8 +301,7 @@ void Cursor::dispatch(FuncRequest const & cmd0)
        
        // store some values to be used inside of the handlers
        getPos(beforeDispX_, beforeDispY_);
-       beforeDispDepth_ = depth();
-       
+       beforeDispatchCursor_ = *this;
        for (; depth(); pop()) {
                LYXERR(Debug::DEBUG) << "Cursor::dispatch: cmd: "
                        << cmd0 << endl << *this << endl;
@@ -319,6 +318,7 @@ void Cursor::dispatch(FuncRequest const & cmd0)
                if (disp_.dispatched())
                        break;
        }
+       
        // it completely to get a 'bomb early' behaviour in case this
        // object will be used again.
        if (!disp_.dispatched()) {
@@ -326,6 +326,10 @@ void Cursor::dispatch(FuncRequest const & cmd0)
                operator=(safe);
                disp_.update(Update::None);
                disp_.dispatched(false);
+       } else {
+               // restore the previous one because nested Cursor::dispatch calls
+               // are possible which would change it
+               beforeDispatchCursor_ = safe.beforeDispatchCursor_;
        }
 }
 
@@ -1183,7 +1187,8 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
        // if we cannot move up/down inside this inset anymore
        if (x_target_ == -1)
                setTargetX(xo);
-       else if (xo - textTargetOffset() != x_target() && depth() == beforeDispDepth_) {
+       else if (xo - textTargetOffset() != x_target() && 
+                                        depth() == beforeDispatchCursor_.depth()) {
                // In text mode inside the line (not left or right) possibly set a new target_x,
                // but only if we are somewhere else than the previous target-offset.
                
@@ -1229,7 +1234,7 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                                row + 1 >= int(pm.rows().size()))
                        return false;
        }       
-       
+
        // with and without selection are handled differently
        if (!selection()) {
                int yo = bv_funcs::getPos(bv(), *this, boundary()).y_;
@@ -1272,10 +1277,10 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                                top().pos() = std::min(tm.x2pos(pit(), 0, xo), top().lastpos());
                        }
                }
-               
+
                updateNeeded |= bv().checkDepm(*this, old);
        }
-       
+
        updateTextTargetOffset();
        return true;
 }      
@@ -1483,4 +1488,24 @@ void Cursor::fixIfBroken()
 }
 
 
+bool notifyCursorLeaves(DocIterator const & old, Cursor & cur)
+{
+       // find inset in common
+       size_type i;
+       for (i = 0; i < old.depth() && i < cur.depth(); ++i) {
+               if (&old.inset() != &cur.inset())
+                       break;
+       }
+       
+       // notify everything on top of the common part in old cursor,
+       // but stop if the inset claims the cursor to be invalid now
+       for (;  i < old.depth(); ++i) {
+               if (old[i].inset().notifyCursorLeaves(cur))
+                       return true;
+       }
+       
+       return false;
+}
+
+
 } // namespace lyx
index 998b66767987cd0c95b8d00f1635171727aba238..cf2344f2c6d53de788f809131d7441bdac754efa 100644 (file)
@@ -86,9 +86,9 @@ public:
        DocIterator selectionBegin() const;
        /// access start of selection
        DocIterator selectionEnd() const;
-       ///
+       /// FIXME: document this
        bool selHandle(bool selecting);
-       //
+       ///
        docstring selectionAsString(bool label) const;
        ///
        docstring currentState();
@@ -194,6 +194,8 @@ public:
        
        ///
        DispatchResult disp_;
+       ///
+       DocIterator const & beforeDispatchCursor() { return beforeDispatchCursor_; }
        
 private:
        /**
@@ -225,8 +227,8 @@ private:
        /// y position before dispatch started
        int beforeDispY_;
        /// position before dispatch started
-       size_t beforeDispDepth_;
-               
+       DocIterator beforeDispatchCursor_;
+
 private:
 
        //
@@ -296,6 +298,7 @@ public:
        bool isInside(Inset const *);
 
        /// make sure cursor position is valid
+       /// FIXME: It does a subset of fixIfBroken. Maybe merge them?
        void normalize();
        /// mark current cursor trace for redraw
        void touch();
@@ -328,6 +331,13 @@ public:
 };
 
 
+/**
+ * Notifies all insets which appear in old, but not in cur. Make
+ * Sure that the cursor old is valid, i.e. als inset pointer
+ * point to valid insets! Use Cursor::fixIfBroken if necessary.
+ */
+bool notifyCursorLeaves(DocIterator const & old, Cursor & cur);
+
 
 } // namespace lyx
 
index 31537675bb940258612b5bc53bd773fbce5cfe7f..075f619a352d7f2a91c057bb12ef3ee2ba89e976 100644 (file)
@@ -510,25 +510,25 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        saveSelection(cur);
                break;
 
+       case LFUN_UP_SELECT:
+       case LFUN_DOWN_SELECT:
+               needsUpdate |= cur.selHandle(select);
        case LFUN_UP:
-       case LFUN_UP_SELECT: {
-               //lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl;
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_UP_SELECT);
-               bool const successful = cur.upDownInText(true, needsUpdate);
-               if (!successful)
-                       cur.undispatched();
-               if (cur.selection())
-                       saveSelection(cur);
-               break;
-       }
-
-       case LFUN_DOWN:
-       case LFUN_DOWN_SELECT: {
-               //lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl;
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_DOWN_SELECT);
-               bool const successful = cur.upDownInText(false, needsUpdate);
-               if (!successful)
+       case LFUN_DOWN: {
+               // move cursor up/down
+               bool up = cmd.action == LFUN_UP_SELECT || cmd.action == LFUN_UP;
+               bool const successful = cur.upDownInText(up, needsUpdate);
+               if (successful) {
+                       // notify insets which were left and get their update flags 
+                       notifyCursorLeaves(cur.beforeDispatchCursor(), cur);
+                       cur.fixIfBroken();
+                       
+                       // redraw if you leave mathed (for the decorations)
+                       needsUpdate |= cur.beforeDispatchCursor().inMathed();
+               } else
                        cur.undispatched();
+               
+               // save new selection
                if (cur.selection())
                        saveSelection(cur);
                break;
index 57c3a27cd474a46e9fede8c9ce277d23515b2cee..66a4e658daa60960537108a2129aa32b5b554cf9 100644 (file)
@@ -522,7 +522,6 @@ bool isHighlyEditableInset(Inset const * inset);
  *  It can be forward-declared and passed as a function argument without
  *  having to expose Inset.h.
  */
-
 class Inset_code {
        Inset::Code val_;
 public:
index f3790b192857a713a3eb610836c36061eeb8e8ed..d2c98e901a9a019e6be973307986c584daa7ba63 100644 (file)
@@ -545,35 +545,33 @@ goto_char_backwards:
                }
                break;
 
-       case LFUN_UP:
-               cur.updateFlags(Update::Decoration | Update::FitCursor);
-       case LFUN_UP_SELECT:
-               // FIXME Tried to use clearTargetX and macroModeClose, crashed on cur.up()
-               if (cur.inMacroMode()) {
-                       // Make Helge happy
-                       cur.macroModeClose();
-                       break;
-               }
-               cur.selHandle(cmd.action == LFUN_UP_SELECT);
-               if (!cur.upDownInMath(true))
-                       cur.undispatched();
-               // fixes bug 1598. Please check!
-               cur.normalize();
-               break;
-
        case LFUN_DOWN:
+       case LFUN_UP:
                cur.updateFlags(Update::Decoration | Update::FitCursor);
-       case LFUN_DOWN_SELECT:
+       case LFUN_DOWN_SELECT: 
+       case LFUN_UP_SELECT: {
+               // close active macro
                if (cur.inMacroMode()) {
                        cur.macroModeClose();
                        break;
                }
-               cur.selHandle(cmd.action == LFUN_DOWN_SELECT);
-               if (!cur.upDownInMath(false))
+               
+               // stop/start the selection
+               bool select = cmd.action == LFUN_DOWN_SELECT ||
+                       cmd.action == LFUN_UP_SELECT;
+               cur.selHandle(select);
+               
+               // go up/down
+               bool up = cmd.action == LFUN_UP || cmd.action == LFUN_UP_SELECT;
+               bool successful = cur.upDownInMath(up);
+               if (successful) {
+                       // notify left insets and give them chance to set update flags
+                       lyx::notifyCursorLeaves(cur.beforeDispatchCursor(), cur);
+                       cur.fixIfBroken();
+               }       else
                        cur.undispatched();
-               // fixes bug 1598. Please check!
-               cur.normalize();
                break;
+       }
 
        case LFUN_MOUSE_DOUBLE:
        case LFUN_MOUSE_TRIPLE: