2 #include "dociterator.h"
9 #include "mathed/math_data.h"
10 #include "mathed/math_inset.h"
12 #include <boost/assert.hpp>
15 InsetBase * DocumentIterator::nextInset()
17 if (pos() == lastpos())
20 return nextAtom().nucleus();
21 return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
25 InsetBase * DocumentIterator::prevInset()
30 return prevAtom().nucleus();
31 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
35 InsetBase const * DocumentIterator::prevInset() const
40 return prevAtom().nucleus();
41 return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
45 MathAtom const & DocumentIterator::prevAtom() const
47 BOOST_ASSERT(pos() > 0);
48 return cell()[pos() - 1];
52 MathAtom & DocumentIterator::prevAtom()
54 BOOST_ASSERT(pos() > 0);
55 return cell()[pos() - 1];
59 MathAtom const & DocumentIterator::nextAtom() const
61 BOOST_ASSERT(pos() < lastpos());
66 MathAtom & DocumentIterator::nextAtom()
68 BOOST_ASSERT(pos() < lastpos());
73 LyXText * DocumentIterator::text() const
79 Paragraph & DocumentIterator::paragraph()
81 BOOST_ASSERT(inTexted());
82 return top().paragraph();
86 Paragraph const & DocumentIterator::paragraph() const
88 BOOST_ASSERT(inTexted());
89 return top().paragraph();
93 Row & DocumentIterator::textRow()
95 return *paragraph().getRow(pos());
99 Row const & DocumentIterator::textRow() const
101 return *paragraph().getRow(pos());
105 DocumentIterator::par_type DocumentIterator::lastpar() const
107 return inMathed() ? 0 : text()->paragraphs().size() - 1;
111 DocumentIterator::pos_type DocumentIterator::lastpos() const
113 return inMathed() ? cell().size() : paragraph().size();
117 DocumentIterator::row_type DocumentIterator::crow() const
119 return paragraph().row(pos());
123 DocumentIterator::row_type DocumentIterator::lastcrow() const
125 return paragraph().rows.size();
129 DocumentIterator::idx_type DocumentIterator::lastidx() const
131 return top().lastidx();
135 size_t DocumentIterator::nargs() const
137 // assume 1x1 grid for main text
138 return top().nargs();
142 size_t DocumentIterator::ncols() const
144 // assume 1x1 grid for main text
145 return top().ncols();
149 size_t DocumentIterator::nrows() const
151 // assume 1x1 grid for main text
152 return top().nrows();
156 DocumentIterator::row_type DocumentIterator::row() const
162 DocumentIterator::col_type DocumentIterator::col() const
168 MathArray const & DocumentIterator::cell() const
170 BOOST_ASSERT(inMathed());
175 MathArray & DocumentIterator::cell()
177 BOOST_ASSERT(inMathed());
182 bool DocumentIterator::inMathed() const
184 return !empty() && inset().inMathed();
188 bool DocumentIterator::inTexted() const
190 return !empty() && !inset().inMathed();
194 LyXText * DocumentIterator::innerText() const
196 BOOST_ASSERT(!empty());
197 // go up until first non-0 text is hit
198 // (innermost text is 0 in mathed)
199 for (int i = size() - 1; i >= 0; --i)
200 if (operator[](i).text())
201 return operator[](i).text();
206 InsetBase * DocumentIterator::innerInsetOfType(int code) const
208 for (int i = size() - 1; i >= 0; --i)
209 if (operator[](i).inset_->lyxCode() == code)
210 return operator[](i).inset_;
215 void DocumentIterator::forwardPos()
217 CursorSlice & top = back();
218 //lyxerr << "XXX\n" << *this << std::endl;
220 // move into an inset to the right if possible
222 if (top.pos() != lastpos()) {
223 // this is impossible for pos() == size()
225 n = (top.cell().begin() + top.pos())->nucleus();
227 if (paragraph().isInset(top.pos()))
228 n = paragraph().getInset(top.pos());
232 if (n && n->isActive()) {
233 //lyxerr << "... descend" << std::endl;
234 push_back(CursorSlice(*n));
238 // otherwise move on one cell back if possible
239 if (top.pos() < lastpos()) {
240 //lyxerr << "... next pos" << std::endl;
244 //lyxerr << "... no next pos" << std::endl;
246 // otherwise move on one cell back if possible
247 if (top.par() < lastpar()) {
248 //lyxerr << "... next par" << std::endl;
253 //lyxerr << "... no next par" << std::endl;
255 // otherwise try to move on one cell if possible
256 // [stupid hack for necessary for MathScriptInset]
257 while (top.idx() < lastidx()) {
258 //lyxerr << "... next idx" << std::endl;
262 if (top.inset().validCell(top.idx())) {
263 //lyxerr << " ... ok" << std::endl;
267 //lyxerr << "... no next idx" << std::endl;
269 // otherwise leave inset an jump over inset as a whole
271 // 'top' is invalid now...
275 // lyxerr << "... no slice left" << std::endl;
279 void DocumentIterator::forwardPar()
281 CursorSlice & top = back();
282 lyxerr << "XXX " << *this << std::endl;
284 // move into an inset to the right if possible
286 if (top.pos() != lastpos()) {
287 // this is impossible for pos() == size()
289 n = (top.cell().begin() + top.pos())->nucleus();
291 if (paragraph().isInset(top.pos()))
292 n = paragraph().getInset(top.pos());
296 if (n && n->isActive()) {
297 lyxerr << "... descend" << std::endl;
298 push_back(CursorSlice(*n));
302 // otherwise move on one cell back if possible
303 if (top.pos() < lastpos()) {
304 lyxerr << "... next pos" << std::endl;
309 // otherwise move on one cell back if possible
310 if (top.par() < lastpar()) {
311 lyxerr << "... next par" << std::endl;
317 // otherwise try to move on one cell if possible
318 // [stupid hack for necessary for MathScriptInset]
319 while (top.idx() < top.lastidx()) {
320 lyxerr << "... next idx"
321 << " was: " << top.idx() << " max: " << top.lastidx() << std::endl;
325 if (top.inset().validCell(top.idx())) {
326 lyxerr << " ... ok" << std::endl;
331 // otherwise leave inset an jump over inset as a whole
333 // 'top' is invalid now...
339 DocumentIterator insetBegin(InsetBase & inset)
342 it.push_back(CursorSlice(inset));
347 DocumentIterator insetEnd()
349 return DocumentIterator();
353 std::ostream & operator<<(std::ostream & os, DocumentIterator const & dit)
355 for (size_t i = 0, n = dit.size(); i != n; ++i)
356 os << " " << dit.operator[](i) << "\n";
362 ///////////////////////////////////////////////////////
364 StableDocumentIterator::StableDocumentIterator(const DocumentIterator & dit)
367 for (size_t i = 0, n = data_.size(); i != n; ++i)
373 StableDocumentIterator::asDocumentIterator(InsetBase * inset) const
375 // this function re-creates the cache of inset pointers
376 //lyxerr << "converting:\n" << *this << std::endl;
377 DocumentIterator dit;
378 for (size_t i = 0, n = data_.size(); i != n; ++i) {
379 dit.push_back(data_[i]);
380 dit.back().inset_ = inset;
382 inset = dit.nextInset();
384 //lyxerr << "convert:\n" << *this << " to:\n" << dit << std::endl;
389 std::ostream & operator<<(std::ostream & os, StableDocumentIterator const & dit)
391 for (size_t i = 0, n = dit.data_.size(); i != n; ++i)
392 os << " " << dit.data_[i] << "\n";