2 #include "dociterator.h"
9 #include "mathed/math_data.h"
10 #include "mathed/math_inset.h"
12 #include <boost/assert.hpp>
15 DocumentIterator::DocumentIterator()
19 DocumentIterator::DocumentIterator(InsetBase & inset)
21 push_back(CursorSlice(inset));
25 InsetBase * DocumentIterator::nextInset()
27 if (pos() == lastpos())
30 return nextAtom().nucleus();
31 return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
35 InsetBase * DocumentIterator::prevInset()
40 return prevAtom().nucleus();
41 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
45 InsetBase const * DocumentIterator::prevInset() const
50 return prevAtom().nucleus();
51 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
55 MathAtom const & DocumentIterator::prevAtom() const
57 BOOST_ASSERT(pos() > 0);
58 return cell()[pos() - 1];
62 MathAtom & DocumentIterator::prevAtom()
64 BOOST_ASSERT(pos() > 0);
65 return cell()[pos() - 1];
69 MathAtom const & DocumentIterator::nextAtom() const
71 BOOST_ASSERT(pos() < lastpos());
76 MathAtom & DocumentIterator::nextAtom()
78 BOOST_ASSERT(pos() < lastpos());
83 LyXText * DocumentIterator::text() const
89 Paragraph & DocumentIterator::paragraph()
91 BOOST_ASSERT(inTexted());
92 return top().paragraph();
96 Paragraph const & DocumentIterator::paragraph() const
98 BOOST_ASSERT(inTexted());
99 return top().paragraph();
103 Row & DocumentIterator::textRow()
105 return *paragraph().getRow(pos());
109 Row const & DocumentIterator::textRow() const
111 return *paragraph().getRow(pos());
115 DocumentIterator::par_type DocumentIterator::lastpar() const
117 return inMathed() ? 0 : text()->paragraphs().size() - 1;
121 DocumentIterator::pos_type DocumentIterator::lastpos() const
123 return inMathed() ? cell().size() : paragraph().size();
127 DocumentIterator::row_type DocumentIterator::crow() const
129 return paragraph().row(pos());
133 DocumentIterator::row_type DocumentIterator::lastcrow() const
135 return paragraph().rows.size();
139 DocumentIterator::idx_type DocumentIterator::lastidx() const
141 return top().lastidx();
145 size_t DocumentIterator::nargs() const
147 // assume 1x1 grid for main text
148 return top().nargs();
152 size_t DocumentIterator::ncols() const
154 // assume 1x1 grid for main text
155 return top().ncols();
159 size_t DocumentIterator::nrows() const
161 // assume 1x1 grid for main text
162 return top().nrows();
166 DocumentIterator::row_type DocumentIterator::row() const
172 DocumentIterator::col_type DocumentIterator::col() const
178 MathArray const & DocumentIterator::cell() const
180 BOOST_ASSERT(inMathed());
185 MathArray & DocumentIterator::cell()
187 BOOST_ASSERT(inMathed());
192 bool DocumentIterator::inMathed() const
194 return !empty() && inset().inMathed();
198 bool DocumentIterator::inTexted() const
200 return !empty() && !inset().inMathed();
204 LyXText * DocumentIterator::innerText() const
206 BOOST_ASSERT(!empty());
207 // go up until first non-0 text is hit
208 // (innermost text is 0 in mathed)
209 for (int i = size() - 1; i >= 0; --i)
210 if (operator[](i).text())
211 return operator[](i).text();
216 InsetBase * DocumentIterator::innerInsetOfType(int code) const
218 for (int i = size() - 1; i >= 0; --i)
219 if (operator[](i).inset_->lyxCode() == code)
220 return operator[](i).inset_;
225 void DocumentIterator::forwardPos()
227 CursorSlice & top = back();
228 //lyxerr << "XXX\n" << *this << std::endl;
230 // move into an inset to the right if possible
232 if (top.pos() != lastpos()) {
233 // this is impossible for pos() == size()
235 n = (top.cell().begin() + top.pos())->nucleus();
237 if (paragraph().isInset(top.pos()))
238 n = paragraph().getInset(top.pos());
242 if (n && n->isActive()) {
243 //lyxerr << "... descend" << std::endl;
244 push_back(CursorSlice(*n));
248 // otherwise move on one cell back if possible
249 if (top.pos() < lastpos()) {
250 //lyxerr << "... next pos" << std::endl;
254 //lyxerr << "... no next pos" << std::endl;
256 // otherwise move on one cell back if possible
257 if (top.par() < lastpar()) {
258 //lyxerr << "... next par" << std::endl;
263 //lyxerr << "... no next par" << std::endl;
265 // otherwise try to move on one cell if possible
266 // [stupid hack for necessary for MathScriptInset]
267 while (top.idx() < lastidx()) {
268 //lyxerr << "... next idx" << std::endl;
272 if (top.inset().validCell(top.idx())) {
273 //lyxerr << " ... ok" << std::endl;
277 //lyxerr << "... no next idx" << std::endl;
279 // otherwise leave inset an jump over inset as a whole
281 // 'top' is invalid now...
285 // lyxerr << "... no slice left" << std::endl;
289 void DocumentIterator::forwardPar()
291 CursorSlice & top = back();
292 lyxerr << "XXX " << *this << std::endl;
294 // move into an inset to the right if possible
296 if (top.pos() != lastpos()) {
297 // this is impossible for pos() == size()
299 n = (top.cell().begin() + top.pos())->nucleus();
301 if (paragraph().isInset(top.pos()))
302 n = paragraph().getInset(top.pos());
306 if (n && n->isActive()) {
307 lyxerr << "... descend" << std::endl;
308 push_back(CursorSlice(*n));
312 // otherwise move on one cell back if possible
313 if (top.pos() < lastpos()) {
314 lyxerr << "... next pos" << std::endl;
319 // otherwise move on one cell back if possible
320 if (top.par() < lastpar()) {
321 lyxerr << "... next par" << std::endl;
327 // otherwise try to move on one cell if possible
328 // [stupid hack for necessary for MathScriptInset]
329 while (top.idx() < top.lastidx()) {
330 lyxerr << "... next idx"
331 << " was: " << top.idx() << " max: " << top.lastidx() << std::endl;
335 if (top.inset().validCell(top.idx())) {
336 lyxerr << " ... ok" << std::endl;
341 // otherwise leave inset an jump over inset as a whole
343 // 'top' is invalid now...
349 std::ostream & operator<<(std::ostream & os, DocumentIterator const & dit)
351 for (size_t i = 0, n = dit.size(); i != n; ++i)
352 os << " " << dit.operator[](i) << "\n";
358 ///////////////////////////////////////////////////////
360 StableDocumentIterator::StableDocumentIterator(const DocumentIterator & dit)
363 for (size_t i = 0, n = data_.size(); i != n; ++i)
369 StableDocumentIterator::asDocumentIterator(InsetBase * inset) const
371 // this function re-creates the cache of inset pointers
372 //lyxerr << "converting:\n" << *this << std::endl;
373 DocumentIterator dit;
374 for (size_t i = 0, n = data_.size(); i != n; ++i) {
375 dit.push_back(data_[i]);
376 dit.back().inset_ = inset;
378 inset = dit.nextInset();
380 //lyxerr << "convert:\n" << *this << " to:\n" << dit << std::endl;
385 std::ostream & operator<<(std::ostream & os, StableDocumentIterator const & dit)
387 for (size_t i = 0, n = dit.data_.size(); i != n; ++i)
388 os << " " << dit.data_[i] << "\n";