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)
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 != p.plist->size() || positions_.size() == 1) {
127 // Drop end and move up in the stack.
128 positions_.pop_back();
134 LyXText * ParIterator::text(Buffer & buf) const
136 //lyxerr << "positions.size: " << positions.size() << std::endl;
137 if (positions_.size() <= 1)
140 ParPosition const & pos = positions_[positions_.size() - 2];
141 return (*pos.it)->inset->getText(*pos.index);
145 InsetBase * ParIterator::inset() const
147 //lyxerr << "positions.size: " << positions.size() << std::endl;
148 if (positions_.size() <= 1)
151 ParPosition const & pos = positions_[positions_.size() - 2];
152 return (*pos.it)->inset;
156 int ParIterator::index() const
158 if (positions_.size() <= 1)
161 return *(positions_[positions_.size() - 2].index);
165 Paragraph & ParIterator::operator*() const
167 return plist()[positions_.back().pit];
171 par_type ParIterator::pit() const
173 return positions_.back().pit;
177 Paragraph * ParIterator::operator->() const
179 return &plist()[positions_.back().pit];
183 par_type ParIterator::outerPar() const
185 return positions_[0].pit;
189 size_t ParIterator::size() const
191 return positions_.size();
195 ParagraphList & ParIterator::plist() const
197 return *const_cast<ParagraphList*>(positions_.back().plist);
201 ParIterator::ParIterator(DocumentIterator const & cur)
203 int const size = cur.size();
205 for (int i = 0; i < size; ++i) {
206 CursorSlice sl = cur[i];
207 ParPosition pp(sl.par(), sl.text()->paragraphs());
209 Paragraph & par = sl.text()->paragraphs()[sl.par()];
210 InsetBase * inset = par.getInset(sl.pos());
212 InsetList::iterator beg = par.insetlist.begin();
213 InsetList::iterator end = par.insetlist.end();
214 for ( ; beg != end && beg->inset != inset; ++beg)
217 pp.index.reset(sl.idx() - 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(par_type pit, ParagraphList const & pl)
243 positions_.push_back(ParPosition(pit, pl));
247 ParConstIterator::~ParConstIterator()
251 ParConstIterator::ParConstIterator(ParConstIterator const & pi)
252 : positions_(pi.positions_)
256 ParConstIterator & ParConstIterator::operator++()
258 while (!positions_.empty()) {
259 ParPosition & p = positions_.back();
261 // Does the current inset contain more "cells" ?
264 if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
265 ParagraphList & plist = text->paragraphs();
266 if (!plist.empty()) {
267 positions_.push_back(ParPosition(0, plist));
273 // The following line is needed because the value of
274 // p.it may be invalid if inset was added/removed to
275 // the paragraph pointed by the iterator
276 p.it.reset(const_cast<InsetList&>((*p.plist)[p.pit].insetlist).begin());
279 // Try to find the next inset that contains paragraphs
280 InsetList::iterator end =
281 const_cast<InsetList&>((*p.plist)[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(0, plist));
293 // Try to go to the next paragarph
294 if (p.pit + 1 != p.plist->size() || positions_.size() == 1) {
301 // Drop end and move up in the stack.
302 positions_.pop_back();
309 Paragraph const & ParConstIterator::operator*() const
311 return plist()[positions_.back().pit];
315 par_type ParConstIterator::pit() const
317 return positions_.back().pit;
321 Paragraph const * ParConstIterator::operator->() const
323 return &plist()[positions_.back().pit];
327 ParagraphList const & ParConstIterator::plist() const
329 return *positions_.back().plist;
333 size_t ParConstIterator::size() const
335 return positions_.size();
339 bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
341 return iter1.positions() == iter2.positions();
345 bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
347 return !(iter1 == iter2);