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"
18 #include "BufferView.h"
19 #include "dispatchresult.h"
21 #include "insets/inset.h"
22 #include "insets/updatableinset.h"
23 #include "insets/insettext.h"
25 #include <boost/next_prior.hpp>
36 ParPosition::ParPosition(par_type p, ParagraphList const & pl)
39 if (p != par_type(pl.size()))
40 it.reset(const_cast<InsetList&>(pl[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(par_type 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(0, 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(const_cast<InsetList&>((*p.plist)[p.pit].insetlist).begin());
105 // Try to find the next inset that contains paragraphs
106 InsetList::iterator end =
107 const_cast<InsetList&>((*p.plist)[p.pit].insetlist).end();
108 for (; *p.it != end; ++(*p.it)) {
109 if (LyXText * text = (*p.it)->inset->getText(0)) {
110 ParagraphList & plist = text->paragraphs();
111 if (!plist.empty()) {
113 positions_.push_back(ParPosition(0, plist));
119 // Try to go to the next paragarph
120 if (p.pit + 1 != par_type(p.plist->size()) ||
121 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 plist()[positions_.back().pit];
172 par_type ParIterator::pit() const
174 return positions_.back().pit;
178 Paragraph * ParIterator::operator->() const
180 return &plist()[positions_.back().pit];
184 par_type 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(DocumentIterator const & cur)
204 int const size = cur.size();
206 for (int i = 0; i < size; ++i) {
207 CursorSlice sl = cur[i];
208 ParPosition pp(sl.par(), sl.text()->paragraphs());
210 Paragraph & par = sl.text()->paragraphs()[sl.par()];
211 InsetBase * inset = par.getInset(sl.pos());
213 InsetList::iterator beg = par.insetlist.begin();
214 InsetList::iterator end = par.insetlist.end();
215 for ( ; beg != end && beg->inset != inset; ++beg)
218 pp.index.reset(sl.idx() - 1);
220 positions_.push_back(pp);
225 bool operator==(ParIterator const & iter1, ParIterator const & iter2)
227 return iter1.positions() == iter2.positions();
231 bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
233 return !(iter1 == iter2);
242 ParConstIterator::ParConstIterator(par_type pit, 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(0, 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(const_cast<InsetList&>((*p.plist)[p.pit].insetlist).begin());
280 // Try to find the next inset that contains paragraphs
281 InsetList::iterator end =
282 const_cast<InsetList&>((*p.plist)[p.pit].insetlist).end();
283 for (; *p.it != end; ++(*p.it)) {
284 if (LyXText * text = (*p.it)->inset->getText(0)) {
285 ParagraphList & plist = text->paragraphs();
286 if (!plist.empty()) {
288 positions_.push_back(ParPosition(0, plist));
294 // Try to go to the next paragarph
295 if (p.pit + 1 != par_type(p.plist->size()) ||
296 positions_.size() == 1) {
303 // Drop end and move up in the stack.
304 positions_.pop_back();
311 Paragraph const & ParConstIterator::operator*() const
313 return plist()[positions_.back().pit];
317 par_type ParConstIterator::pit() const
319 return positions_.back().pit;
323 Paragraph const * ParConstIterator::operator->() const
325 return &plist()[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);