start work on less-likely-to-misuse iterators.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22898 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2008-02-09 15:23:05 +00:00
parent 74632f681e
commit 24fdfc7d5e
9 changed files with 52 additions and 81 deletions

View File

@ -1485,60 +1485,37 @@ bool Buffer::isMultiLingual() const
} }
ParConstIterator Buffer::getParFromID(int const id) const DocIterator Buffer::getParFromID(int const id) const
{ {
ParConstIterator it = par_iterator_begin();
ParConstIterator const end = par_iterator_end();
if (id < 0) { if (id < 0) {
// John says this is called with id == -1 from undo // John says this is called with id == -1 from undo
lyxerr << "getParFromID(), id: " << id << endl; lyxerr << "getParFromID(), id: " << id << endl;
return end; return doc_iterator_end(inset());
} }
for (; it != end; ++it) for (DocIterator it = doc_iterator_begin(inset()); !it.atEnd(); it.forwardPar())
if (it->id() == id) if (it.paragraph().id() == id)
return it; return it;
return end; return doc_iterator_end(inset());
}
ParIterator Buffer::getParFromID(int const id)
{
ParIterator it = par_iterator_begin();
ParIterator const end = par_iterator_end();
if (id < 0) {
// John says this is called with id == -1 from undo
lyxerr << "getParFromID(), id: " << id << endl;
return end;
}
for (; it != end; ++it)
if (it->id() == id)
return it;
return end;
} }
bool Buffer::hasParWithID(int const id) const bool Buffer::hasParWithID(int const id) const
{ {
ParConstIterator const it = getParFromID(id); return !getParFromID(id).atEnd();
return it != par_iterator_end();
} }
ParIterator Buffer::par_iterator_begin() ParIterator Buffer::par_iterator_begin()
{ {
return lyx::par_iterator_begin(inset()); return ParIterator(doc_iterator_begin(inset()));
} }
ParIterator Buffer::par_iterator_end() ParIterator Buffer::par_iterator_end()
{ {
return lyx::par_iterator_end(inset()); return ParIterator(doc_iterator_end(inset()));
} }
@ -2010,8 +1987,8 @@ void Buffer::updateMacroInstances() const
{ {
LYXERR(Debug::MACROS, "updateMacroInstances for " LYXERR(Debug::MACROS, "updateMacroInstances for "
<< d->filename.onlyFileName()); << d->filename.onlyFileName());
ParConstIterator it = par_iterator_begin(); DocIterator it = doc_iterator_begin(inset());
ParConstIterator end = par_iterator_end(); DocIterator end = doc_iterator_end(inset());
for (; it != end; it.forwardPos()) { for (; it != end; it.forwardPos()) {
// look for MathData cells in InsetMathNest insets // look for MathData cells in InsetMathNest insets
Inset * inset = it.nextInset(); Inset * inset = it.nextInset();

View File

@ -144,9 +144,7 @@ public:
pit_type &, pos_type &, pit_type &, pos_type &,
Font const &, docstring const &, bool); Font const &, docstring const &, bool);
/// ///
ParIterator getParFromID(int id); DocIterator getParFromID(int id) const;
///
ParConstIterator getParFromID(int id) const;
/// do we have a paragraph with this id? /// do we have a paragraph with this id?
bool hasParWithID(int id) const; bool hasParWithID(int id) const;

View File

@ -429,7 +429,7 @@ void BufferView::updateScrollbar()
<< " curr par: " << d->cursor_.bottom().pit() << " curr par: " << d->cursor_.bottom().pit()
<< " default height " << defaultRowHeight()); << " default height " << defaultRowHeight());
int const parsize = int(t.paragraphs().size()); size_t const parsize = t.paragraphs().size();
if (d->par_height_.size() != parsize) { if (d->par_height_.size() != parsize) {
d->par_height_.clear(); d->par_height_.clear();
// FIXME: We assume a default paragraph height of 2 rows. This // FIXME: We assume a default paragraph height of 2 rows. This
@ -449,7 +449,7 @@ void BufferView::updateScrollbar()
int top_pos = first.second->position() - first.second->ascent(); int top_pos = first.second->position() - first.second->ascent();
int bottom_pos = last.second->position() + last.second->descent(); int bottom_pos = last.second->position() + last.second->descent();
bool first_visible = first.first == 0 && top_pos >= 0; bool first_visible = first.first == 0 && top_pos >= 0;
bool last_visible = last.first == parsize - 1 && bottom_pos <= height_; bool last_visible = last.first + 1 == int(parsize) && bottom_pos <= height_;
if (first_visible && last_visible) { if (first_visible && last_visible) {
d->scrollbarParameters_.min = 0; d->scrollbarParameters_.min = 0;
d->scrollbarParameters_.max = 0; d->scrollbarParameters_.max = 0;
@ -457,7 +457,7 @@ void BufferView::updateScrollbar()
} }
d->scrollbarParameters_.min = top_pos; d->scrollbarParameters_.min = top_pos;
for (size_t i = 0; i != first.first; ++i) for (size_t i = 0; i != size_t(first.first); ++i)
d->scrollbarParameters_.min -= d->par_height_[i]; d->scrollbarParameters_.min -= d->par_height_[i];
d->scrollbarParameters_.max = bottom_pos; d->scrollbarParameters_.max = bottom_pos;
for (size_t i = last.first + 1; i != parsize; ++i) for (size_t i = last.first + 1; i != parsize; ++i)
@ -527,7 +527,7 @@ void BufferView::scrollDocView(int value)
// find paragraph at target position // find paragraph at target position
int par_pos = d->scrollbarParameters_.min; int par_pos = d->scrollbarParameters_.min;
pit_type i = 0; pit_type i = 0;
for (; i != d->par_height_.size(); ++i) { for (; i != int(d->par_height_.size()); ++i) {
par_pos += d->par_height_[i]; par_pos += d->par_height_[i];
if (par_pos >= value) if (par_pos >= value)
break; break;
@ -631,7 +631,7 @@ bool BufferView::moveToPosition(pit_type bottom_pit, pos_type bottom_pos,
int top_id, pos_type top_pos) int top_id, pos_type top_pos)
{ {
bool success = false; bool success = false;
DocIterator doc_it; DocIterator dit;
d->cursor_.clearSelection(); d->cursor_.clearSelection();
@ -639,19 +639,19 @@ bool BufferView::moveToPosition(pit_type bottom_pit, pos_type bottom_pos,
// This is the case for a 'live' bookmark when unique paragraph ID // This is the case for a 'live' bookmark when unique paragraph ID
// is used to track bookmarks. // is used to track bookmarks.
if (top_id > 0) { if (top_id > 0) {
ParIterator par = buffer_.getParFromID(top_id); dit = buffer_.getParFromID(top_id);
if (par != buffer_.par_iterator_end()) { if (!dit.atEnd()) {
doc_it = makeDocIterator(par, min(par->size(), top_pos)); dit.pos() = min(dit.paragraph().size(), top_pos);
// Some slices of the iterator may not be // Some slices of the iterator may not be
// reachable (e.g. closed collapsable inset) // reachable (e.g. closed collapsable inset)
// so the dociterator may need to be // so the dociterator may need to be
// shortened. Otherwise, setCursor may crash // shortened. Otherwise, setCursor may crash
// lyx when the cursor can not be set to these // lyx when the cursor can not be set to these
// insets. // insets.
size_t const n = doc_it.depth(); size_t const n = dit.depth();
for (size_t i = 0; i < n; ++i) for (size_t i = 0; i < n; ++i)
if (doc_it[i].inset().editable() != Inset::HIGHLY_EDITABLE) { if (dit[i].inset().editable() != Inset::HIGHLY_EDITABLE) {
doc_it.resize(i); dit.resize(i);
break; break;
} }
success = true; success = true;
@ -664,16 +664,17 @@ bool BufferView::moveToPosition(pit_type bottom_pit, pos_type bottom_pos,
// restoration is inaccurate. If a bookmark was within an inset, // restoration is inaccurate. If a bookmark was within an inset,
// it will be restored to the left of the outmost inset that contains // it will be restored to the left of the outmost inset that contains
// the bookmark. // the bookmark.
if (static_cast<size_t>(bottom_pit) < buffer_.paragraphs().size()) { if (bottom_pit < int(buffer_.paragraphs().size())) {
doc_it = doc_iterator_begin(buffer_.inset()); dit = doc_iterator_begin(buffer_.inset());
doc_it.pit() = bottom_pit;
doc_it.pos() = min(bottom_pos, doc_it.paragraph().size()); dit.pit() = bottom_pit;
dit.pos() = min(bottom_pos, dit.paragraph().size());
success = true; success = true;
} }
if (success) { if (success) {
// Note: only bottom (document) level pit is set. // Note: only bottom (document) level pit is set.
setCursor(doc_it); setCursor(dit);
// set the current font. // set the current font.
d->cursor_.setCurrentFont(); d->cursor_.setCurrentFont();
// To center the screen on this new position we need the // To center the screen on this new position we need the
@ -997,17 +998,17 @@ bool BufferView::dispatch(FuncRequest const & cmd)
for (Buffer * b = &buffer_; i == 0 || b != &buffer_; for (Buffer * b = &buffer_; i == 0 || b != &buffer_;
b = theBufferList().next(b)) { b = theBufferList().next(b)) {
ParIterator par = b->getParFromID(id); DocIterator dit = b->getParFromID(id);
if (par == b->par_iterator_end()) { if (dit.atEnd()) {
LYXERR(Debug::INFO, "No matching paragraph found! [" << id << "]."); LYXERR(Debug::INFO, "No matching paragraph found! [" << id << "].");
} else { } else {
LYXERR(Debug::INFO, "Paragraph " << par->id() LYXERR(Debug::INFO, "Paragraph " << dit.paragraph().id()
<< " found in buffer `" << " found in buffer `"
<< b->absFileName() << "'."); << b->absFileName() << "'.");
if (b == &buffer_) { if (b == &buffer_) {
// Set the cursor // Set the cursor
setCursor(makeDocIterator(par, 0)); setCursor(dit);
showCursor(); showCursor();
} else { } else {
// Switch to other buffer view and resend cmd // Switch to other buffer view and resend cmd
@ -1672,9 +1673,9 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select)
// For an example, see bug 2933: // For an example, see bug 2933:
// http://bugzilla.lyx.org/show_bug.cgi?id=2933 // http://bugzilla.lyx.org/show_bug.cgi?id=2933
// The code below could maybe be moved to a DocIterator method. // The code below could maybe be moved to a DocIterator method.
//lyxerr << "cur before " << cur <<endl; //lyxerr << "cur before " << cur << endl;
DocIterator dit(cur.inset()); DocIterator dit = doc_iterator_begin(cur.inset());
dit.push_back(cur.bottom()); dit.bottom() = cur.bottom();
size_t i = 1; size_t i = 1;
while (i < cur.depth() && dit.nextInset() == &cur[i].inset()) { while (i < cur.depth() && dit.nextInset() == &cur[i].inset()) {
dit.push_back(cur[i]); dit.push_back(cur[i]);

View File

@ -272,7 +272,8 @@ void Cursor::reset(Inset & inset)
{ {
clear(); clear();
push_back(CursorSlice(inset)); push_back(CursorSlice(inset));
anchor_ = DocIterator(inset); anchor_ = doc_iterator_begin(inset);
anchor_.clear();
clearTargetX(); clearTargetX();
selection_ = false; selection_ = false;
mark_ = false; mark_ = false;

View File

@ -23,6 +23,7 @@ class LyXErr;
class MathAtom; class MathAtom;
class Paragraph; class Paragraph;
class Text; class Text;
class InsetIterator;
// The public inheritance should go in favour of a suitable data member // The public inheritance should go in favour of a suitable data member
@ -40,8 +41,6 @@ public:
public: public:
/// ///
DocIterator(); DocIterator();
///
explicit DocIterator(Inset & inset);
/// access slice at position \p i /// access slice at position \p i
CursorSlice const & operator[](size_t i) const { return slices_[i]; } CursorSlice const & operator[](size_t i) const { return slices_[i]; }
@ -57,6 +56,8 @@ public:
/// does this iterator have any content? /// does this iterator have any content?
bool empty() const { return slices_.empty(); } bool empty() const { return slices_.empty(); }
/// is this the end position?
bool atEnd() const { return slices_.empty(); }
// //
// access to slice at tip // access to slice at tip
@ -224,6 +225,11 @@ public:
void append(idx_type idx, pos_type pos); void append(idx_type idx, pos_type pos);
private: private:
friend class InsetIterator;
friend DocIterator doc_iterator_begin(Inset & inset);
friend DocIterator doc_iterator_end(Inset & inset);
///
explicit DocIterator(Inset & inset);
/** /**
* Normally, when the cursor is at position i, it is painted *before* * Normally, when the cursor is at position i, it is painted *before*
* the character at position i. However, what if we want the cursor * the character at position i. However, what if we want the cursor

View File

@ -104,15 +104,6 @@ ParagraphList & ParIterator::plist() const
} }
DocIterator makeDocIterator(ParIterator const & par, pos_type pos)
{
DocIterator dit(par);
dit.pos() = pos;
return dit;
}
/// ///
/// ParConstIterator /// ParConstIterator
/// ///

View File

@ -71,8 +71,6 @@ public:
}; };
DocIterator makeDocIterator(ParIterator const &, pos_type);
ParIterator par_iterator_begin(Inset & inset); ParIterator par_iterator_begin(Inset & inset);
ParIterator par_iterator_end(Inset & inset); ParIterator par_iterator_end(Inset & inset);

View File

@ -109,21 +109,20 @@ void GuiErrorList::goTo(int item)
return; return;
Buffer & buf = buffer(); Buffer & buf = buffer();
ParIterator pit = buf.getParFromID(err.par_id); DocIterator dit = buf.getParFromID(err.par_id);
if (pit == buf.par_iterator_end()) { if (dit == doc_iterator_end(buf.inset())) {
LYXERR0("par id " << err.par_id << " not found"); LYXERR0("par id " << err.par_id << " not found");
return; return;
} }
// Now make the selection. // Now make the selection.
// This should be implemented using an LFUN. (Angus)
// if pos_end is 0, this means it is end-of-paragraph // if pos_end is 0, this means it is end-of-paragraph
pos_type const end = err.pos_end ? min(err.pos_end, pit->size()) pos_type const s = dit.paragraph().size();
: pit->size(); pos_type const end = err.pos_end ? min(err.pos_end, s) : s;
pos_type const start = min(err.pos_start, end); pos_type const start = min(err.pos_start, end);
pos_type const range = end - start; pos_type const range = end - start;
DocIterator const dit = makeDocIterator(pit, start); dit.pos() = start;
bufferview()->putSelectionAt(dit, range, false); bufferview()->putSelectionAt(dit, range, false);
// FIXME: If we used an LFUN, we would not need this line: // FIXME: If we used an LFUN, we would not need this line:
bufferview()->processUpdateFlags(Update::Force | Update::FitCursor); bufferview()->processUpdateFlags(Update::Force | Update::FitCursor);

View File

@ -333,8 +333,8 @@ void GuiSpellchecker::check()
ptrdiff_t start = 0; ptrdiff_t start = 0;
ptrdiff_t total = 0; ptrdiff_t total = 0;
DocIterator it = DocIterator(buffer().inset()); DocIterator it = doc_iterator_begin(buffer().inset());
for (start = 0; it != cur; it.forwardPos()) for (start = 1; it != cur; it.forwardPos())
++start; ++start;
for (total = start; it; it.forwardPos()) for (total = start; it; it.forwardPos())