]> git.lyx.org Git - lyx.git/blob - src/PosIterator.C
remove Inset::getParagraphs()
[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 "iterators.h"
18 #include "lyxtext.h"
19 #include "paragraph.h"
20
21 #include "insets/insettext.h"
22 #include "insets/updatableinset.h"
23 #include "insets/inset.h"
24
25 #include <boost/next_prior.hpp>
26
27 using boost::prior;
28
29 PosIterator & PosIterator::operator++()
30 {
31         BOOST_ASSERT(!stack_.empty());
32         while (true) {
33                 PosIteratorItem & p = stack_.back();
34                 
35                 if (p.pos < p.pit->size()) {
36                         if (InsetOld * inset = p.pit->getInset(p.pos)) {
37                                 if (LyXText * text = inset->getText(p.index)) {
38                                         ParagraphList & pl = text->paragraphs();
39                                         p.index++;
40                                         stack_.push_back(PosIteratorItem(&pl, pl.begin(), 0));
41                                         return *this;
42                                 }
43                         }
44                         p.index = 0;
45                         ++p.pos;
46                 } else {
47                         ++p.pit;
48                         p.pos = 0;
49                 }
50                 
51                 if (p.pit != p.pl->end() || stack_.size() == 1)
52                         return *this;
53                 
54                 stack_.pop_back();
55         }
56         return *this;
57 }
58
59
60 PosIterator & PosIterator::operator--()
61 {
62         BOOST_ASSERT(!stack_.empty());
63         
64         // try to go one position backwards: if on the start of the
65         // ParagraphList, pops an item 
66         PosIteratorItem & p = stack_.back();
67         if (p.pos > 0) {
68                 --p.pos;
69                 InsetOld * inset = p.pit->getInset(p.pos);
70                 if (inset)
71                         p.index = inset->numParagraphs();
72         } else {
73                 if (p.pit == p.pl->begin()) {
74                         if (stack_.size() == 1)
75                                 return *this;
76                         stack_.pop_back();
77                         --stack_.back().index;
78                 } else {
79                         --p.pit;
80                         p.pos = p.pit->size();
81                 }
82         }
83         // try to push an item if there is some left unexplored
84         PosIteratorItem & q = stack_.back();
85         if (q.pos < q.pit->size()) {
86                 InsetOld * inset = q.pit->getInset(q.pos);
87                 if (inset && q.index > 0) {
88                         LyXText * text = inset->getText(q.index - 1);
89                         BOOST_ASSERT(text);
90                         ParagraphList & pl = text->paragraphs();
91                         stack_.push_back(PosIteratorItem(&pl, prior(pl.end()), pl.back().size()));
92                 }
93         }
94         return *this;
95 }
96
97
98 bool operator!=(PosIterator const & lhs, PosIterator const & rhs)
99 {
100         return !(lhs == rhs);
101 }
102
103
104 bool operator==(PosIterator const & lhs, PosIterator const & rhs)
105 {
106         
107         PosIteratorItem const & li = lhs.stack_.back();
108         PosIteratorItem const & ri = rhs.stack_.back();
109         
110         return (li.pl == ri.pl && li.pit == ri.pit &&
111                 (li.pit == li.pl->end() || li.pos == ri.pos));
112 }
113
114
115 bool PosIterator::at_end() const
116 {
117         return pos() == pit()->size();
118 }
119
120
121 PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
122                          lyx::pos_type pos)
123 {
124         stack_.push_back(PosIteratorItem(pl, pit, pos));
125 }
126
127
128 PosIterator::PosIterator(BufferView & bv)
129 {
130         LyXText * text = bv.getLyXText();
131         lyx::pos_type pos = text->cursor.pos();
132         ParagraphList::iterator pit = text->cursorPar();
133         
134         ParIterator par = bv.buffer()->par_iterator_begin();
135         ParIterator end = bv.buffer()->par_iterator_end();
136         for ( ; par != end; ++par) {
137                 if (par.pit() == pit)
138                         break;
139         }
140
141         operator=(par.asPosIterator(pos));
142 }
143
144
145 InsetOld * PosIterator::inset() const
146 {
147         if (stack_.size() == 1)
148                 return 0;
149         PosIteratorItem const & pi = stack_[stack_.size() - 2];
150         return pi.pit->getInset(pi.pos);
151 }
152
153
154 int distance(PosIterator const & cur, PosIterator const & end)
155 {
156         PosIterator p = cur;
157         int count = 0;
158         for (; p != end; ++p, ++count)
159                 ;
160         return count;
161 }
162
163
164 void advance(PosIterator & cur, int howmuch)
165 {
166         for (int i = 0; i < howmuch; ++i)
167                 ++cur;
168         for (int i = 0; i > howmuch; --i)
169                 --cur;
170 }