2 * This file is part of LyX, the document processor.
3 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * Full author contact details are available in file CREDITS.
14 #include "iterators.h"
15 #include "paragraph.h"
16 #include "PosIterator.h"
19 #include "BufferView.h"
20 #include "dispatchresult.h"
22 #include "insets/inset.h"
23 #include "insets/updatableinset.h"
24 #include "insets/insettext.h"
26 #include <boost/next_prior.hpp>
35 ParPosition::ParPosition(ParagraphList::iterator p, ParagraphList const & pl)
38 if (p != const_cast<ParagraphList&>(pl).end()) {
39 it.reset(p->insetlist.begin());
44 bool operator==(ParPosition const & pos1, ParPosition const & pos2)
46 return pos1.pit == pos2.pit;
50 bool operator!=(ParPosition const & pos1, ParPosition const & pos2)
52 return !(pos1 == pos2);
60 ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl)
62 positions_.push_back(ParPosition(pit, pl));
66 ParIterator::~ParIterator()
70 ParIterator::ParIterator(ParIterator const & pi)
71 : positions_(pi.positions_)
75 void ParIterator::operator=(ParIterator const & pi)
78 swap(positions_ , tmp.positions_);
82 ParIterator & ParIterator::operator++()
84 while (!positions_.empty()) {
85 ParPosition & p = positions_.back();
87 // Does the current inset contain more "cells" ?
90 if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
91 ParagraphList & plist = text->paragraphs();
93 positions_.push_back(ParPosition(plist.begin(), plist));
99 // The following line is needed because the value of
100 // p.it may be invalid if inset was added/removed to
101 // the paragraph pointed by the iterator
102 p.it.reset(p.pit->insetlist.begin());
105 // Try to find the next inset that contains paragraphs
106 InsetList::iterator end = p.pit->insetlist.end();
107 for (; *p.it != end; ++(*p.it)) {
108 if (LyXText * text = (*p.it)->inset->getText(0)) {
109 ParagraphList & plist = text->paragraphs();
110 if (!plist.empty()) {
112 positions_.push_back(ParPosition(plist.begin(), plist));
118 // Try to go to the next paragarph
119 if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
120 || positions_.size() == 1) {
128 // Drop end and move up in the stack.
129 positions_.pop_back();
135 LyXText * ParIterator::text(Buffer & buf) const
137 //lyxerr << "positions.size: " << positions.size() << std::endl;
138 if (positions_.size() <= 1)
141 ParPosition const & pos = positions_[positions_.size() - 2];
142 return (*pos.it)->inset->getText(*pos.index);
146 InsetBase * ParIterator::inset() const
148 //lyxerr << "positions.size: " << positions.size() << std::endl;
149 if (positions_.size() <= 1)
152 ParPosition const & pos = positions_[positions_.size() - 2];
153 return (*pos.it)->inset;
157 int ParIterator::index() const
159 if (positions_.size() <= 1)
162 return *(positions_[positions_.size() - 2].index);
166 Paragraph & ParIterator::operator*() const
168 return *positions_.back().pit;
172 ParagraphList::iterator ParIterator::pit() const
174 return positions_.back().pit;
178 ParagraphList::iterator ParIterator::operator->() const
180 return positions_.back().pit;
184 ParagraphList::iterator ParIterator::outerPar() const
186 return positions_[0].pit;
190 size_t ParIterator::size() const
192 return positions_.size();
196 ParagraphList & ParIterator::plist() const
198 return *const_cast<ParagraphList*>(positions_.back().plist);
202 ParIterator::ParIterator(PosIterator const & pos)
204 int const size = pos.stack_.size();
206 for (int i = 0; i < size; ++i) {
207 PosIteratorItem const & it = pos.stack_[i];
208 ParPosition pp(it.pit, *it.pl);
210 InsetBase * inset = it.pit->getInset(it.pos);
212 InsetList::iterator beg = it.pit->insetlist.begin();
213 InsetList::iterator end = it.pit->insetlist.end();
214 for ( ; beg != end && beg->inset != inset; ++beg)
217 pp.index.reset(it.index - 1);
219 positions_.push_back(pp);
224 bool operator==(ParIterator const & iter1, ParIterator const & iter2)
226 return iter1.positions() == iter2.positions();
230 bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
232 return !(iter1 == iter2);
241 ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
242 ParagraphList const & pl)
244 positions_.push_back(ParPosition(pit, pl));
248 ParConstIterator::~ParConstIterator()
252 ParConstIterator::ParConstIterator(ParConstIterator const & pi)
253 : positions_(pi.positions_)
257 ParConstIterator & ParConstIterator::operator++()
259 while (!positions_.empty()) {
260 ParPosition & p = positions_.back();
262 // Does the current inset contain more "cells" ?
265 if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
266 ParagraphList & plist = text->paragraphs();
267 if (!plist.empty()) {
268 positions_.push_back(ParPosition(plist.begin(), plist));
274 // The following line is needed because the value of
275 // p.it may be invalid if inset was added/removed to
276 // the paragraph pointed by the iterator
277 p.it.reset(p.pit->insetlist.begin());
280 // Try to find the next inset that contains paragraphs
281 InsetList::iterator end = p.pit->insetlist.end();
282 for (; *p.it != end; ++(*p.it)) {
283 if (LyXText * text = (*p.it)->inset->getText(0)) {
284 ParagraphList & plist = text->paragraphs();
285 if (!plist.empty()) {
287 positions_.push_back(ParPosition(plist.begin(), plist));
293 // Try to go to the next paragarph
294 if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
295 || positions_.size() == 1) {
303 // Drop end and move up in the stack.
304 positions_.pop_back();
311 Paragraph const & ParConstIterator::operator*() const
313 return *positions_.back().pit;
317 ParagraphList::const_iterator ParConstIterator::pit() const
319 return positions_.back().pit;
323 ParagraphList::const_iterator ParConstIterator::operator->() const
325 return positions_.back().pit;
329 ParagraphList const & ParConstIterator::plist() const
331 return *positions_.back().plist;
335 size_t ParConstIterator::size() const
337 return positions_.size();
341 bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
343 return iter1.positions() == iter2.positions();
347 bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
349 return !(iter1 == iter2);