the DocIterator stuff

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8472 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2004-03-01 17:12:09 +00:00
parent c1e5e3de20
commit fc52df8243
30 changed files with 895 additions and 731 deletions

View File

@ -424,8 +424,15 @@ void BufferView::putSelectionAt(PosIterator const & cur,
if (length) { if (length) {
text->setSelectionRange(cursor(), length); text->setSelectionRange(cursor(), length);
cursor().setSelection(); cursor().setSelection();
if (backwards) if (backwards) {
#if 0
swap(cursor().cursor_, cursor().anchor_); swap(cursor().cursor_, cursor().anchor_);
#else
DocumentIterator it = cursor();
cursor().setCursor(cursor().anchor_, false);
cursor().anchor_ = it;
#endif
}
} }
fitCursor(); fitCursor();

View File

@ -474,7 +474,7 @@ void BufferView::Pimpl::scrollDocView(int value)
bv_->cursor().reset(); bv_->cursor().reset();
LyXText * text = bv_->text(); LyXText * text = bv_->text();
CursorSlice & cur = bv_->cursor().cursor_.front(); CursorSlice & cur = bv_->cursor().front();
int y = text->cursorY(cur); int y = text->cursorY(cur);
if (y < first) if (y < first)
text->setCursorFromCoordinates(bv_->cursor(), 0, first); text->setCursorFromCoordinates(bv_->cursor(), 0, first);
@ -541,10 +541,10 @@ void BufferView::Pimpl::selectionRequested()
} }
if (!xsel_cache_.set || if (!xsel_cache_.set ||
cur.cursor_.back() != xsel_cache_.cursor || cur.back() != xsel_cache_.cursor ||
cur.anchor_.back() != xsel_cache_.anchor) cur.anchor_.back() != xsel_cache_.anchor)
{ {
xsel_cache_.cursor = cur.cursor_.back(); xsel_cache_.cursor = cur.back();
xsel_cache_.anchor = cur.anchor_.back(); xsel_cache_.anchor = cur.anchor_.back();
xsel_cache_.set = cur.selection(); xsel_cache_.set = cur.selection();
sel = cur.selectionAsString(false); sel = cur.selectionAsString(false);
@ -613,11 +613,7 @@ void BufferView::Pimpl::update()
// Callback for cursor timer // Callback for cursor timer
void BufferView::Pimpl::cursorToggle() void BufferView::Pimpl::cursorToggle()
{ {
if (!buffer_) { if (buffer_)
cursor_timeout.restart();
return;
}
screen().toggleCursor(*bv_); screen().toggleCursor(*bv_);
cursor_timeout.restart(); cursor_timeout.restart();
} }
@ -720,7 +716,7 @@ void BufferView::Pimpl::center()
bv_->cursor().clearSelection(); bv_->cursor().clearSelection();
int const half_height = workarea().workHeight() / 2; int const half_height = workarea().workHeight() / 2;
int new_y = text->cursorY(bv_->cursor().cursor_.front()) - half_height; int new_y = text->cursorY(bv_->cursor().front()) - half_height;
if (new_y < 0) if (new_y < 0)
new_y = 0; new_y = 0;
@ -1108,6 +1104,7 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd)
case LFUN_SETMARK: case LFUN_SETMARK:
cur.clearSelection(); cur.clearSelection();
if (cur.mark()) { if (cur.mark()) {
cur.mark() = false;
cur.message(N_("Mark removed")); cur.message(N_("Mark removed"));
} else { } else {
cur.mark() = true; cur.mark() = true;

View File

@ -7,6 +7,22 @@
* BufferView_pimpl.C: rename textwidth -> maxwidth, * BufferView_pimpl.C: rename textwidth -> maxwidth,
prepareToPrint -> computeRowMetrics and remove textWidth accessor. prepareToPrint -> computeRowMetrics and remove textWidth accessor.
2004-03-01 André Pönitz <poenitz@gmx.net>
* dociterator.[Ch]: new class for the 'iterator part' of LCursor.
* cursor.[Ch]: adjust, additioally: remove the 'current_' machinery
* Makefile.am:
* BufferView.C:
* BufferView_pimpl.C:
* buffer.C:
* lyxfind.C:
* lyxfunc.C:
* text.C:
* text2.C:
* text3.C: adjust
2004-03-01 Alfredo Braunstein <abraunst@lyx.org> 2004-03-01 Alfredo Braunstein <abraunst@lyx.org>
* Bidi.[Ch] (computeTables): const correctness * Bidi.[Ch] (computeTables): const correctness

View File

@ -130,7 +130,6 @@ lyx_SOURCES = \
changes.h \ changes.h \
chset.C \ chset.C \
chset.h \ chset.h \
lfuns.h \
config.h.in \ config.h.in \
converter.C \ converter.C \
converter.h \ converter.h \
@ -144,6 +143,8 @@ lyx_SOURCES = \
debug.h \ debug.h \
dimension.C \ dimension.C \
dimension.h \ dimension.h \
dociterator.C \
dociterator.h \
dispatchresult.h \ dispatchresult.h \
encoding.C \ encoding.C \
encoding.h \ encoding.h \
@ -178,6 +179,7 @@ lyx_SOURCES = \
layout.h \ layout.h \
lengthcommon.C \ lengthcommon.C \
lengthcommon.h \ lengthcommon.h \
lfuns.h \
lyx_cb.C \ lyx_cb.C \
lyx_cb.h \ lyx_cb.h \
lyx_main.C \ lyx_main.C \

View File

@ -154,13 +154,13 @@ struct Buffer::Impl
/// need to regenerate .tex? /// need to regenerate .tex?
DepClean dep_clean; DepClean dep_clean;
/// is save needed /// is save needed?
mutable bool lyx_clean; mutable bool lyx_clean;
/// is autosave needed /// is autosave needed?
mutable bool bak_clean; mutable bool bak_clean;
/// is this a unnamed file (New...) /// is this a unnamed file (New...)?
bool unnamed; bool unnamed;
/// buffer is r/o /// buffer is r/o
@ -174,13 +174,13 @@ struct Buffer::Impl
boost::scoped_ptr<Messages> messages; boost::scoped_ptr<Messages> messages;
/** set to true only when the file is fully loaded. /** Set to true only when the file is fully loaded.
* Used to prevent the premature generation of previews * Used to prevent the premature generation of previews
* and by the citation inset. * and by the citation inset.
*/ */
bool file_fully_loaded; bool file_fully_loaded;
/// our Text /// our text
LyXText text; LyXText text;
}; };

View File

@ -57,19 +57,17 @@ limited_stack<string> theCutBuffer;
LCursor::LCursor(BufferView & bv) LCursor::LCursor(BufferView & bv)
: cursor_(1), anchor_(1), bv_(&bv), current_(0), : DocumentIterator(bv), anchor_(bv),
cached_y_(0), x_target_(-1), cached_y_(0), x_target_(-1), selection_(false), mark_(false)
selection_(false), mark_(false)
{} {}
void LCursor::reset() void LCursor::reset()
{ {
cursor_.clear(); clear();
push_back(CursorSlice());
anchor_.clear(); anchor_.clear();
cursor_.push_back(CursorSlice());
anchor_.push_back(CursorSlice()); anchor_.push_back(CursorSlice());
current_ = 0;
cached_y_ = 0; cached_y_ = 0;
clearTargetX(); clearTargetX();
selection_ = false; selection_ = false;
@ -77,6 +75,14 @@ void LCursor::reset()
} }
void LCursor::setCursor(DocumentIterator const & cur, bool sel)
{
// this (intentionally) does not touch the anchor
DocumentIterator::operator=(cur);
selection() = sel;
}
DispatchResult LCursor::dispatch(FuncRequest const & cmd0) DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
{ {
lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl; lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
@ -84,9 +90,11 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
BOOST_ASSERT(idx() <= lastidx()); BOOST_ASSERT(idx() <= lastidx());
BOOST_ASSERT(par() <= lastpar()); BOOST_ASSERT(par() <= lastpar());
FuncRequest cmd = cmd0; FuncRequest cmd = cmd0;
nopop_ = false;
DocumentIterator orig = *this;
disp_.update(true); disp_.update(true);
disp_.val(NONE); disp_.val(NONE);
for (current_ = cursor_.size() - 1; current_ >= 1; --current_) { while (size() != 1) {
// the inset's dispatch() is supposed to reset the update and // the inset's dispatch() is supposed to reset the update and
// val flags if necessary // val flags if necessary
inset()->dispatch(*this, cmd); inset()->dispatch(*this, cmd);
@ -96,7 +104,6 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
switch (disp_.val()) { switch (disp_.val()) {
case NONE: case NONE:
// the inset handled the event fully // the inset handled the event fully
current_ = cursor_.size() - 1;
return DispatchResult(true, true); return DispatchResult(true, true);
case FINISHED_LEFT: case FINISHED_LEFT:
// the inset handled the event partially // the inset handled the event partially
@ -112,15 +119,15 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
cmd = FuncRequest(LFUN_FINISHED_DOWN); cmd = FuncRequest(LFUN_FINISHED_DOWN);
break; break;
default: default:
//lyxerr << "not handled on level " << current_ //lyxerr << "not handled on level " << depth()
// << " val: " << disp_.val() << endl; // << " val: " << disp_.val() << endl;
break; break;
} }
} }
BOOST_ASSERT(current_ == 0); bv().text()->dispatch(*this, cmd);
bv_->text()->dispatch(*this, cmd); if (nopop_)
setCursor(orig, false);
//lyxerr << " result: " << res.val() << endl; //lyxerr << " result: " << res.val() << endl;
current_ = cursor_.size() - 1;
return disp_; return disp_;
} }
@ -128,57 +135,60 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status) bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status)
{ {
lyxerr << "\nLCursor::getStatus: cmd: " << cmd << endl << *this << endl; lyxerr << "\nLCursor::getStatus: cmd: " << cmd << endl << *this << endl;
DocumentIterator orig = *this;
BOOST_ASSERT(pos() <= lastpos()); BOOST_ASSERT(pos() <= lastpos());
BOOST_ASSERT(idx() <= lastidx()); BOOST_ASSERT(idx() <= lastidx());
BOOST_ASSERT(par() <= lastpar()); BOOST_ASSERT(par() <= lastpar());
for (current_ = cursor_.size() - 1; current_ >= 1; --current_) { for ( ; size() != 0; pop_back()) {
// the inset's getStatus() will return 'true' if it made // the inset's getStatus() will return 'true' if it made
// a definitive decision on whether it want to handle the // a definitive decision on whether it want to handle the
// request or not. The result of this decision is put into // request or not. The result of this decision is put into
// the 'status' parameter. // the 'status' parameter.
bool const res = inset()->getStatus(*this, cmd, status); bool const res = inset()->getStatus(*this, cmd, status);
if (res) { if (res) {
current_ = cursor_.size() - 1; setCursor(orig, false);
return true; return true;
} }
} }
BOOST_ASSERT(current_ == 0); bool const res = bv().text()->getStatus(*this, cmd, status);
bool const res = bv_->text()->getStatus(*this, cmd, status); setCursor(orig, false);
current_ = cursor_.size() - 1;
return res; return res;
} }
void LCursor::push(InsetBase * inset) BufferView & LCursor::bv() const
{ {
lyxerr << "LCursor::push() inset: " << inset << endl; return DocumentIterator::bv();
cursor_.push_back(CursorSlice(inset));
anchor_.push_back(CursorSlice(inset));
++current_;
updatePos();
} }
/*
void LCursor::pop(int depth) void LCursor::pop(int depth)
{ {
while (int(cursor_.size()) > depth + 1) while (int(size()) > depth + 1)
pop(); pop();
lyxerr << "LCursor::pop() result: " << *this << endl; lyxerr << "LCursor::pop() result: " << *this << endl;
} }
*/
void LCursor::pop() void LCursor::pop()
{ {
BOOST_ASSERT(cursor_.size() >= 1); BOOST_ASSERT(size() >= 1);
cursor_.pop_back(); pop_back();
anchor_.pop_back(); anchor_.pop_back();
current_ = cursor_.size() - 1; }
void LCursor::push(InsetBase * p)
{
push_back(CursorSlice(p));
} }
void LCursor::pushLeft(InsetBase * p) void LCursor::pushLeft(InsetBase * p)
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
//lyxerr << "Entering inset " << t << " left" << endl; //lyxerr << "Entering inset " << t << " left" << endl;
push(p); push(p);
p->idxFirst(*this); p->idxFirst(*this);
@ -187,7 +197,7 @@ void LCursor::pushLeft(InsetBase * p)
bool LCursor::popLeft() bool LCursor::popLeft()
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
//lyxerr << "Leaving inset to the left" << endl; //lyxerr << "Leaving inset to the left" << endl;
if (depth() <= 1) { if (depth() <= 1) {
if (depth() == 1) if (depth() == 1)
@ -202,7 +212,7 @@ bool LCursor::popLeft()
bool LCursor::popRight() bool LCursor::popRight()
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
//lyxerr << "Leaving inset to the right" << endl; //lyxerr << "Leaving inset to the right" << endl;
if (depth() <= 1) { if (depth() <= 1) {
if (depth() == 1) if (depth() == 1)
@ -216,28 +226,11 @@ bool LCursor::popRight()
} }
CursorSlice & LCursor::current()
{
BOOST_ASSERT(!cursor_.empty());
//lyxerr << "accessing cursor slice " << current_
// << ": " << cursor_[current_] << endl;
return cursor_[current_];
}
CursorSlice const & LCursor::current() const
{
//lyxerr << "accessing cursor slice " << current_
// << ": " << cursor_[current_] << endl;
return cursor_[current_];
}
int LCursor::currentMode() int LCursor::currentMode()
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
for (int i = cursor_.size() - 1; i >= 1; --i) { for (int i = size() - 1; i >= 1; --i) {
int res = cursor_[i].inset()->currentMode(); int res = operator[](i).inset()->currentMode();
if (res != MathInset::UNDECIDED_MODE) if (res != MathInset::UNDECIDED_MODE)
return res; return res;
} }
@ -245,46 +238,18 @@ int LCursor::currentMode()
} }
LyXText * LCursor::innerText() const
{
BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1) {
// go up until first non-0 text is hit
// (innermost text is 0 in mathed)
for (int i = cursor_.size() - 1; i >= 1; --i)
if (cursor_[i].text())
return cursor_[i].text();
}
return bv_->text();
}
CursorSlice const & LCursor::innerTextSlice() const
{
BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1) {
// go up until first non-0 text is hit
// (innermost text is 0 in mathed)
for (int i = cursor_.size() - 1; i >= 1; --i)
if (cursor_[i].text())
return cursor_[i];
}
return cursor_[0];
}
void LCursor::updatePos() void LCursor::updatePos()
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
if (cursor_.size() > 1) if (size() > 1)
cached_y_ = bv_->top_y() + cursor_.back().inset()->yo(); cached_y_ = bv().top_y() + back().inset()->yo();
//cached_y_ = cursor_.back().inset()->yo(); //cached_y_ = back().inset()->yo();
} }
void LCursor::getDim(int & asc, int & des) const void LCursor::getDim(int & asc, int & des) const
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
if (inMathed()) { if (inMathed()) {
BOOST_ASSERT(inset()); BOOST_ASSERT(inset());
BOOST_ASSERT(inset()->asMathInset()); BOOST_ASSERT(inset()->asMathInset());
@ -301,18 +266,18 @@ void LCursor::getDim(int & asc, int & des) const
void LCursor::getPos(int & x, int & y) const void LCursor::getPos(int & x, int & y) const
{ {
BOOST_ASSERT(!cursor_.empty()); BOOST_ASSERT(!empty());
x = 0; x = 0;
y = 0; y = 0;
if (cursor_.size() == 1) { if (size() == 1) {
x = bv_->text()->cursorX(cursor_.front()); x = bv().text()->cursorX(front());
y = bv_->text()->cursorY(cursor_.front()); y = bv().text()->cursorY(front());
} else { } else {
if (!inset()) { if (!inset()) {
lyxerr << "#### LCursor::getPos: " << *this << endl; lyxerr << "#### LCursor::getPos: " << *this << endl;
BOOST_ASSERT(inset()); BOOST_ASSERT(inset());
} }
inset()->getCursorPos(cursor_.back(), x, y); inset()->getCursorPos(back(), x, y);
// getCursorPos gives _screen_ coordinates. We need to add // getCursorPos gives _screen_ coordinates. We need to add
// top_y to get document coordinates. This is hidden in cached_y_. // top_y to get document coordinates. This is hidden in cached_y_.
//y += cached_y_ - inset()->yo(); //y += cached_y_ - inset()->yo();
@ -335,60 +300,12 @@ void LCursor::paste(string const & data)
} }
InsetBase * LCursor::innerInsetOfType(int code) const
{
for (int i = cursor_.size() - 1; i >= 1; --i)
if (cursor_[i].inset_->lyxCode() == code)
return cursor_[i].inset_;
return 0;
}
InsetTabular * LCursor::innerInsetTabular() const
{
return static_cast<InsetTabular *>(innerInsetOfType(InsetBase::TABULAR_CODE));
}
void LCursor::resetAnchor() void LCursor::resetAnchor()
{ {
anchor_ = cursor_; anchor_ = *this;
} }
BufferView & LCursor::bv() const
{
return *bv_;
}
MathAtom const & LCursor::prevAtom() const
{
BOOST_ASSERT(pos() > 0);
return cell()[pos() - 1];
}
MathAtom & LCursor::prevAtom()
{
BOOST_ASSERT(pos() > 0);
return cell()[pos() - 1];
}
MathAtom const & LCursor::nextAtom() const
{
BOOST_ASSERT(pos() < lastpos());
return cell()[pos()];
}
MathAtom & LCursor::nextAtom()
{
BOOST_ASSERT(pos() < lastpos());
return cell()[pos()];
}
bool LCursor::posLeft() bool LCursor::posLeft()
{ {
@ -423,34 +340,34 @@ CursorSlice const & LCursor::anchor() const
CursorSlice const & LCursor::selBegin() const CursorSlice const & LCursor::selBegin() const
{ {
if (!selection()) if (!selection())
return cursor_.back(); return back();
return anchor() < cursor_.back() ? anchor() : cursor_.back(); return anchor() < back() ? anchor() : back();
} }
CursorSlice & LCursor::selBegin() CursorSlice & LCursor::selBegin()
{ {
if (!selection()) if (!selection())
return cursor_.back(); return back();
// can't use std::min as this returns a const ref // can't use std::min as this returns a const ref
return anchor() < cursor_.back() ? anchor() : cursor_.back(); return anchor() < back() ? anchor() : back();
} }
CursorSlice const & LCursor::selEnd() const CursorSlice const & LCursor::selEnd() const
{ {
if (!selection()) if (!selection())
return cursor_.back(); return back();
return anchor() > cursor_.back() ? anchor() : cursor_.back(); return anchor() > back() ? anchor() : back();
} }
CursorSlice & LCursor::selEnd() CursorSlice & LCursor::selEnd()
{ {
if (!selection()) if (!selection())
return cursor_.back(); return back();
// can't use std::min as this returns a const ref // can't use std::min as this returns a const ref
return anchor() > cursor_.back() ? anchor() : cursor_.back(); return anchor() > back() ? anchor() : back();
} }
@ -463,10 +380,10 @@ void LCursor::setSelection()
} }
void LCursor::setSelection(CursorBase const & where, size_t n) void LCursor::setSelection(DocumentIterator const & where, size_t n)
{ {
selection() = true; selection() = true;
cursor_ = where; setCursor(where, false);
anchor_ = where; anchor_ = where;
pos() += n; pos() += n;
} }
@ -499,122 +416,11 @@ void LCursor::clearTargetX()
} }
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
{
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();
}
LCursor::idx_type LCursor::lastidx() const
{
return current_ ? current().lastidx() : 0;
}
size_t LCursor::nargs() const
{
// assume 1x1 grid for 'plain text'
return current_ ? current().nargs() : 1;
}
size_t LCursor::ncols() const
{
// assume 1x1 grid for 'plain text'
return current_ ? current().ncols() : 1;
}
size_t LCursor::nrows() const
{
// assume 1x1 grid for 'plain text'
return current_ ? current().nrows() : 1;
}
LCursor::row_type LCursor::row() const
{
BOOST_ASSERT(current_ > 0);
return current().row();
}
LCursor::col_type LCursor::col() const
{
BOOST_ASSERT(current_ > 0);
return current().col();
}
MathArray const & LCursor::cell() const
{
BOOST_ASSERT(current_ > 0);
return current().cell();
}
MathArray & LCursor::cell()
{
BOOST_ASSERT(current_ > 0);
return current().cell();
}
void LCursor::info(std::ostream & os) const void LCursor::info(std::ostream & os) const
{ {
for (int i = 1, n = depth(); i < n; ++i) { for (int i = 1, n = depth(); i < n; ++i) {
cursor_[i].inset()->infoize(os); operator[](i).inset()->infoize(os);
os << " "; os << " ";
} }
if (pos() != 0) if (pos() != 0)
@ -701,7 +507,7 @@ void LCursor::eraseSelection()
for (col_type col = c1; col <= c2; ++col) for (col_type col = c1; col <= c2; ++col)
p->cell(p->index(row, col)).clear(); p->cell(p->index(row, col)).clear();
} }
current() = i1; back() = i1;
} else { } else {
lyxerr << "can't erase this selection 1" << endl; lyxerr << "can't erase this selection 1" << endl;
} }
@ -786,9 +592,8 @@ void LCursor::selClearOrDel()
std::ostream & operator<<(std::ostream & os, LCursor const & cur) std::ostream & operator<<(std::ostream & os, LCursor const & cur)
{ {
for (size_t i = 0, n = cur.cursor_.size(); i != n; ++i) for (size_t i = 0, n = cur.size(); i != n; ++i)
os << " " << cur.cursor_[i] << " | " << cur.anchor_[i] << "\n"; os << " " << cur.operator[](i) << " | " << cur.anchor_[i] << "\n";
os << " current: " << cur.current_ << endl;
os << " selection: " << cur.selection_ << endl; os << " selection: " << cur.selection_ << endl;
return os; return os;
} }
@ -796,89 +601,21 @@ std::ostream & operator<<(std::ostream & os, LCursor const & cur)
//
// CursorBase
//
void increment(CursorBase & it)
{
CursorSlice & top = it.back();
MathArray & ar = top.asMathInset()->cell(top.idx_);
// move into the current inset if possible
// it is impossible for pos() == size()!
MathInset * n = 0;
if (top.pos() != top.lastpos())
n = (ar.begin() + top.pos_)->nucleus();
if (n && n->isActive()) {
it.push_back(CursorSlice(n));
return;
}
// otherwise move on one cell back if possible
if (top.pos() < top.lastpos()) {
// pos() == lastpos() is valid!
++top.pos_;
return;
}
// otherwise try to move on one cell if possible
while (top.idx() < top.lastidx()) {
++top.idx_;
if (top.asMathInset()->validCell(top.idx_)) {
top.pos_ = 0;
return;
}
}
// otherwise leave array, move on one back
// this might yield pos() == size(), but that's a ok.
it.pop_back();
// it certainly invalidates top
++it.back().pos_;
}
CursorBase ibegin(InsetBase * p)
{
CursorBase it;
it.push_back(CursorSlice(p));
return it;
}
CursorBase iend(InsetBase * p)
{
CursorBase it;
it.push_back(CursorSlice(p));
CursorSlice & cur = it.back();
cur.idx() = cur.lastidx();
cur.pos() = cur.lastpos();
return it;
}
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// //
// The part below is the non-integrated rest of the original math // The part below is the non-integrated rest of the original math
// cursor. This should be either generalized for texted or moved // cursor. This should be either generalized for texted or moved
// back to the math insets. // back to mathed (in most cases to MathNestInset).
// //
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
#include "mathed/math_braceinset.h"
#include "mathed/math_charinset.h" #include "mathed/math_charinset.h"
#include "mathed/math_commentinset.h"
#include "mathed/math_factory.h" #include "mathed/math_factory.h"
#include "mathed/math_gridinset.h" #include "mathed/math_gridinset.h"
#include "mathed/math_macroarg.h" #include "mathed/math_macroarg.h"
#include "mathed/math_macrotemplate.h" #include "mathed/math_macrotemplate.h"
#include "mathed/math_mathmlstream.h" #include "mathed/math_mathmlstream.h"
#include "mathed/math_scriptinset.h" #include "mathed/math_scriptinset.h"
#include "mathed/math_spaceinset.h"
#include "mathed/math_support.h" #include "mathed/math_support.h"
#include "mathed/math_unknowninset.h" #include "mathed/math_unknowninset.h"
@ -888,7 +625,7 @@ CursorBase iend(InsetBase * p)
bool LCursor::isInside(InsetBase const * p) bool LCursor::isInside(InsetBase const * p)
{ {
for (unsigned i = 0; i < depth(); ++i) for (unsigned i = 0; i < depth(); ++i)
if (cursor_[i].inset() == p) if (operator[](i).inset() == p)
return true; return true;
return false; return false;
} }
@ -915,7 +652,8 @@ bool LCursor::openable(MathAtom const & t) const
} }
bool positionable(CursorBase const & cursor, CursorBase const & anchor) bool positionable(DocumentIterator const & cursor,
DocumentIterator const & anchor)
{ {
// avoid deeper nested insets when selecting // avoid deeper nested insets when selecting
if (cursor.size() > anchor.size()) if (cursor.size() > anchor.size())
@ -1127,10 +865,10 @@ bool LCursor::erase()
bool LCursor::up() bool LCursor::up()
{ {
macroModeClose(); macroModeClose();
CursorBase save = cursor_; DocumentIterator save = *this;
if (goUpDown(true)) if (goUpDown(true))
return true; return true;
cursor_ = save; setCursor(save, false);
autocorrect() = false; autocorrect() = false;
return selection(); return selection();
} }
@ -1139,10 +877,10 @@ bool LCursor::up()
bool LCursor::down() bool LCursor::down()
{ {
macroModeClose(); macroModeClose();
CursorBase save = cursor_; DocumentIterator save = *this;
if (goUpDown(false)) if (goUpDown(false))
return true; return true;
cursor_ = save; setCursor(save, false);
autocorrect() = false; autocorrect() = false;
return selection(); return selection();
} }
@ -1203,8 +941,8 @@ int LCursor::targetX() const
MathHullInset * LCursor::formula() const MathHullInset * LCursor::formula() const
{ {
for (int i = cursor_.size() - 1; i >= 1; --i) { for (int i = size() - 1; i >= 1; --i) {
MathInset * inset = cursor_[i].inset()->asMathInset(); MathInset * inset = operator[](i).inset()->asMathInset();
if (inset && inset->asHullInset()) if (inset && inset->asHullInset())
return static_cast<MathHullInset *>(inset); return static_cast<MathHullInset *>(inset);
} }
@ -1248,12 +986,12 @@ bool LCursor::inMacroArgMode() const
MathGridInset * LCursor::enclosingGrid(idx_type & idx) const MathGridInset * LCursor::enclosingGrid(idx_type & idx) const
{ {
for (MathInset::difference_type i = depth() - 1; i >= 0; --i) { for (MathInset::difference_type i = depth() - 1; i >= 0; --i) {
MathInset * m = cursor_[i].inset()->asMathInset(); MathInset * m = operator[](i).inset()->asMathInset();
if (!m) if (!m)
return 0; return 0;
MathGridInset * p = m->asGridInset(); MathGridInset * p = m->asGridInset();
if (p) { if (p) {
idx = cursor_[i].idx_; idx = operator[](i).idx_;
return p; return p;
} }
} }
@ -1279,8 +1017,8 @@ void LCursor::touch()
{ {
#warning look here #warning look here
#if 0 #if 0
CursorBase::const_iterator it = cursor_.begin(); DocumentIterator::const_iterator it = begin();
CursorBase::const_iterator et = cursor_.end(); DocumentIterator::const_iterator et = end();
for ( ; it != et; ++it) for ( ; it != et; ++it)
it->cell().touch(); it->cell().touch();
#endif #endif
@ -1416,11 +1154,11 @@ bool LCursor::goUpDown(bool up)
bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh)
{ {
CursorBase best_cursor; DocumentIterator best_cursor(bv());
double best_dist = 1e10; double best_dist = 1e10;
CursorBase it = ibegin(formula()); DocumentIterator it = bufferBegin(bv());
CursorBase et = iend(formula()); DocumentIterator et = bufferEnd();
while (1) { while (1) {
// avoid invalid nesting when selecting // avoid invalid nesting when selecting
if (!selection() || positionable(it, anchor_)) { if (!selection() || positionable(it, anchor_)) {
@ -1441,11 +1179,11 @@ bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh)
if (it == et) if (it == et)
break; break;
increment(it); it.forwardPos();
} }
if (best_dist < 1e10) if (best_dist < 1e10)
cursor_ = best_cursor; setCursor(best_cursor, false);
return best_dist < 1e10; return best_dist < 1e10;
} }
@ -1454,9 +1192,9 @@ void LCursor::bruteFind2(int x, int y)
{ {
double best_dist = 1e10; double best_dist = 1e10;
CursorBase it = cursor_; DocumentIterator it = *this;
it.back().pos() = 0; it.back().pos() = 0;
CursorBase et = cursor_; DocumentIterator et = *this;
et.back().pos() = et.back().asMathInset()->cell(et.back().idx_).size(); et.back().pos() = et.back().asMathInset()->cell(et.back().idx_).size();
for (int i = 0; ; ++i) { for (int i = 0; ; ++i) {
int xo, yo; int xo, yo;
@ -1468,24 +1206,11 @@ void LCursor::bruteFind2(int x, int y)
lyxerr << "i: " << i << " d: " << d << " best: " << best_dist << endl; lyxerr << "i: " << i << " d: " << d << " best: " << best_dist << endl;
if (d <= best_dist) { if (d <= best_dist) {
best_dist = d; best_dist = d;
cursor_ = it; setCursor(it, false);
} }
if (it == et) if (it == et)
break; break;
increment(it); it.forwardPos();
}
}
void LCursor::lockToggle()
{
if (pos() != lastpos()) {
// toggle previous inset ...
nextAtom().nucleus()->lock(!nextAtom()->lock());
} else if (popLeft() && pos() != lastpos()) {
// ... or enclosing inset if we are in the last inset position
nextAtom().nucleus()->lock(!nextAtom()->lock());
++pos();
} }
} }
@ -1498,7 +1223,7 @@ CursorSlice LCursor::normalAnchor()
} }
//lyx::BOOST_ASSERT(Anchor_.size() >= cursor.depth()); //lyx::BOOST_ASSERT(Anchor_.size() >= cursor.depth());
// use Anchor on the same level as Cursor // use Anchor on the same level as Cursor
CursorSlice normal = anchor_[current_]; CursorSlice normal = anchor_[size() - 1];
#if 0 #if 0
if (depth() < anchor_.size() && !(normal < xx())) { if (depth() < anchor_.size() && !(normal < xx())) {
// anchor is behind cursor -> move anchor behind the inset // anchor is behind cursor -> move anchor behind the inset
@ -1519,7 +1244,7 @@ DispatchResult dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_MOUSE_MOTION: case LFUN_MOUSE_MOTION:
case LFUN_MOUSE_RELEASE: case LFUN_MOUSE_RELEASE:
case LFUN_MOUSE_DOUBLE: { case LFUN_MOUSE_DOUBLE: {
CursorSlice & pos = cursor_.back(); CursorSlice & pos = back();
int x = 0; int x = 0;
int y = 0; int y = 0;
getPos(x, y); getPos(x, y);
@ -1576,48 +1301,6 @@ void LCursor::handleFont(string const & font)
} }
bool LCursor::inMathed() const
{
return current_ && inset()->inMathed();
}
bool LCursor::inTexted() const
{
return !inMathed();
}
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 void LCursor::message(string const & msg) const
{ {
bv().owner()->getLyXFunc().setMessage(msg); bv().owner()->getLyXFunc().setMessage(msg);
@ -1705,7 +1388,7 @@ string LCursor::getPossibleLabel()
} }
void LCursor::notdispatched() void LCursor::undispatched()
{ {
disp_.dispatched(false); disp_.dispatched(false);
} }
@ -1717,7 +1400,13 @@ void LCursor::dispatched(dispatch_result_t res)
} }
void LCursor::noupdate() void LCursor::noUpdate()
{ {
disp_.update(false); disp_.update(false);
} }
void LCursor::noPop()
{
nopop_ = true;
}

View File

@ -12,23 +12,17 @@
#ifndef CURSOR_H #ifndef CURSOR_H
#define CURSOR_H #define CURSOR_H
#include "cursor_slice.h"
#include "dispatchresult.h" #include "dispatchresult.h"
#include "dociterator.h"
#include <iosfwd> #include <iosfwd>
#include <vector> #include <vector>
class BufferView;
class UpdatableInset; class UpdatableInset;
class MathAtom;
class DispatchResult; class DispatchResult;
class FuncStatus; class FuncStatus;
class FuncRequest; class FuncRequest;
class InsetTabular; class InsetTabular;
class LyXText;
class Paragraph;
class Row;
// these should go // these should go
class MathHullInset; class MathHullInset;
@ -36,40 +30,14 @@ class MathUnknownInset;
class MathGridInset; class MathGridInset;
// only needed for gcc 2.95, remove when support terminated
template <typename A, typename B>
bool ptr_cmp(A const * a, B const * b)
{
return a == b;
}
// this is used for traversing math insets
typedef std::vector<CursorSlice> CursorBase;
/// move on one step
void increment(CursorBase &);
///
CursorBase ibegin(InsetBase * p);
///
CursorBase iend(InsetBase * p);
/** /**
* The cursor class describes the position of a cursor within a document. * The cursor class describes the position of a cursor within a document.
*/ */
class LCursor { // The public inheritance should go in favour of a suitable data member
// (or maybe private inheritance) at some point of time.
class LCursor : public DocumentIterator {
public: public:
/// type for cell number in inset
typedef CursorSlice::idx_type idx_type;
/// type for paragraph numbers positions within a cell
typedef CursorSlice::par_type par_type;
/// type for cursor positions within a cell
typedef CursorSlice::pos_type pos_type;
/// type for row indices
typedef CursorSlice::row_type row_type;
/// type for col indices
typedef CursorSlice::col_type col_type;
/// create the cursor of a BufferView /// create the cursor of a BufferView
explicit LCursor(BufferView & bv); explicit LCursor(BufferView & bv);
@ -88,16 +56,8 @@ public:
bool popLeft(); bool popLeft();
/// pop one slice off the cursor stack and go right /// pop one slice off the cursor stack and go right
bool popRight(); bool popRight();
/// restrict cursor nesting to given size /// sets cursor part
void pop(int depth); void setCursor(DocumentIterator const & it, bool sel);
/// access to current cursor slice
CursorSlice & current();
/// access to current cursor slice
CursorSlice const & current() const;
/// how many nested insets do we have?
size_t depth() const { return cursor_.size(); }
/// depth of current slice
int currentDepth() const { return current_; }
// //
// selection // selection
@ -113,7 +73,7 @@ public:
/// ///
void setSelection(); void setSelection();
/// set selection at given position /// set selection at given position
void setSelection(CursorBase const & where, size_t n); void setSelection(DocumentIterator const & where, size_t n);
/// ///
void clearSelection(); void clearSelection();
/// access start of selection /// access start of selection
@ -154,70 +114,6 @@ public:
/// ///
std::string currentState(); std::string currentState();
//
// access to the 'current' cursor slice
//
/// the containing inset
InsetBase * inset() const { return current().inset(); }
/// return the cell of the inset this cursor is in
idx_type idx() const { return current().idx(); }
/// return the cell of the inset this cursor is in
idx_type & idx() { return current().idx(); }
/// return the last possible cell in this inset
idx_type lastidx() const;
/// return the paragraph this cursor is in
par_type par() const { return current().par(); }
/// return the paragraph this cursor is in
par_type & par() { return current().par(); }
/// return the last possible paragraph in this inset
par_type lastpar() const;
/// return the position within the paragraph
pos_type pos() const { return current().pos(); }
/// return the position within the paragraph
pos_type & pos() { return current().pos(); }
/// return the last position within the paragraph
pos_type lastpos() const;
/// return the display row of the cursor with in the current par
row_type crow() const;
/// return the display row of the cursor with in the current par
row_type lastcrow() const;
/// return the number of embedded cells
size_t nargs() const;
/// return the number of embedded cells
size_t ncols() const;
/// return the number of embedded cells
size_t nrows() const;
/// return the grid row of the current cell
row_type row() const;
/// return the last row of the current grid
row_type lastrow() const { return nrows() - 1; }
/// return the grid column of the current cell
col_type col() const;
/// return the last column of the current grid
col_type lastcol() const { return ncols() - 1; }
/// the inset just behind the cursor
InsetBase * nextInset();
/// the inset just in front of the cursor
InsetBase * prevInset();
/// the inset just in front of the cursor
InsetBase const * prevInset() const;
//
// math-specific part
//
/// return the mathed cell this cursor is in
MathArray const & cell() const;
/// return the mathed cell this cursor is in
MathArray & cell();
/// the mathatom left of the cursor
MathAtom const & prevAtom() const;
/// the mathatom left of the cursor
MathAtom & prevAtom();
/// the mathatom right of the cursor
MathAtom const & nextAtom() const;
/// the mathatom right of the cursor
MathAtom & nextAtom();
/// auto-correct mode /// auto-correct mode
bool autocorrect() const { return autocorrect_; } bool autocorrect() const { return autocorrect_; }
/// auto-correct mode /// auto-correct mode
@ -226,31 +122,6 @@ public:
bool macromode() const { return macromode_; } bool macromode() const { return macromode_; }
/// are we entering a macro name? /// are we entering a macro name?
bool & macromode() { return macromode_; } bool & macromode() { return macromode_; }
//
// text-specific part
/// see comment for boundary_ below
bool boundary() const { return current().boundary(); }
/// see comment for boundary_ below
bool & boundary() { return current().boundary(); }
/// the paragraph we're in
Paragraph & paragraph();
/// the paragraph we're in
Paragraph const & paragraph() const;
/// the row in the paragraph we're in
Row & textRow();
/// the row in the paragraph we're in
Row const & textRow() const;
///
LyXText * text() const;
///
InsetBase * innerInsetOfType(int code) const;
///
InsetTabular * innerInsetTabular() const;
///
LyXText * innerText() const;
///
CursorSlice const & innerTextSlice() const;
/// returns x,y position /// returns x,y position
void getPos(int & x, int & y) const; void getPos(int & x, int & y) const;
/// returns cursor dimension /// returns cursor dimension
@ -288,7 +159,7 @@ public:
void resetAnchor(); void resetAnchor();
/// access to owning BufferView /// access to owning BufferView
BufferView & bv() const; BufferView & bv() const;
/// get some interesting description of current position /// get some interesting description of top position
void info(std::ostream & os) const; void info(std::ostream & os) const;
/// are we in math mode (2), text mode (1) or unsure (0)? /// are we in math mode (2), text mode (1) or unsure (0)?
int currentMode(); int currentMode();
@ -298,28 +169,26 @@ public:
void replaceWord(std::string const & replacestring); void replaceWord(std::string const & replacestring);
/// update our view /// update our view
void update(); void update();
/// /// set dispatch result
void dispatched(dispatch_result_t res); void dispatched(dispatch_result_t res);
void notdispatched(); /// assume event was not (yet) dispatched
void noupdate(); void undispatched();
/// don't call update() when done
void noUpdate();
/// don't pop cursor to the level where the LFUN was handled
void noPop();
/// output /// output
friend std::ostream & operator<<(std::ostream & os, LCursor const & cur); friend std::ostream & operator<<(std::ostream & os, LCursor const & cur);
public: public:
//private: //private:
/// mainly used as stack, but wee need random access
std::vector<CursorSlice> cursor_;
/// the anchor position /// the anchor position
std::vector<CursorSlice> anchor_; DocumentIterator anchor_;
/// ///
DispatchResult disp_; DispatchResult disp_;
private: private:
///
BufferView * bv_;
/// current slice
int current_;
/// ///
int cached_y_; int cached_y_;
/** /**
@ -339,6 +208,8 @@ private:
bool selection_; bool selection_;
// are we on the way to get one? // are we on the way to get one?
bool mark_; bool mark_;
///
bool nopop_;
// //
// math specific stuff that could be promoted to "global" later // math specific stuff that could be promoted to "global" later
@ -389,7 +260,7 @@ public:
void adjust(pos_type from, int diff); void adjust(pos_type from, int diff);
/// ///
MathHullInset * formula() const; MathHullInset * formula() const;
/// current offset in the current cell /// current offset in the top cell
/// interpret name a name of a macro /// interpret name a name of a macro
void macroModeClose(); void macroModeClose();
/// are we currently typing the name of a macro? /// are we currently typing the name of a macro?
@ -419,9 +290,6 @@ public:
/// returns the normalized anchor of the selection /// returns the normalized anchor of the selection
CursorSlice normalAnchor(); CursorSlice normalAnchor();
/// lock/unlock inset
void lockToggle();
/// hack for reveal codes /// hack for reveal codes
void markInsert(); void markInsert();
void markErase(); void markErase();
@ -430,11 +298,6 @@ public:
/// split font inset etc /// split font inset etc
void handleFont(std::string const & font); void handleFont(std::string const & font);
/// are we in mathed?
bool inMathed() const;
/// are we in texted?
bool inTexted() const;
/// display a message /// display a message
void message(std::string const & msg) const; void message(std::string const & msg) const;
/// display an error message /// display an error message

View File

@ -213,7 +213,7 @@ bool operator>(CursorSlice const & p, CursorSlice const & q)
std::ostream & operator<<(std::ostream & os, CursorSlice const & item) std::ostream & operator<<(std::ostream & os, CursorSlice const & item)
{ {
os os
// << "inset: " << item.inset_ << "inset: " << item.inset_
// << " text: " << item.text() // << " text: " << item.text()
<< " idx: " << item.idx_ << " idx: " << item.idx_
<< " par: " << item.par_ << " par: " << item.par_

401
src/dociterator.C Normal file
View File

@ -0,0 +1,401 @@
#include "dociterator.h"
#include "BufferView.h"
#include "debug.h"
#include "lyxtext.h"
#include "lyxrow.h"
#include "paragraph.h"
#include "mathed/math_data.h"
#include "mathed/math_inset.h"
#include <boost/assert.hpp>
std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur);
DocumentIterator::DocumentIterator()
: bv_(0)
{}
DocumentIterator::DocumentIterator(BufferView & bv)
: std::vector<CursorSlice>(1), bv_(&bv)
{}
InsetBase * DocumentIterator::nextInset()
{
if (pos() == lastpos())
return 0;
if (inMathed())
return nextAtom().nucleus();
return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
}
InsetBase * DocumentIterator::prevInset()
{
if (pos() == 0)
return 0;
if (inMathed())
return prevAtom().nucleus();
return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
}
InsetBase const * DocumentIterator::prevInset() const
{
if (pos() == 0)
return 0;
if (inMathed())
return prevAtom().nucleus();
return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
}
MathAtom const & DocumentIterator::prevAtom() const
{
BOOST_ASSERT(pos() > 0);
return cell()[pos() - 1];
}
MathAtom & DocumentIterator::prevAtom()
{
BOOST_ASSERT(pos() > 0);
return cell()[pos() - 1];
}
MathAtom const & DocumentIterator::nextAtom() const
{
BOOST_ASSERT(pos() < lastpos());
return cell()[pos()];
}
MathAtom & DocumentIterator::nextAtom()
{
BOOST_ASSERT(pos() < lastpos());
return cell()[pos()];
}
LyXText * DocumentIterator::text() const
{
return size() > 1 ? top().text() : bv().text();
}
Paragraph & DocumentIterator::paragraph()
{
BOOST_ASSERT(inTexted());
return size() > 1 ? top().paragraph() : *bv().text()->getPar(par());
}
Paragraph const & DocumentIterator::paragraph() const
{
BOOST_ASSERT(inTexted());
return size() > 1 ? top().paragraph() : *bv().text()->getPar(par());
}
Row & DocumentIterator::textRow()
{
return *paragraph().getRow(pos());
}
Row const & DocumentIterator::textRow() const
{
return *paragraph().getRow(pos());
}
DocumentIterator::par_type DocumentIterator::lastpar() const
{
return inMathed() ? 0 : text()->paragraphs().size() - 1;
}
DocumentIterator::pos_type DocumentIterator::lastpos() const
{
return inMathed() ? cell().size() : paragraph().size();
}
DocumentIterator::row_type DocumentIterator::crow() const
{
return paragraph().row(pos());
}
DocumentIterator::row_type DocumentIterator::lastcrow() const
{
return paragraph().rows.size();
}
DocumentIterator::idx_type DocumentIterator::lastidx() const
{
return size() > 1 ? top().lastidx() : 0;
}
size_t DocumentIterator::nargs() const
{
// assume 1x1 grid for main text
return size() > 1 ? top().nargs() : 1;
}
size_t DocumentIterator::ncols() const
{
// assume 1x1 grid for main text
return size() > 1 ? top().ncols() : 1;
}
size_t DocumentIterator::nrows() const
{
// assume 1x1 grid for main text
return size() > 1 ? top().nrows() : 1;
}
DocumentIterator::row_type DocumentIterator::row() const
{
return size() > 1 ? top().row() : 0;
}
DocumentIterator::col_type DocumentIterator::col() const
{
return size() > 1 ? top().col() : 0;
}
MathArray const & DocumentIterator::cell() const
{
BOOST_ASSERT(size() > 1);
return top().cell();
}
MathArray & DocumentIterator::cell()
{
BOOST_ASSERT(size() > 1);
return top().cell();
}
bool DocumentIterator::inMathed() const
{
return size() > 1 && inset()->inMathed();
}
bool DocumentIterator::inTexted() const
{
return !inMathed();
}
LyXText * DocumentIterator::innerText() const
{
BOOST_ASSERT(!empty());
if (size() > 1) {
// go up until first non-0 text is hit
// (innermost text is 0 in mathed)
for (int i = size() - 1; i >= 1; --i)
if (operator[](i).text())
return operator[](i).text();
}
return bv().text();
}
CursorSlice const & DocumentIterator::innerTextSlice() const
{
BOOST_ASSERT(!empty());
if (size() > 1) {
// go up until first non-0 text is hit
// (innermost text is 0 in mathed)
for (int i = size() - 1; i >= 1; --i)
if (operator[](i).text())
return operator[](i);
}
return operator[](0);
}
InsetBase * DocumentIterator::innerInsetOfType(int code) const
{
for (int i = size() - 1; i >= 1; --i)
if (operator[](i).inset_->lyxCode() == code)
return operator[](i).inset_;
return 0;
}
void DocumentIterator::forwardPos()
{
CursorSlice & top = back();
//lyxerr << "XXX\n" << *this << std::endl;
// move into an inset to the right if possible
InsetBase * n = 0;
if (top.pos() != lastpos()) {
// this is impossible for pos() == size()
if (inMathed()) {
n = (top.cell().begin() + top.pos())->nucleus();
} else {
if (paragraph().isInset(top.pos()))
n = paragraph().getInset(top.pos());
}
}
if (n && n->isActive()) {
//lyxerr << "... descend" << std::endl;
push_back(CursorSlice(n));
return;
}
// otherwise move on one cell back if possible
if (top.pos() < lastpos()) {
//lyxerr << "... next pos" << std::endl;
++top.pos();
return;
}
//lyxerr << "... no next pos" << std::endl;
// otherwise move on one cell back if possible
if (top.par() < lastpar()) {
//lyxerr << "... next par" << std::endl;
++top.par();
top.pos() = 0;
return;
}
//lyxerr << "... no next par" << std::endl;
// otherwise try to move on one cell if possible
// [stupid hack for necessary for MathScriptInset]
while (top.idx() < lastidx()) {
//lyxerr << "... next idx" << std::endl;
++top.idx();
top.par() = 0;
top.pos() = 0;
if (top.inset() && top.inset()->validCell(top.idx())) {
//lyxerr << " ... ok" << std::endl;
return;
}
}
//lyxerr << "... no next idx" << std::endl;
// otherwise leave inset an jump over inset as a whole
pop_back();
// 'top' is invalid now...
if (size())
++back().pos_;
//else
// lyxerr << "... no slice left" << std::endl;
}
void DocumentIterator::forwardPar()
{
CursorSlice & top = back();
lyxerr << "XXX " << *this << std::endl;
// move into an inset to the right if possible
InsetBase * n = 0;
if (top.pos() != lastpos()) {
// this is impossible for pos() == size()
if (inMathed()) {
n = (top.cell().begin() + top.pos())->nucleus();
} else {
if (paragraph().isInset(top.pos()))
n = paragraph().getInset(top.pos());
}
}
if (n && n->isActive()) {
lyxerr << "... descend" << std::endl;
push_back(CursorSlice(n));
return;
}
// otherwise move on one cell back if possible
if (top.pos() < lastpos()) {
lyxerr << "... next pos" << std::endl;
++top.pos();
return;
}
// otherwise move on one cell back if possible
if (top.par() < lastpar()) {
lyxerr << "... next par" << std::endl;
++top.par();
top.pos() = 0;
return;
}
// otherwise try to move on one cell if possible
// [stupid hack for necessary for MathScriptInset]
while (top.idx() < top.lastidx()) {
lyxerr << "... next idx"
<< " was: " << top.idx() << " max: " << top.lastidx() << std::endl;
++top.idx();
top.par() = 0;
top.pos() = 0;
if (top.inset() && top.inset()->validCell(top.idx())) {
lyxerr << " ... ok" << std::endl;
return;
}
}
// otherwise leave inset an jump over inset as a whole
pop_back();
// 'top' is invalid now...
if (size())
++back().pos_;
}
DocumentIterator bufferBegin(BufferView & bv)
{
return DocumentIterator(bv);
}
DocumentIterator bufferEnd()
{
return DocumentIterator();
}
DocumentIterator insetBegin(BufferView & bv, InsetBase * p)
{
DocumentIterator it(bv);
it.back() = CursorSlice(p);
return it;
}
DocumentIterator insetEnd()
{
return DocumentIterator();
}
std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur)
{
for (size_t i = 0, n = cur.size(); i != n; ++i)
os << " " << cur.operator[](i) << "\n";
return os;
}

185
src/dociterator.h Normal file
View File

@ -0,0 +1,185 @@
// -*- C++ -*-
/**
* \file dociterator.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author André Pönitz
*
* Full author contact details are available in file CREDITS.
*/
#ifndef DOCITERATOR_H
#define DOCITERATOR_H
#include "cursor_slice.h"
#include <vector>
class BufferView;
class MathAtom;
class LyXText;
class Paragraph;
class Row;
// only needed for gcc 2.95, remove when support terminated
template <typename A, typename B>
bool ptr_cmp(A const * a, B const * b)
{
return a == b;
}
// The public inheritance should go in favour of a suitable data member
// (or maybe private inheritance) at some point of time.
class DocumentIterator : public std::vector<CursorSlice>
{
public:
/// type for cell number in inset
typedef CursorSlice::idx_type idx_type;
/// type for paragraph numbers positions within a cell
typedef CursorSlice::par_type par_type;
/// type for cursor positions within a cell
typedef CursorSlice::pos_type pos_type;
/// type for row indices
typedef CursorSlice::row_type row_type;
/// type for col indices
typedef CursorSlice::col_type col_type;
public:
///
DocumentIterator();
///
explicit DocumentIterator(BufferView & bv);
///
BufferView & bv() const { return *bv_; }
//
// access to slice at tip
//
/// access to tip
CursorSlice & top() { return back(); }
/// access to tip
CursorSlice const & top() const { return back(); }
/// how many nested insets do we have?
size_t depth() const { return size(); }
/// the containing inset
InsetBase * inset() const { return back().inset(); }
/// return the cell of the inset this cursor is in
idx_type idx() const { return back().idx(); }
/// return the cell of the inset this cursor is in
idx_type & idx() { return back().idx(); }
/// return the last possible cell in this inset
idx_type lastidx() const;
/// return the paragraph this cursor is in
par_type par() const { return back().par(); }
/// return the paragraph this cursor is in
par_type & par() { return back().par(); }
/// return the last possible paragraph in this inset
par_type lastpar() const;
/// return the position within the paragraph
pos_type pos() const { return back().pos(); }
/// return the position within the paragraph
pos_type & pos() { return back().pos(); }
/// return the last position within the paragraph
pos_type lastpos() const;
/// return the display row of the cursor with in the top par
row_type crow() const;
/// return the display row of the cursor with in the top par
row_type lastcrow() const;
/// return the number of embedded cells
size_t nargs() const;
/// return the number of embedded cells
size_t ncols() const;
/// return the number of embedded cells
size_t nrows() const;
/// return the grid row of the top cell
row_type row() const;
/// return the last row of the top grid
row_type lastrow() const { return nrows() - 1; }
/// return the grid column of the top cell
col_type col() const;
/// return the last column of the top grid
col_type lastcol() const { return ncols() - 1; }
/// the inset just behind the cursor
InsetBase * nextInset();
/// the inset just in front of the cursor
InsetBase * prevInset();
/// the inset just in front of the cursor
InsetBase const * prevInset() const;
/// are we in mathed?
bool inMathed() const;
/// are we in texted?
bool inTexted() const;
//
// math-specific part
//
/// return the mathed cell this cursor is in
MathArray const & cell() const;
/// return the mathed cell this cursor is in
MathArray & cell();
/// the mathatom left of the cursor
MathAtom const & prevAtom() const;
/// the mathatom left of the cursor
MathAtom & prevAtom();
/// the mathatom right of the cursor
MathAtom const & nextAtom() const;
/// the mathatom right of the cursor
MathAtom & nextAtom();
//
// text-specific part
//
/// see comment for boundary_ below
bool boundary() const { return top().boundary(); }
/// see comment for boundary_ below
bool & boundary() { return top().boundary(); }
/// the paragraph we're in
Paragraph & paragraph();
/// the paragraph we're in
Paragraph const & paragraph() const;
/// the row in the paragraph we're in
Row & textRow();
/// the row in the paragraph we're in
Row const & textRow() const;
///
LyXText * text() const;
///
CursorSlice const & innerTextSlice() const;
///
InsetBase * innerInsetOfType(int code) const;
///
LyXText * innerText() const;
//
// elementary moving
//
/// move on one position
void forwardPos();
/// move on one paragraph
void forwardPar();
/// move on one cell
void forwardIdx();
/// move on one inset
void forwardInset();
private:
///
BufferView * bv_;
};
///
DocumentIterator bufferBegin(BufferView & bv);
///
DocumentIterator bufferEnd();
///
DocumentIterator insetBegin(BufferView & bv, InsetBase * inset);
///
DocumentIterator insetEnd();
#endif

View File

@ -35,8 +35,8 @@ void InsetBase::dispatch(LCursor & cur, FuncRequest const & cmd)
void InsetBase::priv_dispatch(LCursor & cur, FuncRequest const &) void InsetBase::priv_dispatch(LCursor & cur, FuncRequest const &)
{ {
cur.noupdate(); cur.noUpdate();
cur.notdispatched(); cur.undispatched();
} }

View File

@ -125,7 +125,7 @@ void InsetBranch::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
if (cmd.button() != mouse_button::button3) if (cmd.button() != mouse_button::button3)
InsetCollapsable::priv_dispatch(cur, cmd); InsetCollapsable::priv_dispatch(cur, cmd);
else else
cur.notdispatched(); cur.undispatched();
break; break;
case LFUN_INSET_DIALOG_UPDATE: case LFUN_INSET_DIALOG_UPDATE:

View File

@ -105,7 +105,7 @@ void InsetCommand::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
InsetCommandParams p; InsetCommandParams p;
InsetCommandMailer::string2params(mailer_name_, cmd.argument, p); InsetCommandMailer::string2params(mailer_name_, cmd.argument, p);
if (p.getCmdName().empty()) { if (p.getCmdName().empty()) {
cur.notdispatched(); cur.undispatched();
} else { } else {
setParams(p); setParams(p);
cur.bv().update(); cur.bv().update();

View File

@ -99,7 +99,7 @@ void InsetLabel::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
InsetCommandParams p; InsetCommandParams p;
InsetCommandMailer::string2params("label", cmd.argument, p); InsetCommandMailer::string2params("label", cmd.argument, p);
if (p.getCmdName().empty()) { if (p.getCmdName().empty()) {
cur.notdispatched(); cur.undispatched();
break; break;
} }
if (p.getContents() != params().getContents()) if (p.getContents() != params().getContents())

View File

@ -415,7 +415,7 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{ {
lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl; lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl;
//lyxerr << " cur:\n" << cur << endl; //lyxerr << " cur:\n" << cur << endl;
CursorSlice sl = cur.current(); CursorSlice sl = cur.top();
switch (cmd.action) { switch (cmd.action) {
@ -426,7 +426,7 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
cur.selection() = false; cur.selection() = false;
setPos(cur, cmd.x, cmd.y); setPos(cur, cmd.x, cmd.y);
cur.resetAnchor(); cur.resetAnchor();
cur.bv().cursor() = cur; cur.bv().cursor().setCursor(cur, false);
//if (cmd.button() == mouse_button::button2) //if (cmd.button() == mouse_button::button2)
// dispatch(cur, FuncRequest(LFUN_PASTESELECTION, "paragraph")); // dispatch(cur, FuncRequest(LFUN_PASTESELECTION, "paragraph"));
//lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl; //lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl;
@ -436,8 +436,7 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
if (cmd.button() != mouse_button::button1) if (cmd.button() != mouse_button::button1)
break; break;
setPos(cur, cmd.x, cmd.y); setPos(cur, cmd.x, cmd.y);
cur.bv().cursor().cursor_ = cur.cursor_; cur.bv().cursor().setCursor(cur, true);
cur.bv().cursor().selection() = true;
//lyxerr << "# InsetTabular::MouseMotion\n" << cur.bv().cursor() << endl; //lyxerr << "# InsetTabular::MouseMotion\n" << cur.bv().cursor() << endl;
break; break;
@ -471,9 +470,9 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_RIGHT: case LFUN_RIGHT:
cell(cur.idx()).dispatch(cur, cmd); cell(cur.idx()).dispatch(cur, cmd);
cur.dispatched(NONE); // override the cell's result cur.dispatched(NONE); // override the cell's result
if (sl == cur.current()) if (sl == cur.top())
isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur); isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur);
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_RIGHT); cur.dispatched(FINISHED_RIGHT);
break; break;
@ -481,9 +480,9 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_LEFT: case LFUN_LEFT:
cell(cur.idx()).dispatch(cur, cmd); cell(cur.idx()).dispatch(cur, cmd);
cur.dispatched(NONE); // override the cell's result cur.dispatched(NONE); // override the cell's result
if (sl == cur.current()) if (sl == cur.top())
isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur); isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur);
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_LEFT); cur.dispatched(FINISHED_LEFT);
break; break;
@ -491,14 +490,14 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_DOWN: case LFUN_DOWN:
cell(cur.idx()).dispatch(cur, cmd); cell(cur.idx()).dispatch(cur, cmd);
cur.dispatched(NONE); // override the cell's result cur.dispatched(NONE); // override the cell's result
if (sl == cur.current()) if (sl == cur.top())
if (tabular.row_of_cell(cur.idx()) != tabular.rows() - 1) { if (tabular.row_of_cell(cur.idx()) != tabular.rows() - 1) {
cur.idx() = tabular.getCellBelow(cur.idx()); cur.idx() = tabular.getCellBelow(cur.idx());
cur.par() = 0; cur.par() = 0;
cur.pos() = 0; cur.pos() = 0;
resetPos(cur); resetPos(cur);
} }
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_DOWN); cur.dispatched(FINISHED_DOWN);
break; break;
@ -506,14 +505,14 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_UP: case LFUN_UP:
cell(cur.idx()).dispatch(cur, cmd); cell(cur.idx()).dispatch(cur, cmd);
cur.dispatched(NONE); // override the cell's result cur.dispatched(NONE); // override the cell's result
if (sl == cur.current()) if (sl == cur.top())
if (tabular.row_of_cell(cur.idx()) != 0) { if (tabular.row_of_cell(cur.idx()) != 0) {
cur.idx() = tabular.getCellAbove(cur.idx()); cur.idx() = tabular.getCellAbove(cur.idx());
cur.par() = cur.lastpar(); cur.par() = cur.lastpar();
cur.pos() = cur.lastpos(); cur.pos() = cur.lastpos();
resetPos(cur); resetPos(cur);
} }
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_UP); cur.dispatched(FINISHED_UP);
break; break;
@ -564,7 +563,7 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_TABULAR_FEATURE: case LFUN_TABULAR_FEATURE:
if (!tabularFeatures(cur, cmd.argument)) if (!tabularFeatures(cur, cmd.argument))
cur.notdispatched(); cur.undispatched();
break; break;
// insert file functions // insert file functions
@ -572,7 +571,7 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_FILE_INSERT_ASCII: { case LFUN_FILE_INSERT_ASCII: {
string tmpstr = getContentsOfAsciiFile(&cur.bv(), cmd.argument, false); string tmpstr = getContentsOfAsciiFile(&cur.bv(), cmd.argument, false);
if (!tmpstr.empty() && !insertAsciiString(cur.bv(), tmpstr, false)) if (!tmpstr.empty() && !insertAsciiString(cur.bv(), tmpstr, false))
cur.notdispatched(); cur.undispatched();
break; break;
} }

View File

@ -289,7 +289,7 @@ void InsetText::edit(LCursor & cur, bool left)
setViewCache(&cur.bv()); setViewCache(&cur.bv());
int const par = left ? 0 : paragraphs().size() - 1; int const par = left ? 0 : paragraphs().size() - 1;
int const pos = left ? 0 : paragraphs().back().size(); int const pos = left ? 0 : paragraphs().back().size();
text_.setCursor(cur.current(), par, pos); text_.setCursor(cur.top(), par, pos);
cur.clearSelection(); cur.clearSelection();
finishUndo(); finishUndo();
sanitizeEmptyText(cur.bv()); sanitizeEmptyText(cur.bv());

View File

@ -22,7 +22,6 @@
#include "frontends/mouse_state.h" #include "frontends/mouse_state.h"
class Buffer; class Buffer;
class BufferParams; class BufferParams;
class BufferView; class BufferView;
@ -33,10 +32,10 @@ class Painter;
class Paragraph; class Paragraph;
class Row; class Row;
/** /**
A text inset is like a TeX box to write full text A text inset is like a TeX box to write full text
(including styles and other insets) in a given space. (including styles and other insets) in a given space.
@author: Jürgen Vigna
*/ */
class InsetText : public UpdatableInset { class InsetText : public UpdatableInset {
public: public:
@ -174,7 +173,6 @@ private:
/// ///
void clearInset(Painter &, int x, int y) const; void clearInset(Painter &, int x, int y) const;
/* Private structures and variables */
/// ///
bool autoBreakRows_; bool autoBreakRows_;
/// ///

View File

@ -390,7 +390,7 @@ int replace(BufferView * bv, string const & searchstr,
text->replaceSelectionWithString(bv->cursor(), replacestr); text->replaceSelectionWithString(bv->cursor(), replacestr);
text->setSelectionRange(bv->cursor(), replacestr.length()); text->setSelectionRange(bv->cursor(), replacestr.length());
bv->cursor().current() = fw ? bv->cursor().selEnd() : bv->cursor().selBegin(); bv->cursor().top() = fw ? bv->cursor().selEnd() : bv->cursor().selBegin();
bv->buffer()->markDirty(); bv->buffer()->markDirty();
find(bv, searchstr, cs, mw, fw); find(bv, searchstr, cs, mw, fw);
bv->update(); bv->update();

View File

@ -339,7 +339,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
break; break;
case LFUN_LAYOUT_TABULAR: case LFUN_LAYOUT_TABULAR:
disable = !cur.innerInsetTabular(); disable = !cur.innerInsetOfType(InsetBase::TABULAR_CODE);
break; break;
case LFUN_DEPTH_MIN: case LFUN_DEPTH_MIN:
@ -405,7 +405,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
if (tli) { if (tli) {
FuncStatus ret; FuncStatus ret;
//ret.disabled(true); //ret.disabled(true);
InsetTabular * tab = cur.innerInsetTabular(); InsetTabular * tab = static_cast<InsetTabular *>
(cur.innerInsetOfType(InsetBase::TABULAR_CODE));
if (tab) { if (tab) {
ret = tab->getStatus(cmd.argument); ret = tab->getStatus(cmd.argument);
flag |= ret; flag |= ret;

View File

@ -412,6 +412,13 @@ public:
/// our 'outermost' Font /// our 'outermost' Font
LyXFont font_; LyXFont font_;
///
double fill_separator(Row const & row) const;
///
double fill_hfill(Row const & row) const;
///
double
fill_label_hfill(ParagraphList::iterator pit, Row const & row) const;
private: private:
/// return past-the-last paragraph influenced by a layout /// return past-the-last paragraph influenced by a layout

View File

@ -1113,7 +1113,7 @@ void MathGridInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
else if (s == "swap-column") else if (s == "swap-column")
swapCol(col(cur.idx())); swapCol(col(cur.idx()));
else { else {
cur.notdispatched(); cur.undispatched();
return; return;
} }
lyxerr << "returning FINISHED_LEFT" << endl; lyxerr << "returning FINISHED_LEFT" << endl;

View File

@ -1070,7 +1070,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str,
#warning pretty ugly #warning pretty ugly
#endif #endif
static MathHullInset * lastformula = 0; static MathHullInset * lastformula = 0;
static CursorBase current = CursorBase(ibegin(nucleus())); static CursorBase current = DocumentIterator(ibegin(nucleus()));
static MathArray ar; static MathArray ar;
static string laststr; static string laststr;
@ -1086,7 +1086,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str,
} }
//lyxerr << "searching '" << str << "' in " << this << ar << endl; //lyxerr << "searching '" << str << "' in " << this << ar << endl;
for (CursorBase it = current; it != iend(nucleus()); increment(it)) { for (DocumentIterator it = current; it != iend(nucleus()); increment(it)) {
CursorSlice & top = it.back(); CursorSlice & top = it.back();
MathArray const & a = top.asMathInset()->cell(top.idx_); MathArray const & a = top.asMathInset()->cell(top.idx_);
if (a.matchpart(ar, top.pos_)) { if (a.matchpart(ar, top.pos_)) {

View File

@ -384,24 +384,20 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
break; break;
case LFUN_FINISHED_LEFT: case LFUN_FINISHED_LEFT:
cur.pop(cur.currentDepth());
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
break; break;
case LFUN_FINISHED_RIGHT: case LFUN_FINISHED_RIGHT:
cur.pop(cur.currentDepth());
++cur.pos(); ++cur.pos();
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
break; break;
case LFUN_FINISHED_UP: case LFUN_FINISHED_UP:
cur.pop(cur.currentDepth());
//idxUpDown(cur, true); //idxUpDown(cur, true);
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
break; break;
case LFUN_FINISHED_DOWN: case LFUN_FINISHED_DOWN:
cur.pop(cur.currentDepth());
//idxUpDown(cur, false); //idxUpDown(cur, false);
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
break; break;
@ -554,7 +550,15 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
break; break;
case LFUN_INSET_TOGGLE: case LFUN_INSET_TOGGLE:
cur.lockToggle(); //lockToggle();
if (cur.pos() != cur.lastpos()) {
// toggle previous inset ...
cur.nextAtom().nucleus()->lock(!cur.nextAtom()->lock());
} else if (cur.popLeft() && cur.pos() != cur.lastpos()) {
// ... or enclosing inset if we are in the last inset position
cur.nextAtom().nucleus()->lock(!cur.nextAtom()->lock());
++cur.pos();
}
break; break;
case LFUN_SELFINSERT: case LFUN_SELFINSERT:
@ -780,7 +784,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
cur.insert(ar); cur.insert(ar);
break; break;
} }
cur.notdispatched(); cur.undispatched();
break; break;
} }
@ -790,7 +794,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_WORD_REPLACE: case LFUN_WORD_REPLACE:
case LFUN_WORD_FIND: case LFUN_WORD_FIND:
if (!searchForward(&cur.bv(), cmd.getArg(0), false, false)) if (!searchForward(&cur.bv(), cmd.getArg(0), false, false))
cur.notdispatched(); cur.undispatched();
break; break;
cur.normalize(); cur.normalize();
@ -876,7 +880,7 @@ void MathNestInset::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd)
return; return;
} }
cur.notdispatched(); cur.undispatched();
} }
@ -914,9 +918,7 @@ void MathNestInset::lfunMouseMotion(LCursor & cur, FuncRequest const & cmd)
cur.selBegin(); cur.selBegin();
//cur.setScreenPos(cmd.x + xo_, cmd.y + yo_); //cur.setScreenPos(cmd.x + xo_, cmd.y + yo_);
cur.bv().cursor().cursor_ = cur.cursor_; cur.bv().cursor().setCursor(cur, true);
cur.bv().cursor().selection() = true;
return;
} }

View File

@ -61,36 +61,35 @@ void RefInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
MathArray ar; MathArray ar;
if (createMathInset_fromDialogStr(cmd.argument, ar)) { if (createMathInset_fromDialogStr(cmd.argument, ar)) {
*this = *ar[0].nucleus()->asRefInset(); *this = *ar[0].nucleus()->asRefInset();
return; break;
} }
} }
cur.notdispatched(); cur.undispatched();
return; break;
case LFUN_MOUSE_RELEASE: case LFUN_MOUSE_RELEASE:
if (cmd.button() == mouse_button::button3) { if (cmd.button() == mouse_button::button3) {
lyxerr << "trying to goto ref" << cell(0) << endl; lyxerr << "trying to goto ref" << cell(0) << endl;
cur.bv().dispatch(FuncRequest(LFUN_REF_GOTO, asString(cell(0)))); cur.bv().dispatch(FuncRequest(LFUN_REF_GOTO, asString(cell(0))));
return; break;
} }
if (cmd.button() == mouse_button::button1) { if (cmd.button() == mouse_button::button1) {
// Eventually trigger dialog with button 3 // Eventually trigger dialog with button 3, not 1
// not 1
string const data = createDialogStr("ref"); string const data = createDialogStr("ref");
cur.bv().owner()->getDialogs().show("ref", data, this); cur.bv().owner()->getDialogs().show("ref", data, this);
return; break;
} }
cur.notdispatched(); cur.undispatched();
return; break;
case LFUN_MOUSE_PRESS: case LFUN_MOUSE_PRESS:
case LFUN_MOUSE_MOTION: case LFUN_MOUSE_MOTION:
// eat other mouse commands // eat other mouse commands
return; break;
default: default:
CommandInset::priv_dispatch(cur, cmd); CommandInset::priv_dispatch(cur, cmd);
return; break;
} }
} }

View File

@ -1168,10 +1168,10 @@ void LyXText::cursorLeftOneWord(LCursor & cur)
void LyXText::selectWord(LCursor & cur, word_location loc) void LyXText::selectWord(LCursor & cur, word_location loc)
{ {
BOOST_ASSERT(this == cur.text()); BOOST_ASSERT(this == cur.text());
CursorSlice from = cur.current(); CursorSlice from = cur.top();
CursorSlice to = cur.current(); CursorSlice to = cur.top();
getWord(from, to, loc); getWord(from, to, loc);
if (cur.current() != from) if (cur.top() != from)
setCursor(cur, from.par(), from.pos()); setCursor(cur, from.par(), from.pos());
if (to == from) if (to == from)
return; return;
@ -1340,9 +1340,9 @@ void LyXText::Delete(LCursor & cur)
{ {
BOOST_ASSERT(this == cur.text()); BOOST_ASSERT(this == cur.text());
// just move to the right, if we had success make a backspace // just move to the right, if we had success make a backspace
CursorSlice sl = cur.current(); CursorSlice sl = cur.top();
cursorRight(cur); cursorRight(cur);
if (sl == cur.current()) { if (sl == cur.top()) {
recordUndo(cur, Undo::DELETE, cur.par(), max(0, cur.par() - 1)); recordUndo(cur, Undo::DELETE, cur.par(), max(0, cur.par() - 1));
backspace(cur); backspace(cur);
} }
@ -1820,8 +1820,8 @@ int LyXText::cursorX(CursorSlice const & cur) const
ParagraphList::iterator pit = getPar(cur); ParagraphList::iterator pit = getPar(cur);
if (pit->rows.empty()) if (pit->rows.empty())
return xo_; return xo_;
Row const & row = *pit->getRow(cur.pos());
Row const & row = *pit->getRow(cur.pos());
pos_type pos = cur.pos(); pos_type pos = cur.pos();
pos_type cursor_vpos = 0; pos_type cursor_vpos = 0;
@ -1894,7 +1894,7 @@ CursorSlice & LyXText::cursor()
<< "\nthis: " << this << endl; << "\nthis: " << this << endl;
BOOST_ASSERT(false); BOOST_ASSERT(false);
} }
return bv()->cursor().current(); return bv()->cursor().top();
} }
@ -1906,7 +1906,7 @@ CursorSlice const & LyXText::cursor() const
<< "\nthis: " << this << endl; << "\nthis: " << this << endl;
BOOST_ASSERT(false); BOOST_ASSERT(false);
} }
return bv()->cursor().current(); return bv()->cursor().top();
} }

View File

@ -414,9 +414,8 @@ void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall)
return; return;
} }
// ok we have a selection. // Ok, we have a selection.
recordUndoSelection(cur); recordUndoSelection(cur);
freezeUndo();
ParagraphList::iterator beg = getPar(cur.selBegin().par()); ParagraphList::iterator beg = getPar(cur.selBegin().par());
ParagraphList::iterator end = getPar(cur.selEnd().par()); ParagraphList::iterator end = getPar(cur.selEnd().par());
@ -432,8 +431,6 @@ void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall)
setCharFont(pos.pit(), pos.pos(), f); setCharFont(pos.pit(), pos.pos(), f);
} }
unFreezeUndo();
redoParagraphs(beg, ++end); redoParagraphs(beg, ++end);
} }
@ -486,7 +483,7 @@ void LyXText::toggleFree(LCursor & cur, LyXFont const & font, bool toggleall)
// Try implicit word selection // Try implicit word selection
// If there is a change in the language the implicit word selection // If there is a change in the language the implicit word selection
// is disabled. // is disabled.
CursorSlice resetCursor = cur.current(); CursorSlice resetCursor = cur.top();
bool implicitSelection = bool implicitSelection =
font.language() == ignore_language font.language() == ignore_language
&& font.number() == LyXFont::IGNORE && font.number() == LyXFont::IGNORE
@ -499,7 +496,7 @@ void LyXText::toggleFree(LCursor & cur, LyXFont const & font, bool toggleall)
// and cursor is set to the original position. // and cursor is set to the original position.
if (implicitSelection) { if (implicitSelection) {
cur.clearSelection(); cur.clearSelection();
cur.current() = resetCursor; cur.top() = resetCursor;
cur.resetAnchor(); cur.resetAnchor();
} }
} }
@ -511,7 +508,7 @@ string LyXText::getStringToIndex(LCursor & cur)
// Try implicit word selection // Try implicit word selection
// If there is a change in the language the implicit word selection // If there is a change in the language the implicit word selection
// is disabled. // is disabled.
CursorSlice const reset_cursor = cur.current(); CursorSlice const reset_cursor = cur.top();
bool const implicitSelection = bool const implicitSelection =
selectWordWhenUnderCursor(cur, lyx::PREVIOUS_WORD); selectWordWhenUnderCursor(cur, lyx::PREVIOUS_WORD);
@ -524,7 +521,7 @@ string LyXText::getStringToIndex(LCursor & cur)
idxstring = cur.selectionAsString(false); idxstring = cur.selectionAsString(false);
// Reset cursors to their original position. // Reset cursors to their original position.
cur.current() = reset_cursor; cur.top() = reset_cursor;
cur.resetAnchor(); cur.resetAnchor();
// Clear the implicit selection. // Clear the implicit selection.
@ -1088,9 +1085,9 @@ void LyXText::insertStringAsParagraphs(LCursor & cur, string const & str)
bool LyXText::setCursor(LCursor & cur, par_type par, pos_type pos, bool LyXText::setCursor(LCursor & cur, par_type par, pos_type pos,
bool setfont, bool boundary) bool setfont, bool boundary)
{ {
CursorSlice old_cursor = cur.current(); CursorSlice old_cursor = cur.top();
setCursorIntern(cur, par, pos, setfont, boundary); setCursorIntern(cur, par, pos, setfont, boundary);
return deleteEmptyParagraphMechanism(cur.current(), old_cursor); return deleteEmptyParagraphMechanism(cur.top(), old_cursor);
} }
@ -1145,8 +1142,8 @@ void LyXText::setCursor(CursorSlice & cur, par_type par,
void LyXText::setCursorIntern(LCursor & cur, void LyXText::setCursorIntern(LCursor & cur,
par_type par, pos_type pos, bool setfont, bool boundary) par_type par, pos_type pos, bool setfont, bool boundary)
{ {
setCursor(cur.current(), par, pos, boundary); setCursor(cur.top(), par, pos, boundary);
cur.x_target() = cursorX(cur.current()); cur.x_target() = cursorX(cur.top());
if (setfont) if (setfont)
setCurrentFont(cur); setCurrentFont(cur);
} }
@ -1298,7 +1295,7 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int x, int y)
{ {
x -= xo_; x -= xo_;
y -= yo_; y -= yo_;
CursorSlice old_cursor = cur.current(); CursorSlice old_cursor = cur.top();
ParagraphList::iterator pit; ParagraphList::iterator pit;
Row const & row = *getRowNearY(y, pit); Row const & row = *getRowNearY(y, pit);
lyxerr << "hit row at: " << row.pos() << endl; lyxerr << "hit row at: " << row.pos() << endl;
@ -1308,7 +1305,7 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int x, int y)
cur.par() = parOffset(pit); cur.par() = parOffset(pit);
cur.pos() = pos; cur.pos() = pos;
cur.boundary() = bound; cur.boundary() = bound;
deleteEmptyParagraphMechanism(cur.current(), old_cursor); deleteEmptyParagraphMechanism(cur.top(), old_cursor);
} }
@ -1402,7 +1399,7 @@ void LyXText::cursorUp(LCursor & cur)
{ {
Row const & row = cur.textRow(); Row const & row = cur.textRow();
int x = cur.x_target(); int x = cur.x_target();
int y = cursorY(cur.current()) - row.baseline() - 1; int y = cursorY(cur.top()) - row.baseline() - 1;
setCursorFromCoordinates(cur, x, y); setCursorFromCoordinates(cur, x, y);
if (!cur.selection()) { if (!cur.selection()) {
@ -1417,7 +1414,7 @@ void LyXText::cursorDown(LCursor & cur)
{ {
Row const & row = cur.textRow(); Row const & row = cur.textRow();
int x = cur.x_target(); int x = cur.x_target();
int y = cursorY(cur.current()) - row.baseline() + row.height() + 1; int y = cursorY(cur.top()) - row.baseline() + row.height() + 1;
setCursorFromCoordinates(cur, x, y); setCursorFromCoordinates(cur, x, y);
if (!cur.selection()) { if (!cur.selection()) {

View File

@ -262,7 +262,7 @@ void LyXText::gotoInset(LCursor & cur,
if (!gotoNextInset(cur, codes, contents)) { if (!gotoNextInset(cur, codes, contents)) {
if (cur.pos() || cur.par() != 0) { if (cur.pos() || cur.par() != 0) {
CursorSlice tmp = cur.current(); CursorSlice tmp = cur.top();
cur.par() = 0; cur.par() = 0;
cur.pos() = 0; cur.pos() = 0;
if (!gotoNextInset(cur, codes, contents)) { if (!gotoNextInset(cur, codes, contents)) {
@ -376,7 +376,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
//lyxerr << "*** LyXText::dispatch: cmd: " << cmd << endl; //lyxerr << "*** LyXText::dispatch: cmd: " << cmd << endl;
BufferView * bv = &cur.bv(); BufferView * bv = &cur.bv();
CursorSlice sl = cur.current(); CursorSlice sl = cur.top();
switch (cmd.action) { switch (cmd.action) {
@ -466,7 +466,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
cursorLeft(cur); cursorLeft(cur);
else else
cursorRight(cur); cursorRight(cur);
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_RIGHT); cur.dispatched(FINISHED_RIGHT);
break; break;
@ -477,7 +477,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
cursorRight(cur); cursorRight(cur);
else else
cursorLeft(cur); cursorLeft(cur);
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_LEFT); cur.dispatched(FINISHED_LEFT);
break; break;
@ -485,7 +485,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_UPSEL: case LFUN_UPSEL:
cur.selHandle(cmd.action == LFUN_UPSEL); cur.selHandle(cmd.action == LFUN_UPSEL);
cursorUp(cur); cursorUp(cur);
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_UP); cur.dispatched(FINISHED_UP);
break; break;
@ -493,7 +493,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_DOWNSEL: case LFUN_DOWNSEL:
cur.selHandle(cmd.action == LFUN_DOWNSEL); cur.selHandle(cmd.action == LFUN_DOWNSEL);
cursorDown(cur); cursorDown(cur);
if (sl == cur.current()) if (sl == cur.top())
cur.dispatched(FINISHED_DOWN); cur.dispatched(FINISHED_DOWN);
break; break;
@ -788,7 +788,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_INSET_TOGGLE: case LFUN_INSET_TOGGLE:
cur.clearSelection(); cur.clearSelection();
if (!toggleInset(cur)) if (!toggleInset(cur))
cur.notdispatched(); cur.undispatched();
else else
bv->switchKeyMap(); bv->switchKeyMap();
break; break;
@ -869,7 +869,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_BEGINNINGBUFSEL: case LFUN_BEGINNINGBUFSEL:
if (in_inset_) { if (in_inset_) {
cur.notdispatched(); cur.undispatched();
} else { } else {
if (!cur.selection()) if (!cur.selection())
cur.resetAnchor(); cur.resetAnchor();
@ -880,7 +880,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_ENDBUFSEL: case LFUN_ENDBUFSEL:
if (in_inset_) { if (in_inset_) {
cur.notdispatched(); cur.undispatched();
} else { } else {
if (!cur.selection()) if (!cur.selection())
cur.resetAnchor(); cur.resetAnchor();
@ -890,8 +890,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
break; break;
case LFUN_GETXY: case LFUN_GETXY:
cur.message(tostr(cursorX(cur.current())) + ' ' cur.message(tostr(cursorX(cur.top())) + ' '
+ tostr(cursorY(cur.current()))); + tostr(cursorY(cur.top())));
break; break;
case LFUN_SETXY: { case LFUN_SETXY: {
@ -1095,12 +1095,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
"Dispatch: no selection possible\n"; "Dispatch: no selection possible\n";
break; break;
} }
CursorSlice old = cur.current(); CursorSlice old = cur.top();
setCursorFromCoordinates(cur, cmd.x, cmd.y); setCursorFromCoordinates(cur, cmd.x, cmd.y);
// This is to allow jumping over large insets // This is to allow jumping over large insets
// FIXME: shouldn't be top-text-specific // FIXME: shouldn't be top-text-specific
if (!in_inset_ && cur.current() == old) { if (!in_inset_ && cur.top() == old) {
if (cmd.y - bv->top_y() >= bv->workHeight()) if (cmd.y - bv->top_y() >= bv->workHeight())
cursorDown(cur); cursorDown(cur);
else if (cmd.y - bv->top_y() < 0) else if (cmd.y - bv->top_y() < 0)
@ -1108,8 +1108,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
} }
// don't set anchor_ // don't set anchor_
bv->cursor().cursor_ = cur.cursor_; bv->cursor().setCursor(cur, false);
bv->cursor().setSelection();
break; break;
} }
@ -1154,7 +1153,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
setCursorFromCoordinates(cur, cmd.x, cmd.y); setCursorFromCoordinates(cur, cmd.x, cmd.y);
cur.resetAnchor(); cur.resetAnchor();
finishUndo(); finishUndo();
cur.x_target() = cursorX(cur.current()); cur.x_target() = cursorX(cur.top());
// set cursor and anchor to this position // set cursor and anchor to this position
bv->cursor() = cur; bv->cursor() = cur;
@ -1179,7 +1178,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
// do nothing if we used the mouse wheel // do nothing if we used the mouse wheel
if (cmd.button() == mouse_button::button4 if (cmd.button() == mouse_button::button4
|| cmd.button() == mouse_button::button5) { || cmd.button() == mouse_button::button5) {
cur.notdispatched(); cur.undispatched();
break; break;
} }
@ -1444,7 +1443,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_FINISHED_LEFT: case LFUN_FINISHED_LEFT:
lyxerr << "handle LFUN_FINISHED_LEFT" << endl; lyxerr << "handle LFUN_FINISHED_LEFT" << endl;
cur.pop(cur.currentDepth());
if (isRTL(cur.paragraph())) if (isRTL(cur.paragraph()))
cursorLeft(cur); cursorLeft(cur);
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
@ -1452,7 +1450,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_FINISHED_RIGHT: case LFUN_FINISHED_RIGHT:
lyxerr << "handle LFUN_FINISHED_RIGHT" << endl; lyxerr << "handle LFUN_FINISHED_RIGHT" << endl;
cur.pop(cur.currentDepth());
if (!isRTL(cur.paragraph())) if (!isRTL(cur.paragraph()))
cursorRight(cur); cursorRight(cur);
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
@ -1460,14 +1457,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_FINISHED_UP: case LFUN_FINISHED_UP:
lyxerr << "handle LFUN_FINISHED_UP" << endl; lyxerr << "handle LFUN_FINISHED_UP" << endl;
cur.pop(cur.currentDepth());
cursorUp(cur); cursorUp(cur);
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
break; break;
case LFUN_FINISHED_DOWN: case LFUN_FINISHED_DOWN:
lyxerr << "handle LFUN_FINISHED_DOWN" << endl; lyxerr << "handle LFUN_FINISHED_DOWN" << endl;
cur.pop(cur.currentDepth());
cursorDown(cur); cursorDown(cur);
cur.bv().cursor() = cur; cur.bv().cursor() = cur;
break; break;
@ -1598,7 +1593,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
break; break;
default: default:
cur.notdispatched(); cur.undispatched();
break; break;
} }
} }

View File

@ -27,27 +27,15 @@
using lyx::paroffset_type; using lyx::paroffset_type;
/// The flag used by finishUndo(). namespace {
bool undo_finished;
/// Whether actions are not added to the undo stacks. /// Whether actions are not added to the undo stacks.
bool undo_frozen; bool undo_frozen;
Undo::Undo(undo_kind kind_, int text_, int index_, /// The flag used by finishUndo().
int first_par_, int end_par_, int cursor_par_, int cursor_pos_) bool undo_finished;
:
kind(kind_),
text(text_),
index(index_),
first_par(first_par_),
end_par(end_par_),
cursor_par(cursor_par_),
cursor_pos(cursor_pos_)
{}
namespace {
std::ostream & operator<<(std::ostream & os, Undo const & undo) std::ostream & operator<<(std::ostream & os, Undo const & undo)
{ {
return os << " text: " << undo.text return os << " text: " << undo.text
@ -97,6 +85,15 @@ void recordUndo(Undo::undo_kind kind,
LCursor & cur, paroffset_type first_par, paroffset_type last_par, LCursor & cur, paroffset_type first_par, paroffset_type last_par,
limited_stack<Undo> & stack) limited_stack<Undo> & stack)
{ {
#if 0
DocumentIterator it = bufferBegin(cur.bv());
DocumentIterator et = bufferEnd();
size_t count = 0;
for ( ; it != et; it.forwardPos(), ++count)
if (it.top() == cur.top())
lyxerr << "### found at " << count << std::endl;
#endif
if (first_par > last_par) { if (first_par > last_par) {
paroffset_type t = first_par; paroffset_type t = first_par;
first_par = last_par; first_par = last_par;
@ -121,18 +118,24 @@ void recordUndo(Undo::undo_kind kind,
} }
} }
// make and push the Undo entry // push and fill the Undo entry
int textnum; if (cur.inTexted()) {
stack.push(Undo());
LyXText * text = cur.text(); LyXText * text = cur.text();
BOOST_ASSERT(text); // not in mathed (yet) int textnum;
ParIterator pit = text2pit(buf, text, textnum); ParIterator pit = text2pit(buf, text, textnum);
stack.push(Undo(kind, textnum, pit.index(), Undo & undo = stack.top();
first_par, end_par, cur.par(), cur.pos())); undo.kind = kind;
undo.text = textnum;
undo.index = pit.index();
undo.first_par = first_par;
undo.end_par = end_par;
undo.cursor_par = cur.par();
undo.cursor_pos = cur.pos();
undo.math = false;
//lyxerr << "undo record: " << stack.top() << std::endl; //lyxerr << "undo record: " << stack.top() << std::endl;
// record the relevant paragraphs // record the relevant paragraphs
ParagraphList & undo_pars = stack.top().pars;
ParagraphList & plist = text->paragraphs(); ParagraphList & plist = text->paragraphs();
ParagraphList::iterator first = plist.begin(); ParagraphList::iterator first = plist.begin();
advance(first, first_par); advance(first, first_par);
@ -140,8 +143,14 @@ void recordUndo(Undo::undo_kind kind,
advance(last, last_par); advance(last, last_par);
for (ParagraphList::iterator it = first; it != last; ++it) for (ParagraphList::iterator it = first; it != last; ++it)
undo_pars.push_back(*it); undo.pars.push_back(*it);
undo_pars.push_back(*last); undo.pars.push_back(*last);
} else {
BOOST_ASSERT(false); // not in mathed (yet)
stack.push(Undo());
Undo & undo = stack.top();
undo.math = false;
}
// and make sure that next time, we should be combining if possible // and make sure that next time, we should be combining if possible
undo_finished = false; undo_finished = false;

View File

@ -19,6 +19,8 @@
#include "ParagraphList_fwd.h" #include "ParagraphList_fwd.h"
#include "support/types.h" #include "support/types.h"
#include <string>
class LCursor; class LCursor;
class BufferView; class BufferView;
@ -28,8 +30,7 @@ class BufferView;
* contains complete paragraphs and sufficient information * contains complete paragraphs and sufficient information
* to restore the state. * to restore the state.
*/ */
class Undo { struct Undo {
public:
/// This is used to combine consecutive undo recordings of the same kind. /// This is used to combine consecutive undo recordings of the same kind.
enum undo_kind { enum undo_kind {
/** /**
@ -46,11 +47,6 @@ public:
ATOMIC ATOMIC
}; };
/// constructor
Undo(undo_kind kind, int text, int index,
int first_par, int end_par, int cursor_par, int cursor_pos);
public:
/// which kind of operation are we recording for? /// which kind of operation are we recording for?
undo_kind kind; undo_kind kind;
/// hosting LyXText counted from buffer begin /// hosting LyXText counted from buffer begin
@ -65,8 +61,12 @@ public:
int cursor_par; int cursor_par;
/// the position of the cursor in the hosting paragraph /// the position of the cursor in the hosting paragraph
int cursor_pos; int cursor_pos;
/// the contents of the paragraphs saved /// the contents of the saved paragraphs (for texted)
ParagraphList pars; ParagraphList pars;
/// the contents of the saved matharray (for mathed)
std::string array;
/// in mathed?
bool math;
}; };
@ -79,7 +79,7 @@ bool textRedo(BufferView &);
/// makes sure the next operation will be stored /// makes sure the next operation will be stored
void finishUndo(); void finishUndo();
/// whilst undo is frozen, all actions do not get added to the undo stack /// whilst undo is frozen, no actions gets added to the undo stack
void freezeUndo(); void freezeUndo();
/// track undos again /// track undos again
@ -108,7 +108,4 @@ void recordUndoSelection(LCursor & cur, Undo::undo_kind kind = Undo::ATOMIC);
/// convienience: prepare undo for the single paragraph containing the cursor /// convienience: prepare undo for the single paragraph containing the cursor
void recordUndoFullDocument(LCursor & cur); void recordUndoFullDocument(LCursor & cur);
/// are we avoiding tracking undos currently?
extern bool undo_frozen;
#endif // UNDO_FUNCS_H #endif // UNDO_FUNCS_H