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 void ParIterator::lockPath(BufferView * bv) const
226 LCursor & cur = bv->cursor();
228 int const last = size() - 1;
229 for (int i = 0; i < last; ++i)
230 (*positions_[i].it)->inset->edit(cur, true);
235 bool operator==(ParIterator const & iter1, ParIterator const & iter2)
237 return iter1.positions() == iter2.positions();
241 bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
243 return !(iter1 == iter2);
252 ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
253 ParagraphList const & pl)
255 positions_.push_back(ParPosition(pit, pl));
259 ParConstIterator::~ParConstIterator()
263 ParConstIterator::ParConstIterator(ParConstIterator const & pi)
264 : positions_(pi.positions_)
268 ParConstIterator & ParConstIterator::operator++()
270 while (!positions_.empty()) {
271 ParPosition & p = positions_.back();
273 // Does the current inset contain more "cells" ?
276 if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
277 ParagraphList & plist = text->paragraphs();
278 if (!plist.empty()) {
279 positions_.push_back(ParPosition(plist.begin(), plist));
285 // The following line is needed because the value of
286 // p.it may be invalid if inset was added/removed to
287 // the paragraph pointed by the iterator
288 p.it.reset(p.pit->insetlist.begin());
291 // Try to find the next inset that contains paragraphs
292 InsetList::iterator end = p.pit->insetlist.end();
293 for (; *p.it != end; ++(*p.it)) {
294 if (LyXText * text = (*p.it)->inset->getText(0)) {
295 ParagraphList & plist = text->paragraphs();
296 if (!plist.empty()) {
298 positions_.push_back(ParPosition(plist.begin(), plist));
304 // Try to go to the next paragarph
305 if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
306 || positions_.size() == 1) {
314 // Drop end and move up in the stack.
315 positions_.pop_back();
322 Paragraph const & ParConstIterator::operator*() const
324 return *positions_.back().pit;
328 ParagraphList::const_iterator ParConstIterator::pit() const
330 return positions_.back().pit;
334 ParagraphList::const_iterator ParConstIterator::operator->() const
336 return positions_.back().pit;
340 ParagraphList const & ParConstIterator::plist() const
342 return *positions_.back().plist;
346 size_t ParConstIterator::size() const
348 return positions_.size();
352 bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
354 return iter1.positions() == iter2.positions();
358 bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
360 return !(iter1 == iter2);