+ LCursor safe = *this;
+
+ for ( ; size(); pop()) {
+ //lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
+ BOOST_ASSERT(pos() <= lastpos());
+ BOOST_ASSERT(idx() <= lastidx());
+ BOOST_ASSERT(par() <= lastpar());
+
+ // 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 << "RESTORING OLD CURSOR!" << endl;
+ operator=(safe);
+ disp_.dispatched(false);
+ }
+ return disp_;
+}
+
+
+bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status)
+{
+ // This is, of course, a mess. Better create a new doc iterator and use
+ // this in Inset::getStatus. This might require an additional
+ // BufferView * arg, though (which should be avoided)
+ LCursor safe = *this;
+ bool res = false;
+ for ( ; size(); pop()) {
+ //lyxerr << "\nLCursor::getStatus: cmd: " << cmd << endl << *this << endl;
+ BOOST_ASSERT(pos() <= lastpos());
+ BOOST_ASSERT(idx() <= lastidx());
+ BOOST_ASSERT(par() <= lastpar());
+
+ // The inset's getStatus() will return 'true' if it made
+ // a definitive decision on whether it want to handle the
+ // request or not. The result of this decision is put into
+ // the 'status' parameter.
+ if (inset().getStatus(*this, cmd, status)) {
+ res = true;
+ break;
+ }
+ }
+ operator=(safe);
+ return res;
+}
+
+
+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(size() >= 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 = size() - 1; i >= 0; --i) {
+ int res = operator[](i).inset().currentMode();
+ if (res != InsetBase::UNDECIDED_MODE)
+ return res;
+ }
+ return InsetBase::TEXT_MODE;
+}
+
+
+void LCursor::getDim(int & asc, int & des) const
+{
+ if (inMathed()) {
+ BOOST_ASSERT(inset().asMathInset());
+ //inset().asMathInset()->getCursorDim(asc, des);
+ asc = 10;
+ des = 10;
+ } else if (inTexted()) {
+ Row const & row = textRow();
+ asc = row.baseline();
+ des = row.height() - asc;
+ } else {
+ lyxerr << "should this happen?" << endl;
+ asc = 10;
+ des = 10;
+ }
+}
+
+
+void LCursor::getPos(int & x, int & y) const
+{
+ x = 0;
+ y = 0;
+ if (!empty())
+ inset().getCursorPos(*this, x, 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;
+}
+