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) {
text->setSelectionRange(cursor(), length);
cursor().setSelection();
if (backwards)
if (backwards) {
#if 0
swap(cursor().cursor_, cursor().anchor_);
#else
DocumentIterator it = cursor();
cursor().setCursor(cursor().anchor_, false);
cursor().anchor_ = it;
#endif
}
}
fitCursor();

View File

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

View File

@ -7,6 +7,22 @@
* BufferView_pimpl.C: rename textwidth -> maxwidth,
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>
* Bidi.[Ch] (computeTables): const correctness

View File

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

View File

@ -151,16 +151,16 @@ struct Buffer::Impl
string temppath;
TexRow texrow;
/// need to regenerate .tex ?
/// need to regenerate .tex?
DepClean dep_clean;
/// is save needed
/// is save needed?
mutable bool lyx_clean;
/// is autosave needed
/// is autosave needed?
mutable bool bak_clean;
/// is this a unnamed file (New...)
/// is this a unnamed file (New...)?
bool unnamed;
/// buffer is r/o
@ -174,13 +174,13 @@ struct Buffer::Impl
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
* and by the citation inset.
*/
bool file_fully_loaded;
/// our Text
/// our text
LyXText text;
};

View File

@ -57,19 +57,17 @@ limited_stack<string> theCutBuffer;
LCursor::LCursor(BufferView & bv)
: cursor_(1), anchor_(1), bv_(&bv), current_(0),
cached_y_(0), x_target_(-1),
selection_(false), mark_(false)
: DocumentIterator(bv), anchor_(bv),
cached_y_(0), x_target_(-1), selection_(false), mark_(false)
{}
void LCursor::reset()
{
cursor_.clear();
clear();
push_back(CursorSlice());
anchor_.clear();
cursor_.push_back(CursorSlice());
anchor_.push_back(CursorSlice());
current_ = 0;
cached_y_ = 0;
clearTargetX();
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)
{
lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
@ -84,9 +90,11 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
BOOST_ASSERT(idx() <= lastidx());
BOOST_ASSERT(par() <= lastpar());
FuncRequest cmd = cmd0;
nopop_ = false;
DocumentIterator orig = *this;
disp_.update(true);
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
// val flags if necessary
inset()->dispatch(*this, cmd);
@ -96,7 +104,6 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
switch (disp_.val()) {
case NONE:
// the inset handled the event fully
current_ = cursor_.size() - 1;
return DispatchResult(true, true);
case FINISHED_LEFT:
// the inset handled the event partially
@ -112,15 +119,15 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
cmd = FuncRequest(LFUN_FINISHED_DOWN);
break;
default:
//lyxerr << "not handled on level " << current_
//lyxerr << "not handled on level " << depth()
// << " val: " << disp_.val() << endl;
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;
current_ = cursor_.size() - 1;
return disp_;
}
@ -128,57 +135,60 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status)
{
lyxerr << "\nLCursor::getStatus: cmd: " << cmd << endl << *this << endl;
DocumentIterator orig = *this;
BOOST_ASSERT(pos() <= lastpos());
BOOST_ASSERT(idx() <= lastidx());
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
// a definitive decision on whether it want to handle the
// request or not. The result of this decision is put into
// the 'status' parameter.
bool const res = inset()->getStatus(*this, cmd, status);
if (res) {
current_ = cursor_.size() - 1;
setCursor(orig, false);
return true;
}
}
BOOST_ASSERT(current_ == 0);
bool const res = bv_->text()->getStatus(*this, cmd, status);
current_ = cursor_.size() - 1;
bool const res = bv().text()->getStatus(*this, cmd, status);
setCursor(orig, false);
return res;
}
void LCursor::push(InsetBase * inset)
BufferView & LCursor::bv() const
{
lyxerr << "LCursor::push() inset: " << inset << endl;
cursor_.push_back(CursorSlice(inset));
anchor_.push_back(CursorSlice(inset));
++current_;
updatePos();
return DocumentIterator::bv();
}
/*
void LCursor::pop(int depth)
{
while (int(cursor_.size()) > depth + 1)
while (int(size()) > depth + 1)
pop();
lyxerr << "LCursor::pop() result: " << *this << endl;
}
*/
void LCursor::pop()
{
BOOST_ASSERT(cursor_.size() >= 1);
cursor_.pop_back();
BOOST_ASSERT(size() >= 1);
pop_back();
anchor_.pop_back();
current_ = cursor_.size() - 1;
}
void LCursor::push(InsetBase * p)
{
push_back(CursorSlice(p));
}
void LCursor::pushLeft(InsetBase * p)
{
BOOST_ASSERT(!cursor_.empty());
BOOST_ASSERT(!empty());
//lyxerr << "Entering inset " << t << " left" << endl;
push(p);
p->idxFirst(*this);
@ -187,7 +197,7 @@ void LCursor::pushLeft(InsetBase * p)
bool LCursor::popLeft()
{
BOOST_ASSERT(!cursor_.empty());
BOOST_ASSERT(!empty());
//lyxerr << "Leaving inset to the left" << endl;
if (depth() <= 1) {
if (depth() == 1)
@ -202,7 +212,7 @@ bool LCursor::popLeft()
bool LCursor::popRight()
{
BOOST_ASSERT(!cursor_.empty());
BOOST_ASSERT(!empty());
//lyxerr << "Leaving inset to the right" << endl;
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()
{
BOOST_ASSERT(!cursor_.empty());
for (int i = cursor_.size() - 1; i >= 1; --i) {
int res = cursor_[i].inset()->currentMode();
BOOST_ASSERT(!empty());
for (int i = size() - 1; i >= 1; --i) {
int res = operator[](i).inset()->currentMode();
if (res != MathInset::UNDECIDED_MODE)
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()
{
BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1)
cached_y_ = bv_->top_y() + cursor_.back().inset()->yo();
//cached_y_ = cursor_.back().inset()->yo();
BOOST_ASSERT(!empty());
if (size() > 1)
cached_y_ = bv().top_y() + back().inset()->yo();
//cached_y_ = back().inset()->yo();
}
void LCursor::getDim(int & asc, int & des) const
{
BOOST_ASSERT(!cursor_.empty());
BOOST_ASSERT(!empty());
if (inMathed()) {
BOOST_ASSERT(inset());
BOOST_ASSERT(inset()->asMathInset());
@ -301,18 +266,18 @@ void LCursor::getDim(int & asc, int & des) const
void LCursor::getPos(int & x, int & y) const
{
BOOST_ASSERT(!cursor_.empty());
BOOST_ASSERT(!empty());
x = 0;
y = 0;
if (cursor_.size() == 1) {
x = bv_->text()->cursorX(cursor_.front());
y = bv_->text()->cursorY(cursor_.front());
if (size() == 1) {
x = bv().text()->cursorX(front());
y = bv().text()->cursorY(front());
} else {
if (!inset()) {
lyxerr << "#### LCursor::getPos: " << *this << endl;
BOOST_ASSERT(inset());
}
inset()->getCursorPos(cursor_.back(), x, y);
inset()->getCursorPos(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();
@ -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()
{
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()
{
@ -423,34 +340,34 @@ CursorSlice const & LCursor::anchor() const
CursorSlice const & LCursor::selBegin() const
{
if (!selection())
return cursor_.back();
return anchor() < cursor_.back() ? anchor() : cursor_.back();
return back();
return anchor() < back() ? anchor() : back();
}
CursorSlice & LCursor::selBegin()
{
if (!selection())
return cursor_.back();
return back();
// 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
{
if (!selection())
return cursor_.back();
return anchor() > cursor_.back() ? anchor() : cursor_.back();
return back();
return anchor() > back() ? anchor() : back();
}
CursorSlice & LCursor::selEnd()
{
if (!selection())
return cursor_.back();
return back();
// 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;
cursor_ = where;
setCursor(where, false);
anchor_ = where;
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
{
for (int i = 1, n = depth(); i < n; ++i) {
cursor_[i].inset()->infoize(os);
operator[](i).inset()->infoize(os);
os << " ";
}
if (pos() != 0)
@ -701,7 +507,7 @@ void LCursor::eraseSelection()
for (col_type col = c1; col <= c2; ++col)
p->cell(p->index(row, col)).clear();
}
current() = i1;
back() = i1;
} else {
lyxerr << "can't erase this selection 1" << endl;
}
@ -786,9 +592,8 @@ void LCursor::selClearOrDel()
std::ostream & operator<<(std::ostream & os, LCursor const & cur)
{
for (size_t i = 0, n = cur.cursor_.size(); i != n; ++i)
os << " " << cur.cursor_[i] << " | " << cur.anchor_[i] << "\n";
os << " current: " << cur.current_ << endl;
for (size_t i = 0, n = cur.size(); i != n; ++i)
os << " " << cur.operator[](i) << " | " << cur.anchor_[i] << "\n";
os << " selection: " << cur.selection_ << endl;
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
// 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_commentinset.h"
#include "mathed/math_factory.h"
#include "mathed/math_gridinset.h"
#include "mathed/math_macroarg.h"
#include "mathed/math_macrotemplate.h"
#include "mathed/math_mathmlstream.h"
#include "mathed/math_scriptinset.h"
#include "mathed/math_spaceinset.h"
#include "mathed/math_support.h"
#include "mathed/math_unknowninset.h"
@ -888,7 +625,7 @@ CursorBase iend(InsetBase * p)
bool LCursor::isInside(InsetBase const * p)
{
for (unsigned i = 0; i < depth(); ++i)
if (cursor_[i].inset() == p)
if (operator[](i).inset() == p)
return true;
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
if (cursor.size() > anchor.size())
@ -1127,10 +865,10 @@ bool LCursor::erase()
bool LCursor::up()
{
macroModeClose();
CursorBase save = cursor_;
DocumentIterator save = *this;
if (goUpDown(true))
return true;
cursor_ = save;
setCursor(save, false);
autocorrect() = false;
return selection();
}
@ -1139,10 +877,10 @@ bool LCursor::up()
bool LCursor::down()
{
macroModeClose();
CursorBase save = cursor_;
DocumentIterator save = *this;
if (goUpDown(false))
return true;
cursor_ = save;
setCursor(save, false);
autocorrect() = false;
return selection();
}
@ -1203,8 +941,8 @@ int LCursor::targetX() const
MathHullInset * LCursor::formula() const
{
for (int i = cursor_.size() - 1; i >= 1; --i) {
MathInset * inset = cursor_[i].inset()->asMathInset();
for (int i = size() - 1; i >= 1; --i) {
MathInset * inset = operator[](i).inset()->asMathInset();
if (inset && inset->asHullInset())
return static_cast<MathHullInset *>(inset);
}
@ -1248,12 +986,12 @@ bool LCursor::inMacroArgMode() const
MathGridInset * LCursor::enclosingGrid(idx_type & idx) const
{
for (MathInset::difference_type i = depth() - 1; i >= 0; --i) {
MathInset * m = cursor_[i].inset()->asMathInset();
MathInset * m = operator[](i).inset()->asMathInset();
if (!m)
return 0;
MathGridInset * p = m->asGridInset();
if (p) {
idx = cursor_[i].idx_;
idx = operator[](i).idx_;
return p;
}
}
@ -1279,8 +1017,8 @@ void LCursor::touch()
{
#warning look here
#if 0
CursorBase::const_iterator it = cursor_.begin();
CursorBase::const_iterator et = cursor_.end();
DocumentIterator::const_iterator it = begin();
DocumentIterator::const_iterator et = end();
for ( ; it != et; ++it)
it->cell().touch();
#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)
{
CursorBase best_cursor;
DocumentIterator best_cursor(bv());
double best_dist = 1e10;
CursorBase it = ibegin(formula());
CursorBase et = iend(formula());
DocumentIterator it = bufferBegin(bv());
DocumentIterator et = bufferEnd();
while (1) {
// avoid invalid nesting when selecting
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)
break;
increment(it);
it.forwardPos();
}
if (best_dist < 1e10)
cursor_ = best_cursor;
setCursor(best_cursor, false);
return best_dist < 1e10;
}
@ -1454,9 +1192,9 @@ void LCursor::bruteFind2(int x, int y)
{
double best_dist = 1e10;
CursorBase it = cursor_;
DocumentIterator it = *this;
it.back().pos() = 0;
CursorBase et = cursor_;
DocumentIterator et = *this;
et.back().pos() = et.back().asMathInset()->cell(et.back().idx_).size();
for (int i = 0; ; ++i) {
int xo, yo;
@ -1468,24 +1206,11 @@ void LCursor::bruteFind2(int x, int y)
lyxerr << "i: " << i << " d: " << d << " best: " << best_dist << endl;
if (d <= best_dist) {
best_dist = d;
cursor_ = it;
setCursor(it, false);
}
if (it == et)
break;
increment(it);
}
}
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();
it.forwardPos();
}
}
@ -1498,7 +1223,7 @@ CursorSlice LCursor::normalAnchor()
}
//lyx::BOOST_ASSERT(Anchor_.size() >= cursor.depth());
// use Anchor on the same level as Cursor
CursorSlice normal = anchor_[current_];
CursorSlice normal = anchor_[size() - 1];
#if 0
if (depth() < anchor_.size() && !(normal < xx())) {
// 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_RELEASE:
case LFUN_MOUSE_DOUBLE: {
CursorSlice & pos = cursor_.back();
CursorSlice & pos = back();
int x = 0;
int y = 0;
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
{
bv().owner()->getLyXFunc().setMessage(msg);
@ -1705,7 +1388,7 @@ string LCursor::getPossibleLabel()
}
void LCursor::notdispatched()
void LCursor::undispatched()
{
disp_.dispatched(false);
}
@ -1717,7 +1400,13 @@ void LCursor::dispatched(dispatch_result_t res)
}
void LCursor::noupdate()
void LCursor::noUpdate()
{
disp_.update(false);
}
void LCursor::noPop()
{
nopop_ = true;
}

View File

@ -12,23 +12,17 @@
#ifndef CURSOR_H
#define CURSOR_H
#include "cursor_slice.h"
#include "dispatchresult.h"
#include "dociterator.h"
#include <iosfwd>
#include <vector>
class BufferView;
class UpdatableInset;
class MathAtom;
class DispatchResult;
class FuncStatus;
class FuncRequest;
class InsetTabular;
class LyXText;
class Paragraph;
class Row;
// these should go
class MathHullInset;
@ -36,40 +30,14 @@ class MathUnknownInset;
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.
*/
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:
/// 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
explicit LCursor(BufferView & bv);
@ -88,16 +56,8 @@ public:
bool popLeft();
/// pop one slice off the cursor stack and go right
bool popRight();
/// restrict cursor nesting to given size
void pop(int depth);
/// 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_; }
/// sets cursor part
void setCursor(DocumentIterator const & it, bool sel);
//
// selection
@ -113,7 +73,7 @@ public:
///
void setSelection();
/// set selection at given position
void setSelection(CursorBase const & where, size_t n);
void setSelection(DocumentIterator const & where, size_t n);
///
void clearSelection();
/// access start of selection
@ -154,70 +114,6 @@ public:
///
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
bool autocorrect() const { return autocorrect_; }
/// auto-correct mode
@ -226,31 +122,6 @@ public:
bool macromode() const { return macromode_; }
/// are we entering a macro name?
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
void getPos(int & x, int & y) const;
/// returns cursor dimension
@ -288,7 +159,7 @@ public:
void resetAnchor();
/// access to owning BufferView
BufferView & bv() const;
/// get some interesting description of current position
/// get some interesting description of top position
void info(std::ostream & os) const;
/// are we in math mode (2), text mode (1) or unsure (0)?
int currentMode();
@ -298,28 +169,26 @@ public:
void replaceWord(std::string const & replacestring);
/// update our view
void update();
///
/// set dispatch result
void dispatched(dispatch_result_t res);
void notdispatched();
void noupdate();
/// assume event was not (yet) dispatched
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
friend std::ostream & operator<<(std::ostream & os, LCursor const & cur);
public:
//private:
/// mainly used as stack, but wee need random access
std::vector<CursorSlice> cursor_;
/// the anchor position
std::vector<CursorSlice> anchor_;
DocumentIterator anchor_;
///
DispatchResult disp_;
private:
///
BufferView * bv_;
/// current slice
int current_;
///
int cached_y_;
/**
@ -339,6 +208,8 @@ private:
bool selection_;
// are we on the way to get one?
bool mark_;
///
bool nopop_;
//
// math specific stuff that could be promoted to "global" later
@ -389,7 +260,7 @@ public:
void adjust(pos_type from, int diff);
///
MathHullInset * formula() const;
/// current offset in the current cell
/// current offset in the top cell
/// interpret name a name of a macro
void macroModeClose();
/// are we currently typing the name of a macro?
@ -419,9 +290,6 @@ public:
/// returns the normalized anchor of the selection
CursorSlice normalAnchor();
/// lock/unlock inset
void lockToggle();
/// hack for reveal codes
void markInsert();
void markErase();
@ -430,11 +298,6 @@ public:
/// split font inset etc
void handleFont(std::string const & font);
/// are we in mathed?
bool inMathed() const;
/// are we in texted?
bool inTexted() const;
/// display a message
void message(std::string const & msg) const;
/// 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)
{
os
// << "inset: " << item.inset_
<< "inset: " << item.inset_
// << " text: " << item.text()
<< " idx: " << item.idx_
<< " 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

@ -470,7 +470,7 @@ unsigned int packedcolor(LColor::color col)
bool const success = getRGBColor(col, r, g, b);
if (!success)
// Set to black on failure
return FL_PACK(255,255,255);
return FL_PACK(255, 255, 255);
return FL_PACK(r, g, b);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -390,7 +390,7 @@ int replace(BufferView * bv, string const & searchstr,
text->replaceSelectionWithString(bv->cursor(), replacestr);
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();
find(bv, searchstr, cs, mw, fw);
bv->update();

View File

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

View File

@ -412,6 +412,13 @@ public:
/// our 'outermost' 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:
/// 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")
swapCol(col(cur.idx()));
else {
cur.notdispatched();
cur.undispatched();
return;
}
lyxerr << "returning FINISHED_LEFT" << endl;

View File

@ -1070,7 +1070,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str,
#warning pretty ugly
#endif
static MathHullInset * lastformula = 0;
static CursorBase current = CursorBase(ibegin(nucleus()));
static CursorBase current = DocumentIterator(ibegin(nucleus()));
static MathArray ar;
static string laststr;
@ -1086,7 +1086,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str,
}
//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();
MathArray const & a = top.asMathInset()->cell(top.idx_);
if (a.matchpart(ar, top.pos_)) {

View File

@ -384,24 +384,20 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
break;
case LFUN_FINISHED_LEFT:
cur.pop(cur.currentDepth());
cur.bv().cursor() = cur;
break;
case LFUN_FINISHED_RIGHT:
cur.pop(cur.currentDepth());
++cur.pos();
cur.bv().cursor() = cur;
break;
case LFUN_FINISHED_UP:
cur.pop(cur.currentDepth());
//idxUpDown(cur, true);
cur.bv().cursor() = cur;
break;
case LFUN_FINISHED_DOWN:
cur.pop(cur.currentDepth());
//idxUpDown(cur, false);
cur.bv().cursor() = cur;
break;
@ -554,7 +550,15 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
break;
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;
case LFUN_SELFINSERT:
@ -780,7 +784,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
cur.insert(ar);
break;
}
cur.notdispatched();
cur.undispatched();
break;
}
@ -790,7 +794,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
case LFUN_WORD_REPLACE:
case LFUN_WORD_FIND:
if (!searchForward(&cur.bv(), cmd.getArg(0), false, false))
cur.notdispatched();
cur.undispatched();
break;
cur.normalize();
@ -876,7 +880,7 @@ void MathNestInset::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd)
return;
}
cur.notdispatched();
cur.undispatched();
}
@ -914,9 +918,7 @@ void MathNestInset::lfunMouseMotion(LCursor & cur, FuncRequest const & cmd)
cur.selBegin();
//cur.setScreenPos(cmd.x + xo_, cmd.y + yo_);
cur.bv().cursor().cursor_ = cur.cursor_;
cur.bv().cursor().selection() = true;
return;
cur.bv().cursor().setCursor(cur, true);
}

View File

@ -61,36 +61,35 @@ void RefInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
MathArray ar;
if (createMathInset_fromDialogStr(cmd.argument, ar)) {
*this = *ar[0].nucleus()->asRefInset();
return;
break;
}
}
cur.notdispatched();
return;
cur.undispatched();
break;
case LFUN_MOUSE_RELEASE:
if (cmd.button() == mouse_button::button3) {
lyxerr << "trying to goto ref" << cell(0) << endl;
cur.bv().dispatch(FuncRequest(LFUN_REF_GOTO, asString(cell(0))));
return;
break;
}
if (cmd.button() == mouse_button::button1) {
// Eventually trigger dialog with button 3
// not 1
// Eventually trigger dialog with button 3, not 1
string const data = createDialogStr("ref");
cur.bv().owner()->getDialogs().show("ref", data, this);
return;
break;
}
cur.notdispatched();
return;
cur.undispatched();
break;
case LFUN_MOUSE_PRESS:
case LFUN_MOUSE_MOTION:
// eat other mouse commands
return;
break;
default:
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)
{
BOOST_ASSERT(this == cur.text());
CursorSlice from = cur.current();
CursorSlice to = cur.current();
CursorSlice from = cur.top();
CursorSlice to = cur.top();
getWord(from, to, loc);
if (cur.current() != from)
if (cur.top() != from)
setCursor(cur, from.par(), from.pos());
if (to == from)
return;
@ -1340,9 +1340,9 @@ void LyXText::Delete(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
// just move to the right, if we had success make a backspace
CursorSlice sl = cur.current();
CursorSlice sl = cur.top();
cursorRight(cur);
if (sl == cur.current()) {
if (sl == cur.top()) {
recordUndo(cur, Undo::DELETE, cur.par(), max(0, cur.par() - 1));
backspace(cur);
}
@ -1820,9 +1820,9 @@ int LyXText::cursorX(CursorSlice const & cur) const
ParagraphList::iterator pit = getPar(cur);
if (pit->rows.empty())
return xo_;
Row const & row = *pit->getRow(cur.pos());
pos_type pos = cur.pos();
pos_type cursor_vpos = 0;
@ -1894,7 +1894,7 @@ CursorSlice & LyXText::cursor()
<< "\nthis: " << this << endl;
BOOST_ASSERT(false);
}
return bv()->cursor().current();
return bv()->cursor().top();
}
@ -1906,7 +1906,7 @@ CursorSlice const & LyXText::cursor() const
<< "\nthis: " << this << endl;
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;
}
// ok we have a selection.
// Ok, we have a selection.
recordUndoSelection(cur);
freezeUndo();
ParagraphList::iterator beg = getPar(cur.selBegin().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);
}
unFreezeUndo();
redoParagraphs(beg, ++end);
}
@ -486,7 +483,7 @@ void LyXText::toggleFree(LCursor & cur, LyXFont const & font, bool toggleall)
// Try implicit word selection
// If there is a change in the language the implicit word selection
// is disabled.
CursorSlice resetCursor = cur.current();
CursorSlice resetCursor = cur.top();
bool implicitSelection =
font.language() == ignore_language
&& 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.
if (implicitSelection) {
cur.clearSelection();
cur.current() = resetCursor;
cur.top() = resetCursor;
cur.resetAnchor();
}
}
@ -511,7 +508,7 @@ string LyXText::getStringToIndex(LCursor & cur)
// Try implicit word selection
// If there is a change in the language the implicit word selection
// is disabled.
CursorSlice const reset_cursor = cur.current();
CursorSlice const reset_cursor = cur.top();
bool const implicitSelection =
selectWordWhenUnderCursor(cur, lyx::PREVIOUS_WORD);
@ -524,7 +521,7 @@ string LyXText::getStringToIndex(LCursor & cur)
idxstring = cur.selectionAsString(false);
// Reset cursors to their original position.
cur.current() = reset_cursor;
cur.top() = reset_cursor;
cur.resetAnchor();
// 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 setfont, bool boundary)
{
CursorSlice old_cursor = cur.current();
CursorSlice old_cursor = cur.top();
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,
par_type par, pos_type pos, bool setfont, bool boundary)
{
setCursor(cur.current(), par, pos, boundary);
cur.x_target() = cursorX(cur.current());
setCursor(cur.top(), par, pos, boundary);
cur.x_target() = cursorX(cur.top());
if (setfont)
setCurrentFont(cur);
}
@ -1298,7 +1295,7 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int x, int y)
{
x -= xo_;
y -= yo_;
CursorSlice old_cursor = cur.current();
CursorSlice old_cursor = cur.top();
ParagraphList::iterator pit;
Row const & row = *getRowNearY(y, pit);
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.pos() = pos;
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();
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);
if (!cur.selection()) {
@ -1417,7 +1414,7 @@ void LyXText::cursorDown(LCursor & cur)
{
Row const & row = cur.textRow();
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);
if (!cur.selection()) {

View File

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

View File

@ -27,27 +27,15 @@
using lyx::paroffset_type;
/// The flag used by finishUndo().
bool undo_finished;
namespace {
/// Whether actions are not added to the undo stacks.
bool undo_frozen;
Undo::Undo(undo_kind kind_, int text_, int index_,
int first_par_, int end_par_, int cursor_par_, int cursor_pos_)
:
kind(kind_),
text(text_),
index(index_),
first_par(first_par_),
end_par(end_par_),
cursor_par(cursor_par_),
cursor_pos(cursor_pos_)
{}
/// The flag used by finishUndo().
bool undo_finished;
namespace {
std::ostream & operator<<(std::ostream & os, Undo const & undo)
{
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,
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) {
paroffset_type t = first_par;
first_par = last_par;
@ -121,27 +118,39 @@ void recordUndo(Undo::undo_kind kind,
}
}
// make and push the Undo entry
int textnum;
LyXText * text = cur.text();
BOOST_ASSERT(text); // not in mathed (yet)
ParIterator pit = text2pit(buf, text, textnum);
stack.push(Undo(kind, textnum, pit.index(),
first_par, end_par, cur.par(), cur.pos()));
//lyxerr << "undo record: " << stack.top() << std::endl;
// push and fill the Undo entry
if (cur.inTexted()) {
stack.push(Undo());
LyXText * text = cur.text();
int textnum;
ParIterator pit = text2pit(buf, text, textnum);
Undo & undo = stack.top();
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;
// record the relevant paragraphs
ParagraphList & undo_pars = stack.top().pars;
// record the relevant paragraphs
ParagraphList & plist = text->paragraphs();
ParagraphList::iterator first = plist.begin();
advance(first, first_par);
ParagraphList::iterator last = plist.begin();
advance(last, last_par);
ParagraphList & plist = text->paragraphs();
ParagraphList::iterator first = plist.begin();
advance(first, first_par);
ParagraphList::iterator last = plist.begin();
advance(last, last_par);
for (ParagraphList::iterator it = first; it != last; ++it)
undo_pars.push_back(*it);
undo_pars.push_back(*last);
for (ParagraphList::iterator it = first; it != last; ++it)
undo.pars.push_back(*it);
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
undo_finished = false;

View File

@ -19,6 +19,8 @@
#include "ParagraphList_fwd.h"
#include "support/types.h"
#include <string>
class LCursor;
class BufferView;
@ -28,8 +30,7 @@ class BufferView;
* contains complete paragraphs and sufficient information
* to restore the state.
*/
class Undo {
public:
struct Undo {
/// This is used to combine consecutive undo recordings of the same kind.
enum undo_kind {
/**
@ -46,11 +47,6 @@ public:
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?
undo_kind kind;
/// hosting LyXText counted from buffer begin
@ -65,8 +61,12 @@ public:
int cursor_par;
/// the position of the cursor in the hosting paragraph
int cursor_pos;
/// the contents of the paragraphs saved
/// the contents of the saved paragraphs (for texted)
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
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();
/// 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
void recordUndoFullDocument(LCursor & cur);
/// are we avoiding tracking undos currently?
extern bool undo_frozen;
#endif // UNDO_FUNCS_H