]> git.lyx.org Git - lyx.git/blob - src/PosIterator.C
remove part of old texted<->mathed interface
[lyx.git] / src / PosIterator.C
1 /* \file PosIterator.C
2  * This file is part of LyX, the document processor.
3  * Licence details can be found in the file COPYING.
4  *
5  * \author Alfredo Braunstein
6  *
7  * Full author contact details are available in file CREDITS.
8  */
9
10
11 #include <config.h>
12
13 #include "PosIterator.h"
14
15 #include "buffer.h"
16 #include "BufferView.h"
17 #include "cursor.h"
18 #include "iterators.h"
19 #include "lyxtext.h"
20 #include "paragraph.h"
21
22 #include "insets/insettext.h"
23 #include "insets/updatableinset.h"
24 #include "insets/inset.h"
25
26 #include <boost/next_prior.hpp>
27
28
29 using boost::prior;
30
31
32 PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
33                          lyx::pos_type pos)
34 {
35         stack_.push_back(PosIteratorItem(pl, pit, pos));
36 }
37
38
39 PosIterator::PosIterator(BufferView & bv)
40 {
41         LCursor & cur = bv.cursor();
42         BOOST_ASSERT(cur.inTexted());
43         LyXText * text = cur.text();
44         lyx::pos_type pos = cur.pos();
45         ParagraphList::iterator pit = text->getPar(cur.par());
46
47         ParIterator par = bv.buffer()->par_iterator_begin();
48         ParIterator end = bv.buffer()->par_iterator_end();
49         for (; par != end; ++par) {
50                 if (par.pit() == pit)
51                         break;
52         }
53         setFrom(par, pos);
54 }
55
56
57 PosIterator::PosIterator(ParIterator const & par, lyx::pos_type pos)
58 {
59         setFrom(par, pos);
60 }
61
62
63 void PosIterator::setFrom(ParIterator const & par, lyx::pos_type pos)
64 {
65         BOOST_ASSERT(par.size() > 0);
66
67         ParIterator::PosHolder const & ph = par.positions();
68
69         int const last = par.size() - 1;
70         for (int i = 0; i < last; ++i) {
71                 ParPosition const & pp = ph[i];
72                 stack_.push_back(
73                         PosIteratorItem(const_cast<ParagraphList *>(pp.plist),
74                                         pp.pit, (*pp.it)->pos, *pp.index + 1));
75         }
76         ParPosition const & pp = ph[last];
77         stack_.push_back(
78                 PosIteratorItem(const_cast<ParagraphList *>(pp.plist), pp.pit, pos, 0));
79 }
80
81
82 PosIterator & PosIterator::operator++()
83 {
84         BOOST_ASSERT(!stack_.empty());
85         while (true) {
86                 PosIteratorItem & p = stack_.back();
87
88                 if (p.pos < p.pit->size()) {
89                         if (InsetBase * inset = p.pit->getInset(p.pos)) {
90                                 if (LyXText * text = inset->getText(p.index)) {
91                                         ParagraphList & pl = text->paragraphs();
92                                         p.index++;
93                                         stack_.push_back(PosIteratorItem(&pl, pl.begin(), 0));
94                                         return *this;
95                                 }
96                         }
97                         p.index = 0;
98                         ++p.pos;
99                 } else {
100                         ++p.pit;
101                         p.pos = 0;
102                 }
103
104                 if (p.pit != p.pl->end() || stack_.size() == 1)
105                         return *this;
106
107                 stack_.pop_back();
108         }
109         return *this;
110 }
111
112
113 PosIterator & PosIterator::operator--()
114 {
115         BOOST_ASSERT(!stack_.empty());
116
117         // try to go one position backwards: if on the start of the
118         // ParagraphList, pops an item
119         PosIteratorItem & p = stack_.back();
120         if (p.pos > 0) {
121                 --p.pos;
122                 InsetBase * inset = p.pit->getInset(p.pos);
123                 if (inset)
124                         p.index = inset->nargs();
125         } else {
126                 if (p.pit == p.pl->begin()) {
127                         if (stack_.size() == 1)
128                                 return *this;
129                         stack_.pop_back();
130                         --stack_.back().index;
131                 } else {
132                         --p.pit;
133                         p.pos = p.pit->size();
134                 }
135         }
136         // try to push an item if there is some left unexplored
137         PosIteratorItem & q = stack_.back();
138         if (q.pos < q.pit->size()) {
139                 InsetBase * inset = q.pit->getInset(q.pos);
140                 if (inset && q.index > 0) {
141                         LyXText * text = inset->getText(q.index - 1);
142                         BOOST_ASSERT(text);
143                         ParagraphList & pl = text->paragraphs();
144                         stack_.push_back(PosIteratorItem(&pl, prior(pl.end()), pl.back().size()));
145                 }
146         }
147         return *this;
148 }
149
150
151 bool operator==(PosIterator const & lhs, PosIterator const & rhs)
152 {
153         PosIteratorItem const & li = lhs.stack_.back();
154         PosIteratorItem const & ri = rhs.stack_.back();
155
156         return (li.pl == ri.pl && li.pit == ri.pit &&
157                 (li.pit == li.pl->end() || li.pos == ri.pos));
158 }
159
160
161 bool PosIterator::at_end() const
162 {
163         return pos() == pit()->size();
164 }
165
166
167 InsetBase * PosIterator::inset() const
168 {
169         if (stack_.size() == 1)
170                 return 0;
171         PosIteratorItem const & pi = stack_[stack_.size() - 2];
172         return pi.pit->getInset(pi.pos);
173 }