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 LCursor & cur = bv.cursor();
42 BOOST_ASSERT(cur.inTexted());
43 LyXText * text = cur.text();
44 lyx::pos_type pos = cur.pos();
45 ParagraphList::iterator pit = text->getPar(cur.par());
47 ParIterator par = bv.buffer()->par_iterator_begin();
48 ParIterator end = bv.buffer()->par_iterator_end();
49 for (; par != end; ++par) {
57 PosIterator::PosIterator(ParIterator const & par, lyx::pos_type pos)
63 void PosIterator::setFrom(ParIterator const & par, lyx::pos_type pos)
65 BOOST_ASSERT(par.size() > 0);
67 ParIterator::PosHolder const & ph = par.positions();
69 int const last = par.size() - 1;
70 for (int i = 0; i < last; ++i) {
71 ParPosition const & pp = ph[i];
73 PosIteratorItem(const_cast<ParagraphList *>(pp.plist),
74 pp.pit, (*pp.it)->pos, *pp.index + 1));
76 ParPosition const & pp = ph[last];
78 PosIteratorItem(const_cast<ParagraphList *>(pp.plist), pp.pit, pos, 0));
82 PosIterator & PosIterator::operator++()
84 BOOST_ASSERT(!stack_.empty());
86 PosIteratorItem & p = stack_.back();
88 if (p.pos < p.pit->size()) {
89 if (InsetBase * inset = p.pit->getInset(p.pos)) {
90 if (LyXText * text = inset->getText(p.index)) {
91 ParagraphList & pl = text->paragraphs();
93 stack_.push_back(PosIteratorItem(&pl, pl.begin(), 0));
104 if (p.pit != p.pl->end() || stack_.size() == 1)
113 PosIterator & PosIterator::operator--()
115 BOOST_ASSERT(!stack_.empty());
117 // try to go one position backwards: if on the start of the
118 // ParagraphList, pops an item
119 PosIteratorItem & p = stack_.back();
122 InsetBase * inset = p.pit->getInset(p.pos);
124 p.index = inset->nargs();
126 if (p.pit == p.pl->begin()) {
127 if (stack_.size() == 1)
130 --stack_.back().index;
133 p.pos = p.pit->size();
136 // try to push an item if there is some left unexplored
137 PosIteratorItem & q = stack_.back();
138 if (q.pos < q.pit->size()) {
139 InsetBase * inset = q.pit->getInset(q.pos);
140 if (inset && q.index > 0) {
141 LyXText * text = inset->getText(q.index - 1);
143 ParagraphList & pl = text->paragraphs();
144 stack_.push_back(PosIteratorItem(&pl, prior(pl.end()), pl.back().size()));
151 bool operator==(PosIterator const & lhs, PosIterator const & rhs)
153 PosIteratorItem const & li = lhs.stack_.back();
154 PosIteratorItem const & ri = rhs.stack_.back();
156 return (li.pl == ri.pl && li.pit == ri.pit &&
157 (li.pit == li.pl->end() || li.pos == ri.pos));
161 bool PosIterator::at_end() const
163 return pos() == pit()->size();
167 InsetBase * PosIterator::inset() const
169 if (stack_.size() == 1)
171 PosIteratorItem const & pi = stack_[stack_.size() - 2];
172 return pi.pit->getInset(pi.pos);