2 #include "dociterator.h"
4 #include "BufferView.h"
10 #include "mathed/math_data.h"
11 #include "mathed/math_inset.h"
13 #include <boost/assert.hpp>
17 std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur);
20 DocumentIterator::DocumentIterator()
25 DocumentIterator::DocumentIterator(BufferView & bv)
26 : std::vector<CursorSlice>(1), bv_(&bv)
30 InsetBase * DocumentIterator::nextInset()
32 if (pos() == lastpos())
35 return nextAtom().nucleus();
36 return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
40 InsetBase * DocumentIterator::prevInset()
45 return prevAtom().nucleus();
46 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
50 InsetBase const * DocumentIterator::prevInset() const
55 return prevAtom().nucleus();
56 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
60 MathAtom const & DocumentIterator::prevAtom() const
62 BOOST_ASSERT(pos() > 0);
63 return cell()[pos() - 1];
67 MathAtom & DocumentIterator::prevAtom()
69 BOOST_ASSERT(pos() > 0);
70 return cell()[pos() - 1];
74 MathAtom const & DocumentIterator::nextAtom() const
76 BOOST_ASSERT(pos() < lastpos());
81 MathAtom & DocumentIterator::nextAtom()
83 BOOST_ASSERT(pos() < lastpos());
88 LyXText * DocumentIterator::text() const
90 return size() > 1 ? top().text() : bv().text();
94 Paragraph & DocumentIterator::paragraph()
96 BOOST_ASSERT(inTexted());
97 return size() > 1 ? top().paragraph() : *bv().text()->getPar(par());
101 Paragraph const & DocumentIterator::paragraph() const
103 BOOST_ASSERT(inTexted());
104 return size() > 1 ? top().paragraph() : *bv().text()->getPar(par());
108 Row & DocumentIterator::textRow()
110 return *paragraph().getRow(pos());
114 Row const & DocumentIterator::textRow() const
116 return *paragraph().getRow(pos());
120 DocumentIterator::par_type DocumentIterator::lastpar() const
122 return inMathed() ? 0 : text()->paragraphs().size() - 1;
126 DocumentIterator::pos_type DocumentIterator::lastpos() const
128 return inMathed() ? cell().size() : paragraph().size();
132 DocumentIterator::row_type DocumentIterator::crow() const
134 return paragraph().row(pos());
138 DocumentIterator::row_type DocumentIterator::lastcrow() const
140 return paragraph().rows.size();
144 DocumentIterator::idx_type DocumentIterator::lastidx() const
146 return size() > 1 ? top().lastidx() : 0;
150 size_t DocumentIterator::nargs() const
152 // assume 1x1 grid for main text
153 return size() > 1 ? top().nargs() : 1;
157 size_t DocumentIterator::ncols() const
159 // assume 1x1 grid for main text
160 return size() > 1 ? top().ncols() : 1;
164 size_t DocumentIterator::nrows() const
166 // assume 1x1 grid for main text
167 return size() > 1 ? top().nrows() : 1;
171 DocumentIterator::row_type DocumentIterator::row() const
173 return size() > 1 ? top().row() : 0;
177 DocumentIterator::col_type DocumentIterator::col() const
179 return size() > 1 ? top().col() : 0;
183 MathArray const & DocumentIterator::cell() const
185 BOOST_ASSERT(size() > 1);
190 MathArray & DocumentIterator::cell()
192 BOOST_ASSERT(size() > 1);
197 bool DocumentIterator::inMathed() const
199 return size() > 1 && inset()->inMathed();
203 bool DocumentIterator::inTexted() const
209 LyXText * DocumentIterator::innerText() const
211 BOOST_ASSERT(!empty());
213 // go up until first non-0 text is hit
214 // (innermost text is 0 in mathed)
215 for (int i = size() - 1; i >= 1; --i)
216 if (operator[](i).text())
217 return operator[](i).text();
223 CursorSlice const & DocumentIterator::innerTextSlice() const
225 BOOST_ASSERT(!empty());
227 // go up until first non-0 text is hit
228 // (innermost text is 0 in mathed)
229 for (int i = size() - 1; i >= 1; --i)
230 if (operator[](i).text())
231 return operator[](i);
233 return operator[](0);
237 InsetBase * DocumentIterator::innerInsetOfType(int code) const
239 for (int i = size() - 1; i >= 1; --i)
240 if (operator[](i).inset_->lyxCode() == code)
241 return operator[](i).inset_;
246 void DocumentIterator::forwardPos()
248 CursorSlice & top = back();
249 //lyxerr << "XXX\n" << *this << std::endl;
251 // move into an inset to the right if possible
253 if (top.pos() != lastpos()) {
254 // this is impossible for pos() == size()
256 n = (top.cell().begin() + top.pos())->nucleus();
258 if (paragraph().isInset(top.pos()))
259 n = paragraph().getInset(top.pos());
263 if (n && n->isActive()) {
264 //lyxerr << "... descend" << std::endl;
265 push_back(CursorSlice(n));
269 // otherwise move on one cell back if possible
270 if (top.pos() < lastpos()) {
271 //lyxerr << "... next pos" << std::endl;
275 //lyxerr << "... no next pos" << std::endl;
277 // otherwise move on one cell back if possible
278 if (top.par() < lastpar()) {
279 //lyxerr << "... next par" << std::endl;
284 //lyxerr << "... no next par" << std::endl;
286 // otherwise try to move on one cell if possible
287 // [stupid hack for necessary for MathScriptInset]
288 while (top.idx() < lastidx()) {
289 //lyxerr << "... next idx" << std::endl;
293 if (top.inset() && top.inset()->validCell(top.idx())) {
294 //lyxerr << " ... ok" << std::endl;
298 //lyxerr << "... no next idx" << std::endl;
300 // otherwise leave inset an jump over inset as a whole
302 // 'top' is invalid now...
306 // lyxerr << "... no slice left" << std::endl;
310 void DocumentIterator::forwardPar()
312 CursorSlice & top = back();
313 lyxerr << "XXX " << *this << std::endl;
315 // move into an inset to the right if possible
317 if (top.pos() != lastpos()) {
318 // this is impossible for pos() == size()
320 n = (top.cell().begin() + top.pos())->nucleus();
322 if (paragraph().isInset(top.pos()))
323 n = paragraph().getInset(top.pos());
327 if (n && n->isActive()) {
328 lyxerr << "... descend" << std::endl;
329 push_back(CursorSlice(n));
333 // otherwise move on one cell back if possible
334 if (top.pos() < lastpos()) {
335 lyxerr << "... next pos" << std::endl;
340 // otherwise move on one cell back if possible
341 if (top.par() < lastpar()) {
342 lyxerr << "... next par" << std::endl;
348 // otherwise try to move on one cell if possible
349 // [stupid hack for necessary for MathScriptInset]
350 while (top.idx() < top.lastidx()) {
351 lyxerr << "... next idx"
352 << " was: " << top.idx() << " max: " << top.lastidx() << std::endl;
356 if (top.inset() && top.inset()->validCell(top.idx())) {
357 lyxerr << " ... ok" << std::endl;
362 // otherwise leave inset an jump over inset as a whole
364 // 'top' is invalid now...
370 DocumentIterator bufferBegin(BufferView & bv)
372 return DocumentIterator(bv);
376 DocumentIterator bufferEnd()
378 return DocumentIterator();
382 DocumentIterator insetBegin(BufferView & bv, InsetBase * p)
384 DocumentIterator it(bv);
385 it.back() = CursorSlice(p);
390 DocumentIterator insetEnd()
392 return DocumentIterator();
396 std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur)
398 for (size_t i = 0, n = cur.size(); i != n; ++i)
399 os << " " << cur.operator[](i) << "\n";