2 #include "dociterator.h"
9 #include "mathed/math_data.h"
10 #include "mathed/math_inset.h"
12 #include <boost/assert.hpp>
17 DocumentIterator::DocumentIterator()
21 DocumentIterator::DocumentIterator(InsetBase & inset)
23 push_back(CursorSlice(inset));
27 InsetBase * DocumentIterator::nextInset()
29 BOOST_ASSERT(!empty());
30 if (pos() == lastpos())
33 return nextAtom().nucleus();
34 return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
38 InsetBase * DocumentIterator::prevInset()
40 BOOST_ASSERT(!empty());
44 return prevAtom().nucleus();
45 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
49 InsetBase const * DocumentIterator::prevInset() const
51 BOOST_ASSERT(!empty());
55 return prevAtom().nucleus();
56 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
60 MathAtom const & DocumentIterator::prevAtom() const
62 BOOST_ASSERT(!empty());
63 BOOST_ASSERT(pos() > 0);
64 return cell()[pos() - 1];
68 MathAtom & DocumentIterator::prevAtom()
70 BOOST_ASSERT(!empty());
71 BOOST_ASSERT(pos() > 0);
72 return cell()[pos() - 1];
76 MathAtom const & DocumentIterator::nextAtom() const
78 BOOST_ASSERT(!empty());
79 BOOST_ASSERT(pos() < lastpos());
84 MathAtom & DocumentIterator::nextAtom()
86 BOOST_ASSERT(!empty());
87 BOOST_ASSERT(pos() < lastpos());
92 LyXText * DocumentIterator::text() const
94 BOOST_ASSERT(!empty());
99 Paragraph & DocumentIterator::paragraph()
101 BOOST_ASSERT(inTexted());
102 return top().paragraph();
106 Paragraph const & DocumentIterator::paragraph() const
108 BOOST_ASSERT(inTexted());
109 return top().paragraph();
113 Row & DocumentIterator::textRow()
115 return *paragraph().getRow(pos());
119 Row const & DocumentIterator::textRow() const
121 return *paragraph().getRow(pos());
125 DocumentIterator::par_type DocumentIterator::lastpar() const
127 return inMathed() ? 0 : text()->paragraphs().size() - 1;
131 DocumentIterator::pos_type DocumentIterator::lastpos() const
133 return inMathed() ? cell().size() : paragraph().size();
137 DocumentIterator::row_type DocumentIterator::crow() const
139 return paragraph().row(pos());
143 DocumentIterator::row_type DocumentIterator::lastcrow() const
145 return paragraph().rows.size();
149 DocumentIterator::idx_type DocumentIterator::lastidx() const
151 return top().lastidx();
155 size_t DocumentIterator::nargs() const
157 // assume 1x1 grid for main text
158 return top().nargs();
162 size_t DocumentIterator::ncols() const
164 // assume 1x1 grid for main text
165 return top().ncols();
169 size_t DocumentIterator::nrows() const
171 // assume 1x1 grid for main text
172 return top().nrows();
176 DocumentIterator::row_type DocumentIterator::row() const
182 DocumentIterator::col_type DocumentIterator::col() const
188 MathArray const & DocumentIterator::cell() const
190 BOOST_ASSERT(inMathed());
195 MathArray & DocumentIterator::cell()
197 BOOST_ASSERT(inMathed());
202 bool DocumentIterator::inMathed() const
204 return !empty() && inset().inMathed();
208 bool DocumentIterator::inTexted() const
210 return !empty() && !inset().inMathed();
214 LyXText * DocumentIterator::innerText() const
216 BOOST_ASSERT(!empty());
217 // go up until first non-0 text is hit
218 // (innermost text is 0 in mathed)
219 for (int i = size() - 1; i >= 0; --i)
220 if (operator[](i).text())
221 return operator[](i).text();
226 InsetBase * DocumentIterator::innerInsetOfType(int code) const
228 for (int i = size() - 1; i >= 0; --i)
229 if (operator[](i).inset_->lyxCode() == code)
230 return operator[](i).inset_;
235 void DocumentIterator::forwardPos()
237 CursorSlice & top = back();
238 //lyxerr << "XXX\n" << *this << endl;
240 // this is used twice and shows up in the profiler!
241 pos_type const lastp = lastpos();
243 // move into an inset to the right if possible
246 if (top.pos() != lastp) {
247 // this is impossible for pos() == size()
249 n = (top.cell().begin() + top.pos())->nucleus();
251 if (paragraph().isInset(top.pos()))
252 n = paragraph().getInset(top.pos());
256 if (n && n->isActive()) {
257 //lyxerr << "... descend" << endl;
258 push_back(CursorSlice(*n));
262 // otherwise move on one position if possible
263 if (top.pos() < lastp) {
264 //lyxerr << "... next pos" << endl;
268 //lyxerr << "... no next pos" << endl;
270 // otherwise move on one paragraph if possible
271 if (top.par() < lastpar()) {
272 //lyxerr << "... next par" << endl;
277 //lyxerr << "... no next par" << endl;
279 // otherwise try to move on one cell if possible
280 if (top.idx() < lastidx()) {
281 //lyxerr << "... next idx" << endl;
287 //lyxerr << "... no next idx" << endl;
289 // otherwise leave inset and jump over inset as a whole
291 // 'top' is invalid now...
297 void DocumentIterator::forwardPar()
300 while (!empty() && (!inTexted() || pos() != 0))
305 void DocumentIterator::forwardChar()
308 while (size() != 0 && pos() == lastpos())
313 void DocumentIterator::forwardInset()
316 while (size() != 0 && (pos() == lastpos() || nextInset() == 0))
321 void DocumentIterator::backwardChar()
323 lyxerr << "not implemented" << endl;
328 std::ostream & operator<<(std::ostream & os, DocumentIterator const & dit)
330 for (size_t i = 0, n = dit.size(); i != n; ++i)
331 os << " " << dit.operator[](i) << "\n";
337 ///////////////////////////////////////////////////////
339 StableDocumentIterator::StableDocumentIterator(const DocumentIterator & dit)
342 for (size_t i = 0, n = data_.size(); i != n; ++i)
348 StableDocumentIterator::asDocumentIterator(InsetBase * inset) const
350 // this function re-creates the cache of inset pointers
351 //lyxerr << "converting:\n" << *this << endl;
352 DocumentIterator dit;
353 for (size_t i = 0, n = data_.size(); i != n; ++i) {
354 dit.push_back(data_[i]);
355 dit.back().inset_ = inset;
357 inset = dit.nextInset();
359 //lyxerr << "convert:\n" << *this << " to:\n" << dit << endl;
364 std::ostream & operator<<(std::ostream & os, StableDocumentIterator const & dit)
366 for (size_t i = 0, n = dit.data_.size(); i != n; ++i)
367 os << " " << dit.data_[i] << "\n";