+ clear();
+ push_back(CursorSlice(inset));
+ anchor_ = DocIterator(inset);
+ clearTargetX();
+ selection_ = false;
+ mark_ = false;
+}
+
+
+// this (intentionally) does neither touch anchor nor selection status
+void LCursor::setCursor(DocIterator const & cur)
+{
+ DocIterator::operator=(cur);
+}
+
+
+void LCursor::dispatch(FuncRequest const & cmd0)
+{
+ lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION
+ << " cmd: " << cmd0 << '\n'
+ << *this << endl;
+ if (empty())
+ return;
+
+ fixIfBroken();
+ FuncRequest cmd = cmd0;
+ LCursor safe = *this;
+
+ for (; depth(); pop()) {
+ lyxerr[Debug::DEBUG] << "LCursor::dispatch: cmd: "
+ << cmd0 << endl << *this << endl;
+ BOOST_ASSERT(pos() <= lastpos());
+ BOOST_ASSERT(idx() <= lastidx());
+ BOOST_ASSERT(pit() <= lastpit());
+
+ // The common case is 'LFUN handled, need update', so make the
+ // LFUN handler's life easier by assuming this as default value.
+ // The handler can reset the update and val flags if necessary.
+ disp_.update(true);
+ disp_.dispatched(true);
+ inset().dispatch(*this, cmd);
+ if (disp_.dispatched())
+ break;
+ }
+ // 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!" << endl;
+ operator=(safe);
+ disp_.dispatched(false);
+ }
+}
+
+
+DispatchResult LCursor::result() const
+{
+ return disp_;
+}
+
+
+BufferView & LCursor::bv() const
+{
+ BOOST_ASSERT(bv_);
+ return *bv_;
+}
+
+
+Buffer & LCursor::buffer() const
+{
+ BOOST_ASSERT(bv_);
+ BOOST_ASSERT(bv_->buffer());
+ return *bv_->buffer();
+}
+
+
+void LCursor::pop()
+{
+ BOOST_ASSERT(depth() >= 1);
+ pop_back();
+}
+
+
+void LCursor::push(InsetBase & p)
+{
+ push_back(CursorSlice(p));
+}
+
+
+void LCursor::pushLeft(InsetBase & p)
+{
+ BOOST_ASSERT(!empty());
+ //lyxerr << "Entering inset " << t << " left" << endl;
+ push(p);
+ p.idxFirst(*this);
+}
+
+
+bool LCursor::popLeft()
+{
+ BOOST_ASSERT(!empty());
+ //lyxerr << "Leaving inset to the left" << endl;
+ inset().notifyCursorLeaves(*this);
+ if (depth() == 1)
+ return false;
+ pop();
+ return true;
+}
+
+
+bool LCursor::popRight()
+{
+ BOOST_ASSERT(!empty());
+ //lyxerr << "Leaving inset to the right" << endl;
+ inset().notifyCursorLeaves(*this);
+ if (depth() == 1)
+ return false;
+ pop();
+ ++pos();
+ return true;
+}
+
+
+int LCursor::currentMode()
+{
+ BOOST_ASSERT(!empty());
+ for (int i = depth() - 1; i >= 0; --i) {
+ int res = operator[](i).inset().currentMode();
+ if (res != InsetBase::UNDECIDED_MODE)
+ return res;
+ }
+ return InsetBase::TEXT_MODE;
+}
+
+
+void LCursor::getPos(int & x, int & y) const
+{
+ Point p = bv_funcs::getPos(*this, boundary());
+ x = p.x_;
+ y = p.y_;
+}
+
+
+void LCursor::paste(string const & data)
+{
+ dispatch(FuncRequest(LFUN_PASTE, data));
+}
+
+
+void LCursor::resetAnchor()
+{
+ anchor_ = *this;
+}
+
+
+
+bool LCursor::posLeft()
+{
+ if (pos() == 0)
+ return false;
+ --pos();
+ return true;
+}
+
+
+bool LCursor::posRight()
+{
+ if (pos() == lastpos())
+ return false;
+ ++pos();
+ return true;
+}
+
+
+CursorSlice LCursor::anchor() const
+{
+ BOOST_ASSERT(anchor_.depth() >= depth());
+ CursorSlice normal = anchor_[depth() - 1];
+ if (depth() < anchor_.depth() && top() <= normal) {
+ // anchor is behind cursor -> move anchor behind the inset
+ ++normal.pos();
+ }
+ return normal;
+}
+
+
+CursorSlice LCursor::selBegin() const
+{
+ if (!selection())
+ return top();
+ return anchor() < top() ? anchor() : top();
+}
+
+
+CursorSlice LCursor::selEnd() const
+{
+ if (!selection())
+ return top();
+ return anchor() > top() ? anchor() : top();
+}
+
+
+DocIterator LCursor::selectionBegin() const
+{
+ if (!selection())
+ return *this;
+ return anchor() < top() ? anchor_ : *this;
+}
+
+
+DocIterator LCursor::selectionEnd() const
+{
+ if (!selection())
+ return *this;
+ return anchor() > top() ? anchor_ : *this;
+}
+
+
+void LCursor::setSelection()
+{
+ selection() = true;
+ // A selection with no contents is not a selection
+#ifdef WITH_WARNINGS
+#warning doesnt look ok
+#endif
+ if (pit() == anchor().pit() && pos() == anchor().pos())
+ selection() = false;
+}
+
+
+void LCursor::setSelection(DocIterator const & where, size_t n)
+{
+ setCursor(where);
+ selection() = true;
+ anchor_ = where;
+ pos() += n;
+ // Open all collapsed insets
+ for (int i = depth() - 1; i >= 0; --i)
+ operator[](i).inset().setStatus(*this, InsetBase::Open);
+}
+
+
+void LCursor::clearSelection()
+{
+ selection() = false;
+ mark() = false;
+ resetAnchor();
+ bv().unsetXSel();
+}
+
+
+int & LCursor::x_target()
+{
+ return x_target_;
+}
+
+
+int LCursor::x_target() const
+{
+ return x_target_;
+}
+
+
+void LCursor::clearTargetX()
+{
+ x_target_ = -1;
+}
+
+
+
+void LCursor::info(std::ostream & os) const
+{
+ for (int i = 1, n = depth(); i < n; ++i) {
+ operator[](i).inset().infoize(os);
+ os << " ";
+ }
+ if (pos() != 0)
+ prevInset()->infoize2(os);
+ // overwite old message
+ os << " ";