2003-11-02 17:56:26 +00:00
|
|
|
/* \file PosIterator.C
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Alfredo Braunstein
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "PosIterator.h"
|
|
|
|
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "BufferView.h"
|
|
|
|
#include "iterators.h"
|
|
|
|
#include "lyxtext.h"
|
|
|
|
#include "paragraph.h"
|
|
|
|
|
|
|
|
#include "insets/insettext.h"
|
|
|
|
#include "insets/updatableinset.h"
|
|
|
|
#include "insets/inset.h"
|
|
|
|
|
|
|
|
#include <boost/next_prior.hpp>
|
|
|
|
|
|
|
|
using boost::prior;
|
|
|
|
|
|
|
|
PosIterator & PosIterator::operator++()
|
|
|
|
{
|
|
|
|
BOOST_ASSERT(!stack_.empty());
|
|
|
|
while (true) {
|
2003-11-07 09:40:49 +00:00
|
|
|
PosIteratorItem & p = stack_.back();
|
2003-11-02 17:56:26 +00:00
|
|
|
|
|
|
|
if (p.pos < p.pit->size()) {
|
|
|
|
InsetOld * inset = p.pit->getInset(p.pos);
|
|
|
|
if (inset) {
|
|
|
|
ParagraphList * pl = inset->getParagraphs(p.index);
|
|
|
|
if (pl) {
|
|
|
|
p.index++;
|
2003-11-07 09:40:49 +00:00
|
|
|
stack_.push_back(PosIteratorItem(pl, pl->begin(), 0));
|
2003-11-02 17:56:26 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p.index = 0;
|
|
|
|
++p.pos;
|
|
|
|
} else {
|
|
|
|
++p.pit;
|
|
|
|
p.pos = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p.pit != p.pl->end() || stack_.size() == 1)
|
|
|
|
return *this;
|
|
|
|
|
2003-11-07 09:40:49 +00:00
|
|
|
stack_.pop_back();
|
2003-11-02 17:56:26 +00:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PosIterator & PosIterator::operator--()
|
|
|
|
{
|
|
|
|
BOOST_ASSERT(!stack_.empty());
|
|
|
|
|
|
|
|
// try to go one position backwards: if on the start of the
|
|
|
|
// ParagraphList, pops an item
|
2003-11-07 09:40:49 +00:00
|
|
|
PosIteratorItem & p = stack_.back();
|
2003-11-02 17:56:26 +00:00
|
|
|
if (p.pos > 0) {
|
|
|
|
--p.pos;
|
|
|
|
InsetOld * inset = p.pit->getInset(p.pos);
|
|
|
|
if (inset)
|
|
|
|
p.index = inset->numParagraphs();
|
|
|
|
} else {
|
|
|
|
if (p.pit == p.pl->begin()) {
|
|
|
|
if (stack_.size() == 1)
|
|
|
|
return *this;
|
2003-11-07 09:40:49 +00:00
|
|
|
stack_.pop_back();
|
|
|
|
--stack_.back().index;
|
2003-11-02 17:56:26 +00:00
|
|
|
} else {
|
|
|
|
--p.pit;
|
|
|
|
p.pos = p.pit->size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// try to push an item if there is some left unexplored
|
2003-11-07 09:40:49 +00:00
|
|
|
PosIteratorItem & q = stack_.back();
|
2003-11-02 17:56:26 +00:00
|
|
|
if (q.pos < q.pit->size()) {
|
|
|
|
InsetOld * inset = q.pit->getInset(q.pos);
|
|
|
|
if (inset && q.index > 0) {
|
|
|
|
ParagraphList *
|
|
|
|
pl = inset->getParagraphs(q.index - 1);
|
|
|
|
BOOST_ASSERT(pl);
|
2003-11-07 09:40:49 +00:00
|
|
|
stack_.push_back(PosIteratorItem(pl, prior(pl->end()), pl->back().size()));
|
2003-11-02 17:56:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator!=(PosIterator const & lhs, PosIterator const & rhs)
|
|
|
|
{
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator==(PosIterator const & lhs, PosIterator const & rhs)
|
|
|
|
{
|
|
|
|
|
2003-11-07 09:40:49 +00:00
|
|
|
PosIteratorItem const & li = lhs.stack_.back();
|
|
|
|
PosIteratorItem const & ri = rhs.stack_.back();
|
2003-11-02 17:56:26 +00:00
|
|
|
|
|
|
|
return (li.pl == ri.pl && li.pit == ri.pit &&
|
|
|
|
(li.pit == li.pl->end() || li.pos == ri.pos));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool PosIterator::at_end() const
|
|
|
|
{
|
|
|
|
return pos() == pit()->size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
|
|
|
|
lyx::pos_type pos)
|
|
|
|
{
|
2003-11-07 09:40:49 +00:00
|
|
|
stack_.push_back(PosIteratorItem(pl, pit, pos));
|
2003-11-02 17:56:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PosIterator::PosIterator(BufferView & bv)
|
|
|
|
{
|
|
|
|
LyXText * text = bv.getLyXText();
|
|
|
|
lyx::pos_type pos = text->cursor.pos();
|
|
|
|
ParagraphList::iterator pit = text->cursorPar();
|
|
|
|
|
|
|
|
ParIterator par = bv.buffer()->par_iterator_begin();
|
|
|
|
ParIterator end = bv.buffer()->par_iterator_end();
|
|
|
|
for ( ; par != end; ++par) {
|
|
|
|
if (par.pit() == pit)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
operator=(par.asPosIterator(pos));
|
|
|
|
}
|
2003-11-03 09:23:23 +00:00
|
|
|
|
|
|
|
|
2003-11-07 09:40:49 +00:00
|
|
|
InsetOld * PosIterator::inset() const
|
|
|
|
{
|
|
|
|
if (stack_.size() == 1)
|
|
|
|
return 0;
|
|
|
|
PosIteratorItem const & pi = stack_[stack_.size() - 2];
|
|
|
|
return pi.pit->getInset(pi.pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-03 09:23:23 +00:00
|
|
|
int distance(PosIterator const & cur, PosIterator const & end)
|
|
|
|
{
|
|
|
|
PosIterator p = cur;
|
|
|
|
int count = 0;
|
|
|
|
for (; p != end; ++p, ++count);
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void advance(PosIterator & cur, int howmuch)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < howmuch; ++i)
|
|
|
|
++cur;
|
|
|
|
for (int i = 0; i > howmuch; --i)
|
|
|
|
--cur;
|
|
|
|
}
|