#include "funcrequest.h"
#include "iterators.h"
#include "lfuns.h"
+#include "lyxfunc.h" // only for setMessage()
#include "lyxrc.h"
-#include "lyxtext.h"
#include "lyxrow.h"
+#include "lyxtext.h"
#include "paragraph.h"
#include "insets/updatableinset.h"
#include "mathed/math_support.h"
#include "support/limited_stack.h"
+#include "support/std_sstream.h"
+
+#include "frontends/LyXView.h"
#include <boost/assert.hpp>
anchor_.push_back(CursorSlice());
current_ = 0;
cached_y_ = 0;
- x_target_ = -1;
+ clearTargetX();
selection_ = false;
mark_ = false;
}
DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
{
- lyxerr << "\nLCursor::dispatch: " << *this << endl;
+ lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
FuncRequest cmd = cmd0;
-
- for (int i = cursor_.size() - 1; i >= 1; --i) {
- current_ = i;
- CursorSlice const & citem = cursor_[i];
- lyxerr << "trying to dispatch to inset " << citem.inset_ << endl;
- DispatchResult res = inset()->dispatch(*this, cmd);
- if (res.dispatched()) {
- lyxerr << " successfully dispatched to inset " << citem.inset_ << endl;
- return DispatchResult(true, true);
- }
- // remove one level of cursor
- switch (res.val()) {
+ disp_.update(true);
+ disp_.val(NONE);
+ for (current_ = cursor_.size() - 1; current_ >= 1; --current_) {
+ // the inset's dispatch() is supposed to reset the update and
+ // val flags if necessary
+ inset()->dispatch(*this, cmd);
+
+ // "Mutate" the request for semi-handled requests that need
+ // additional handling in outer levels.
+ switch (disp_.val()) {
+ case NONE:
+ // the inset handled the event fully
+ current_ = cursor_.size() - 1;
+ return DispatchResult(true, true);
case FINISHED:
- pop(i);
+ // the inset handled the event partially
cmd = FuncRequest(LFUN_FINISHED_LEFT);
break;
case FINISHED_RIGHT:
- pop(i);
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
break;
case FINISHED_UP:
- pop(i);
cmd = FuncRequest(LFUN_FINISHED_UP);
break;
case FINISHED_DOWN:
- pop(i);
cmd = FuncRequest(LFUN_FINISHED_DOWN);
break;
default:
- lyxerr << "not handled on level " << i << " val: " << res.val() << endl;
+ //lyxerr << "not handled on level " << current_
+ // << " val: " << disp_.val() << endl;
break;
}
}
- lyxerr << "trying to dispatch to main text " << bv_->text() << endl;
- DispatchResult res = bv_->text()->dispatch(*this, cmd);
- lyxerr << " result: " << res.val() << endl;
-
- if (!res.dispatched()) {
- lyxerr << "trying to dispatch to bv " << bv_ << endl;
- bool sucess = bv_->dispatch(cmd);
- lyxerr << " result: " << sucess << endl;
- res.dispatched(sucess);
- }
-
- return res;
+ BOOST_ASSERT(current_ == 0);
+ bv_->text()->dispatch(*this, cmd);
+ //lyxerr << " result: " << res.val() << endl;
+ current_ = cursor_.size() - 1;
+ return disp_;
}
void LCursor::pop(int depth)
{
- lyxerr << "LCursor::pop() to depth " << depth << endl;
- while (int(cursor_.size()) > depth)
+ while (int(cursor_.size()) > depth + 1)
pop();
+ lyxerr << "LCursor::pop() result: " << *this << endl;
}
void LCursor::pop()
{
- lyxerr << "LCursor::pop() a level" << endl;
- //BOOST_ASSERT(!cursor_.empty());
- if (cursor_.size() <= 1)
- lyxerr << "### TRYING TO POP FROM EMPTY CURSOR" << endl;
- else {
- cursor_.pop_back();
- anchor_.pop_back();
- current_ = cursor_.size() - 1;
- }
- lyxerr << "LCursor::pop() current now: " << current_ << endl;
+ BOOST_ASSERT(cursor_.size() >= 1);
+ cursor_.pop_back();
+ anchor_.pop_back();
+ current_ = cursor_.size() - 1;
}
void LCursor::pushLeft(InsetBase * p)
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "Entering inset " << t << " left" << endl;
push(p);
p->idxFirst(*this);
bool LCursor::popLeft()
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "Leaving inset to the left" << endl;
if (depth() <= 1) {
if (depth() == 1)
bool LCursor::popRight()
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "Leaving inset to the right" << endl;
if (depth() <= 1) {
if (depth() == 1)
}
inset()->notifyCursorLeaves(idx());
pop();
- posRight();
+ ++pos();
return true;
}
CursorSlice & LCursor::current()
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "accessing cursor slice " << current_
// << ": " << cursor_[current_] << endl;
return cursor_[current_];
int LCursor::currentMode()
{
+ BOOST_ASSERT(!cursor_.empty());
for (int i = cursor_.size() - 1; i >= 1; --i) {
int res = cursor_[i].inset()->currentMode();
if (res != MathInset::UNDECIDED_MODE)
LyXText * LCursor::innerText() const
{
- //lyxerr << "LCursor::innerText() depth: " << cursor_.size() << endl;
+ BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1) {
// go up until first non-0 text is hit
// (innermost text is 0 in mathed)
CursorSlice const & LCursor::innerTextSlice() const
{
- //lyxerr << "LCursor::innerTextSlice() depth: " << cursor_.size() << endl;
+ BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1) {
// go up until first non-0 text is hit
// (innermost text is 0 in mathed)
void LCursor::updatePos()
{
+ BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1)
- cached_y_ = bv_->top_y() + cursor_.back().inset()->y();
+ cached_y_ = bv_->top_y() + cursor_.back().inset()->yo();
+ //cached_y_ = cursor_.back().inset()->yo();
}
-void LCursor::getDim(int & asc, int & desc) const
+void LCursor::getDim(int & asc, int & des) const
{
- LyXText * txt = innerText();
-
- if (txt) {
- Row const & row = *txt->cursorRow();
- asc = row.baseline();
- desc = row.height() - asc;
- } else {
+ BOOST_ASSERT(!cursor_.empty());
+ if (inMathed()) {
+ BOOST_ASSERT(inset());
+ BOOST_ASSERT(inset()->asMathInset());
+ //inset()->asMathInset()->getCursorDim(asc, des);
asc = 10;
- desc = 10;
- //innerInset()->getCursorDim(asc, desc);
+ des = 10;
+ } else {
+ Row const & row = textRow();
+ asc = row.baseline();
+ des = row.height() - asc;
}
}
void LCursor::getPos(int & x, int & y) const
{
- if (cursor_.size() <= 1) {
- x = bv_->text()->cursorX();
- y = bv_->text()->cursorY();
-// y -= bv_->top_y();
+ BOOST_ASSERT(!cursor_.empty());
+ x = 0;
+ y = 0;
+ if (cursor_.size() == 1) {
+ x = bv_->text()->cursorX(cursor_.front());
+ y = bv_->text()->cursorY(cursor_.front());
} else {
- if (inset()->asUpdatableInset()) {
- // Would be nice to clean this up to make some understandable sense...
- // Non-obvious. The reason we have to have these
- // extra checks is that the ->getCursor() calls rely
- // on the inset's own knowledge of its screen position.
- // If we scroll up or down in a big enough increment, the
- // inset->draw() is not called: this doesn't update
- // inset.top_baseline, so getCursor() returns an old value.
- // Ugly as you like.
- inset()->asUpdatableInset()->getCursorPos(cursor_.back().idx_, x, y);
- x += inset()->asUpdatableInset()->x();
- y += cached_y_;
- } else if (inset()->asMathInset()) {
- getScreenPos(x, y);
- } else {
- // this should not happen
- BOOST_ASSERT(false);
+ if (!inset()) {
+ lyxerr << "#### LCursor::getPos: " << *this << endl;
+ BOOST_ASSERT(inset());
}
+ inset()->getCursorPos(cursor_.back(), x, y);
+ // getCursorPos gives _screen_ coordinates. We need to add
+ // top_y to get document coordinates. This is hidden in cached_y_.
+ //y += cached_y_ - inset()->yo();
+ // The rest is non-obvious. The reason we have to have these
+ // extra computation is that the getCursorPos() calls rely
+ // on the inset's own knowledge of its screen position.
+ // If we scroll up or down in a big enough increment,
+ // inset->draw() is not called: this doesn't update
+ // inset.yo_, so getCursor() returns an old value.
+ // Ugly as you like.
}
+ //lyxerr << "#### LCursor::getPos: " << *this
+ // << " x: " << x << " y: " << y << endl;
}
{
if (!selection())
return cursor_.back();
- // can't use std::min as this creates a new object
return anchor() < cursor_.back() ? anchor() : cursor_.back();
}
{
if (!selection())
return cursor_.back();
+ // can't use std::min as this returns a const ref
return anchor() < cursor_.back() ? anchor() : cursor_.back();
}
CursorSlice & LCursor::selEnd()
{
- if (selection())
+ if (!selection())
return cursor_.back();
+ // can't use std::min as this returns a const ref
return anchor() > cursor_.back() ? anchor() : cursor_.back();
}
}
-void LCursor::x_target(int x)
+int & LCursor::x_target()
{
- x_target_ = x;
+ return x_target_;
}
}
+void LCursor::clearTargetX()
+{
+ x_target_ = -1;
+}
+
+
+LyXText * LCursor::text() const
+{
+ return current_ ? current().text() : bv_->text();
+}
+
+
Paragraph & LCursor::paragraph()
{
+ BOOST_ASSERT(inTexted());
return current_ ? current().paragraph() : *bv_->text()->getPar(par());
}
Paragraph const & LCursor::paragraph() const
{
+ BOOST_ASSERT(inTexted());
return current_ ? current().paragraph() : *bv_->text()->getPar(par());
}
+Row & LCursor::textRow()
+{
+ return *paragraph().getRow(pos());
+}
+
+
+Row const & LCursor::textRow() const
+{
+ return *paragraph().getRow(pos());
+}
+
+
+LCursor::par_type LCursor::lastpar() const
+{
+ return inMathed() ? 0 : text()->paragraphs().size() - 1;
+}
+
+
LCursor::pos_type LCursor::lastpos() const
{
- CursorSlice const & cur = current();
- if (cur.inset() && cur.inset()->asMathInset())
- return cell().size();
- else
- return paragraph().size();
+ InsetBase * inset = current().inset();
+ return inset && inset->asMathInset() ? cell().size() : paragraph().size();
+}
+
+
+LCursor::row_type LCursor::crow() const
+{
+ return paragraph().row(pos());
+}
+
+
+LCursor::row_type LCursor::lastcrow() const
+{
+ return paragraph().rows.size();
}
}
-void LCursor::info(std::ostream & os)
+void LCursor::info(std::ostream & os) const
{
for (int i = 1, n = depth(); i < n; ++i) {
cursor_[i].inset()->infoize(os);
os << " ";
}
-#warning FIXME
- //if (pos() != 0)
- // prevAtom()->infoize2(os);
+ if (pos() != 0)
+ prevInset()->infoize2(os);
// overwite old message
os << " ";
}
void LCursor::eraseSelection()
{
- CursorSlice i1 = selBegin();
- CursorSlice i2 = selEnd();
+ //lyxerr << "LCursor::eraseSelection" << endl;
+ CursorSlice const & i1 = selBegin();
+ CursorSlice const & i2 = selEnd();
#warning FIXME
if (i1.inset()->asMathInset()) {
if (i1.idx_ == i2.idx_) {
} else {
lyxerr << "can't erase this selection 1" << endl;
}
+ //lyxerr << "LCursor::eraseSelection end" << endl;
}
void LCursor::selDel()
{
+ //lyxerr << "LCursor::selDel" << endl;
if (selection()) {
eraseSelection();
selection() = false;
void LCursor::selHandle(bool sel)
{
+ //lyxerr << "LCursor::selHandle" << endl;
if (sel == selection())
return;
resetAnchor();
}
-void LCursor::selStart()
-{
- resetAnchor();
- selection() = true;
-}
-
-
void LCursor::selClearOrDel()
{
+ //lyxerr << "LCursor::selClearOrDel" << endl;
if (lyxrc.auto_region_delete)
selDel();
else
std::ostream & operator<<(std::ostream & os, LCursor const & cur)
{
- os << "\n";
for (size_t i = 0, n = cur.cursor_.size(); i != n; ++i)
- os << " (" << cur.cursor_[i] << " | " << cur.anchor_[i] << "\n";
+ os << " " << cur.cursor_[i] << " | " << cur.anchor_[i] << "\n";
+ os << " current: " << cur.current_ << endl;
+ os << " selection: " << cur.selection_ << endl;
return os;
}
// we can't move into anything new during selection
if (depth() == anchor_.size())
return false;
- if (t.nucleus() != anchor_[depth()].inset())
+ if (!ptr_cmp(t.nucleus(), anchor_[depth()].inset()))
return false;
return true;
bool LCursor::left()
{
autocorrect() = false;
- x_target(-1); // "no target"
+ clearTargetX();
if (inMacroMode()) {
macroModeClose();
return true;
if (pos() != 0 && openable(prevAtom())) {
posLeft();
- push(inset());
- inset()->idxFirst(*this);
+ push(nextAtom().nucleus());
+ inset()->idxLast(*this);
return true;
}
bool LCursor::right()
{
autocorrect() = false;
- x_target(-1); // "no target"
+ clearTargetX();
if (inMacroMode()) {
macroModeClose();
return true;
}
if (pos() != lastpos() && openable(nextAtom())) {
- pushLeft(inset());
+ pushLeft(nextAtom().nucleus());
+ inset()->idxFirst(*this);
return true;
}
return false;
// anchor might be deeper, should have same path then
- for (CursorBase::size_type i = 0; i < cursor.size(); ++i)
+ for (size_t i = 0; i < cursor.size(); ++i)
if (cursor[i].inset() != anchor[i].inset())
return false;
idx() = 0;
pos() = 0;
}
- x_target(-1); // "no target"
+ clearTargetX();
}
macroModeClose();
if (!inset()->idxHome(*this))
return popLeft();
- x_target(-1); // "no target"
+ clearTargetX();
return true;
}
macroModeClose();
if (!inset()->idxEnd(*this))
return popRight();
- x_target(-1); // "no target"
+ clearTargetX();
return true;
}
}
-void LCursor::insert2(string const & str)
-{
- MathArray ar;
- asArray(str, ar);
- insert(ar);
-}
-
-
void LCursor::insert(string const & str)
{
- //lyxerr << "inserting '" << str << "'" << endl;
+ lyxerr << "LCursor::insert str '" << str << "'" << endl;
selClearOrDel();
+#if 0
for (string::const_iterator it = str.begin(); it != str.end(); ++it)
plainInsert(MathAtom(new MathCharInset(*it)));
+#else
+ MathArray ar;
+ asArray(str, ar);
+ insert(ar);
+#endif
}
void LCursor::insert(char c)
{
- //lyxerr << "inserting '" << c << "'" << endl;
+ //lyxerr << "LCursor::insert char '" << c << "'" << endl;
selClearOrDel();
plainInsert(MathAtom(new MathCharInset(c)));
}
void LCursor::insert(MathAtom const & t)
{
+ //lyxerr << "LCursor::insert MathAtom: " << endl;
macroModeClose();
selClearOrDel();
plainInsert(t);
}
+void LCursor::insert(InsetBase * inset)
+{
+ if (inMathed())
+ insert(MathAtom(inset));
+ else
+ text()->insertInset(*this, inset);
+}
+
+
void LCursor::niceInsert(string const & t)
{
MathArray ar;
// enter the new inset and move the contents of the selection if possible
if (t->isActive()) {
posLeft();
- pushLeft(inset());
+ // be careful here: don't use 'pushLeft(t)' as this we need to
+ // push the clone, not the original
+ pushLeft(nextAtom().nucleus());
paste(safe);
}
}
}
// delete empty cells if possible
-#warning FIXME
- //if (cell().empty() && inset()->idxDelete(idx()))
- // return true;
+ if (pos() == lastpos() && inset()->idxDelete(idx()))
+ return true;
// special behaviour when in last position of cell
if (pos() == lastpos()) {
}
-void LCursor::drawSelection(PainterInfo & pi)
-{
- if (!selection())
- return;
- CursorSlice i1 = selBegin();
- CursorSlice i2 = selEnd();
- i1.asMathInset()->drawSelection(pi, i1.idx_, i1.pos_, i2.idx_, i2.pos_);
-}
-
-
void LCursor::handleNest(MathAtom const & a, int c)
{
- MathAtom at = a;
- asArray(grabAndEraseSelection(), at.nucleus()->cell(c));
- insert(at);
+ //lyxerr << "LCursor::handleNest: " << c << endl;
+ MathAtom t = a;
+ asArray(grabAndEraseSelection(), t.nucleus()->cell(c));
+ insert(t);
posLeft();
- pushLeft(inset());
-}
-
-
-void LCursor::getScreenPos(int & x, int & y) const
-{
- BOOST_ASSERT(inset());
- BOOST_ASSERT(inset()->asMathInset());
- inset()->asMathInset()->getScreenPos(idx(), pos(), x, y);
+ pushLeft(nextAtom().nucleus());
}
return x_target();
int x = 0;
int y = 0;
- getScreenPos(x, y);
+ getPos(x, y);
return x;
}
MathHullInset * LCursor::formula() const
{
- for (int i = cursor_.size() - 1; i >= 1; --i)
- if (cursor_[i].inset()->lyxCode() == InsetBase::MATH_CODE)
- return static_cast<MathHullInset *>(cursor_[i].inset());
+ for (int i = cursor_.size() - 1; i >= 1; --i) {
+ MathInset * inset = cursor_[i].inset()->asMathInset();
+ if (inset && inset->asHullInset())
+ return static_cast<MathHullInset *>(inset);
+ }
return 0;
}
void LCursor::pullArg()
{
-#warning look here
-#if 0
+#warning Look here
MathArray ar = cell();
- if (popLeft()) {
+ if (popLeft() && inMathed()) {
plainErase();
cell().insert(pos(), ar);
resetAnchor();
} else {
- formula()->mutateToText();
+ //formula()->mutateToText();
}
-#endif
}
<< idx() << ' ' << nargs()
<< " in: " << inset() << endl;
}
- idx() = min(idx(), nargs() - 1);
+ idx() = min(idx(), lastidx());
if (pos() > lastpos()) {
lyxerr << "this should not really happen - 2: "
bool LCursor::goUpDown(bool up)
{
- // Be warned: The 'logic' implemented in this function is highly fragile.
- // A distance of one pixel or a '<' vs '<=' _really_ matters.
- // So fiddle around with it only if you know what you are doing!
+ // Be warned: The 'logic' implemented in this function is highly
+ // fragile. A distance of one pixel or a '<' vs '<=' _really
+ // matters. So fiddle around with it only if you think you know
+ // what you are doing!
int xo = 0;
int yo = 0;
- getScreenPos(xo, yo);
+ getPos(xo, yo);
// check if we had something else in mind, if not, this is the future goal
if (x_target() == -1)
- x_target(xo);
+ x_target() = xo;
else
xo = x_target();
// any improvement so far?
int xnew, ynew;
- getScreenPos(xnew, ynew);
+ getPos(xnew, ynew);
if (up ? ynew < yo : ynew > yo)
return true;
}
// avoid invalid nesting when selecting
if (!selection() || positionable(it, anchor_)) {
int xo, yo;
- it.back().getScreenPos(xo, yo);
+ CursorSlice & cur = it.back();
+ cur.inset()->getCursorPos(cur, xo, yo);
if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
//lyxerr << "x: " << x << " y: " << y << " d: " << endl;
double best_dist = 1e10;
CursorBase it = cursor_;
- it.back().pos(0);
+ it.back().pos() = 0;
CursorBase et = cursor_;
- int n = et.back().asMathInset()->cell(et.back().idx_).size();
- et.back().pos(n);
+ et.back().pos() = et.back().asMathInset()->cell(et.back().idx_).size();
for (int i = 0; ; ++i) {
int xo, yo;
- it.back().getScreenPos(xo, yo);
+ CursorSlice & cur = it.back();
+ cur.inset()->getCursorPos(cur, xo, yo);
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
// '<=' in order to take the last possible position
// this is important for clicking behind \sum in e.g. '\sum_i a'
bool LCursor::script(bool up)
{
// Hack to get \\^ and \\_ working
+ lyxerr << "handling script: up: " << up << endl;
if (inMacroMode() && macroName() == "\\") {
if (up)
niceInsert(createMathInset("mathcircumflex"));
idx() = up;
pos() = 0;
} else if (pos() != 0 && prevAtom()->asScriptInset()) {
- prevAtom().nucleus()->asScriptInset()->ensure(up);
- posLeft();
- push(inset());
+ --pos();
+ nextAtom().nucleus()->asScriptInset()->ensure(up);
+ push(nextInset());
idx() = up;
pos() = lastpos();
} else if (pos() != 0) {
--pos();
- cell()[pos()]
- = MathAtom(new MathScriptInset(nextAtom(), up));
- push(inset());
+ cell()[pos()] = MathAtom(new MathScriptInset(nextAtom(), up));
+ push(nextInset());
idx() = up;
pos() = 0;
} else {
plainInsert(MathAtom(new MathScriptInset(up)));
- posLeft();
+ --pos();
nextAtom().nucleus()->asScriptInset()->ensure(up);
- push(inset());
+ push(nextInset());
idx() = up;
pos() = 0;
}
bool LCursor::interpret(char c)
{
//lyxerr << "interpret 2: '" << c << "'" << endl;
- x_target(-1); // "no target"
+ clearTargetX();
if (inMacroArgMode()) {
posLeft();
plainErase();
} else if (popLeft() && pos() != lastpos()) {
// ... or enclosing inset if we are in the last inset position
nextAtom().nucleus()->lock(!nextAtom()->lock());
- posRight();
+ ++pos();
}
}
}
//lyx::BOOST_ASSERT(Anchor_.size() >= cursor.depth());
// use Anchor on the same level as Cursor
- CursorSlice normal = anchor_[depth() - 1];
+ CursorSlice normal = anchor_[current_];
#if 0
if (depth() < anchor_.size() && !(normal < xx())) {
// anchor is behind cursor -> move anchor behind the inset
// mouse clicks are somewhat special
// check
switch (cmd.action) {
- case LFUN_MOUSE_PRESS:
- case LFUN_MOUSE_MOTION:
- case LFUN_MOUSE_RELEASE:
- case LFUN_MOUSE_DOUBLE: {
- CursorSlice & pos = cursor_.back();
- int x = 0;
- int y = 0;
- getScreenPos(x, y);
- if (x < cmd.x && pos() != 0) {
- DispatchResult const res = prevAtom().nucleus()->dispatch(cmd);
- if (res.dispatched())
- return res;
- }
- if (x > cmd.x && pos() != lastpos()) {
- DispatchResult const res = inset()->dispatch(cmd);
- if (res.dispatched())
- return res;
- }
+ case LFUN_MOUSE_PRESS:
+ case LFUN_MOUSE_MOTION:
+ case LFUN_MOUSE_RELEASE:
+ case LFUN_MOUSE_DOUBLE: {
+ CursorSlice & pos = cursor_.back();
+ int x = 0;
+ int y = 0;
+ getPos(x, y);
+ if (x < cmd.x && pos() != 0) {
+ DispatchResult const res = prevAtom().nucleus()->dispatch(cmd);
+ if (res.dispatched())
+ return res;
}
- default:
- break;
+ if (x > cmd.x && pos() != lastpos()) {
+ DispatchResult const res = inset()->dispatch(cmd);
+ if (res.dispatched())
+ return res;
+ }
+ }
+ default:
+ break;
}
- /...
}
*/
void LCursor::handleFont(string const & font)
{
+ lyxerr << "LCursor::handleFont: " << font << endl;
string safe;
if (selection()) {
macroModeClose();
}
-void LCursor::releaseMathCursor()
+bool LCursor::inMathed() const
{
- if (inMathed())
- formula()->insetUnlock(bv());
+ return formula();
}
-bool LCursor::inMathed() const
+bool LCursor::inTexted() const
{
- return formula();
+ return !formula();
+}
+
+
+InsetBase * LCursor::nextInset()
+{
+ if (pos() == lastpos())
+ return 0;
+ if (inMathed())
+ return nextAtom().nucleus();
+ return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
+}
+
+
+InsetBase * LCursor::prevInset()
+{
+ if (pos() == 0)
+ return 0;
+ if (inMathed())
+ return prevAtom().nucleus();
+ return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
+}
+
+
+InsetBase const * LCursor::prevInset() const
+{
+ if (pos() == 0)
+ return 0;
+ if (inMathed())
+ return prevAtom().nucleus();
+ return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
+}
+
+
+void LCursor::message(string const & msg) const
+{
+ bv().owner()->getLyXFunc().setMessage(msg);
+}
+
+
+void LCursor::errorMessage(string const & msg) const
+{
+ bv().owner()->getLyXFunc().setErrorMessage(msg);
+}
+
+
+string LCursor::selectionAsString(bool label) const
+{
+ if (!selection())
+ return string();
+
+ if (inTexted()) {
+ Buffer const & buffer = *bv().buffer();
+
+ // should be const ...
+ ParagraphList::iterator startpit = text()->getPar(selBegin());
+ ParagraphList::iterator endpit = text()->getPar(selEnd());
+ size_t const startpos = selBegin().pos();
+ size_t const endpos = selEnd().pos();
+
+ if (startpit == endpit)
+ return startpit->asString(buffer, startpos, endpos, label);
+
+ // First paragraph in selection
+ string result =
+ startpit->asString(buffer, startpos, startpit->size(), label) + "\n\n";
+
+ // The paragraphs in between (if any)
+ ParagraphList::iterator pit = startpit;
+ for (++pit; pit != endpit; ++pit)
+ result += pit->asString(buffer, 0, pit->size(), label) + "\n\n";
+
+ // Last paragraph in selection
+ result += endpit->asString(buffer, 0, endpos, label);
+
+ return result;
+ }
+
+#warning an mathed?
+ return string();
+}
+
+
+string LCursor::currentState()
+{
+ if (inMathed()) {
+ std::ostringstream os;
+ info(os);
+ return os.str();
+ }
+ return text() ? text()->currentState(*this) : string();
+}
+
+
+// only used by the spellchecker
+void LCursor::replaceWord(string const & replacestring)
+{
+ LyXText * t = text();
+ BOOST_ASSERT(t);
+
+ t->replaceSelectionWithString(*this, replacestring);
+ t->setSelectionRange(*this, replacestring.length());
+
+ // Go back so that replacement string is also spellchecked
+ for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
+ t->cursorLeft(*this, true);
+}
+
+
+void LCursor::update()
+{
+ bv().update();
+}
+
+
+string LCursor::getPossibleLabel()
+{
+ return inMathed() ? "eq:" : text()->getPossibleLabel(*this);
+}
+
+
+void LCursor::notdispatched()
+{
+ disp_.dispatched(false);
+}
+
+
+void LCursor::dispatched(dispatch_result_t res)
+{
+ disp_.val(res);
+}
+
+
+void LCursor::noupdate()
+{
+ disp_.update(false);
}