2 * This file is part of LyX, the document processor.
3 * Licence details can be found in the file COPYING.
5 * \author Alfredo Braunstein
7 * Full author contact details are available in file CREDITS.
13 #include "PosIterator.h"
16 #include "BufferView.h"
18 #include "iterators.h"
20 #include "paragraph.h"
22 #include "insets/insettext.h"
23 #include "insets/updatableinset.h"
24 #include "insets/inset.h"
26 #include <boost/next_prior.hpp>
32 PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
35 stack_.push_back(PosIteratorItem(pl, pit, pos));
39 PosIterator::PosIterator(BufferView & bv)
41 LyXText * text = bv.getLyXText();
42 lyx::pos_type pos = text->cursor().pos();
43 ParagraphList::iterator pit = text->cursorPar();
45 ParIterator par = bv.buffer()->par_iterator_begin();
46 ParIterator end = bv.buffer()->par_iterator_end();
47 for (; par != end; ++par) {
55 PosIterator::PosIterator(ParIterator const & par, lyx::pos_type pos)
61 void PosIterator::setFrom(ParIterator const & par, lyx::pos_type pos)
63 BOOST_ASSERT(par.size() > 0);
65 ParIterator::PosHolder const & ph = par.positions();
67 int const last = par.size() - 1;
68 for (int i = 0; i < last; ++i) {
69 ParPosition const & pp = ph[i];
71 PosIteratorItem(const_cast<ParagraphList *>(pp.plist),
72 pp.pit, (*pp.it)->pos, *pp.index + 1));
74 ParPosition const & pp = ph[last];
76 PosIteratorItem(const_cast<ParagraphList *>(pp.plist), pp.pit, pos, 0));
80 PosIterator & PosIterator::operator++()
82 BOOST_ASSERT(!stack_.empty());
84 PosIteratorItem & p = stack_.back();
86 if (p.pos < p.pit->size()) {
87 if (InsetBase * inset = p.pit->getInset(p.pos)) {
88 if (LyXText * text = inset->getText(p.index)) {
89 ParagraphList & pl = text->paragraphs();
91 stack_.push_back(PosIteratorItem(&pl, pl.begin(), 0));
102 if (p.pit != p.pl->end() || stack_.size() == 1)
111 PosIterator & PosIterator::operator--()
113 BOOST_ASSERT(!stack_.empty());
115 // try to go one position backwards: if on the start of the
116 // ParagraphList, pops an item
117 PosIteratorItem & p = stack_.back();
120 InsetBase * inset = p.pit->getInset(p.pos);
122 p.index = inset->numParagraphs();
124 if (p.pit == p.pl->begin()) {
125 if (stack_.size() == 1)
128 --stack_.back().index;
131 p.pos = p.pit->size();
134 // try to push an item if there is some left unexplored
135 PosIteratorItem & q = stack_.back();
136 if (q.pos < q.pit->size()) {
137 InsetBase * inset = q.pit->getInset(q.pos);
138 if (inset && q.index > 0) {
139 LyXText * text = inset->getText(q.index - 1);
141 ParagraphList & pl = text->paragraphs();
142 stack_.push_back(PosIteratorItem(&pl, prior(pl.end()), pl.back().size()));
149 bool operator==(PosIterator const & lhs, PosIterator const & rhs)
151 PosIteratorItem const & li = lhs.stack_.back();
152 PosIteratorItem const & ri = rhs.stack_.back();
154 return (li.pl == ri.pl && li.pit == ri.pit &&
155 (li.pit == li.pl->end() || li.pos == ri.pos));
159 bool PosIterator::at_end() const
161 return pos() == pit()->size();
165 InsetBase * PosIterator::inset() const
167 if (stack_.size() == 1)
169 PosIteratorItem const & pi = stack_[stack_.size() - 2];
170 return pi.pit->getInset(pi.pos);