// 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;
if (disp_.dispatched())
break;
}
+
// it completely to get a 'bomb early' behaviour in case this
// object will be used again.
if (!disp_.dispatched()) {
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_;
}
}
// 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.
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_;
top().pos() = std::min(tm.x2pos(pit(), 0, xo), top().lastpos());
}
}
-
+
updateNeeded |= bv().checkDepm(*this, old);
}
-
+
updateTextTargetOffset();
return true;
}
}
+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
DocIterator selectionBegin() const;
/// access start of selection
DocIterator selectionEnd() const;
- ///
+ /// FIXME: document this
bool selHandle(bool selecting);
- //
+ ///
docstring selectionAsString(bool label) const;
///
docstring currentState();
///
DispatchResult disp_;
+ ///
+ DocIterator const & beforeDispatchCursor() { return beforeDispatchCursor_; }
private:
/**
/// y position before dispatch started
int beforeDispY_;
/// position before dispatch started
- size_t beforeDispDepth_;
-
+ DocIterator beforeDispatchCursor_;
+
private:
//
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();
};
+/**
+ * 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
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;
* It can be forward-declared and passed as a function argument without
* having to expose Inset.h.
*/
-
class Inset_code {
Inset::Code val_;
public:
}
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: