]> git.lyx.org Git - lyx.git/blob - src/lyxrow_funcs.C
Alfredo's second patch
[lyx.git] / src / lyxrow_funcs.C
1 #include <config.h>
2
3 #include "lyxrow_funcs.h"
4 #include "lyxtext.h"
5 #include "paragraph.h"
6 #include "lyxlayout.h"
7
8 #include <boost/next_prior.hpp>
9 #include <algorithm>
10
11 using lyx::pos_type;
12 using std::max;
13 using std::min;
14
15
16 bool isParEnd(LyXText const & lt, RowList::iterator rit)
17 {
18         RowList::iterator next_row = boost::next(rit);
19
20         return next_row == lt.rows().end() ||
21                 next_row->par() != rit->par();
22 }
23
24
25 pos_type lastPos(LyXText const & lt, RowList::iterator rit)
26 {
27         if (rit->par()->empty())
28                 return 0;
29
30         if (isParEnd(lt, rit)) {
31                 return rit->par()->size() - 1;
32         } else {
33                 return boost::next(rit)->pos() - 1;
34         }
35 }
36
37
38 namespace {
39
40 bool nextRowIsAllInset(Row const & row, pos_type last)
41 {
42         ParagraphList::iterator pit = row.par();
43
44         if (last + 1 >= pit->size())
45                 return false;
46
47         if (!pit->isInset(last + 1))
48                 return false;
49
50         Inset const * i = pit->getInset(last + 1);
51         return i->needFullRow() || i->display();
52 }
53
54 } // anon namespace
55
56
57 pos_type lastPrintablePos(LyXText const & lt, RowList::iterator rit)
58 {
59         pos_type const last = lastPos(lt, rit);
60
61         // if this row is an end of par, just act like lastPos()
62         if (isParEnd(lt, rit))
63                 return last;
64
65         bool const nextrownotinset = !nextRowIsAllInset(*rit, last);
66
67         if (nextrownotinset && rit->par()->isSeparator(last))
68                 return last - 1;
69
70         return last;
71 }
72
73
74 int numberOfSeparators(LyXText const & lt, RowList::iterator rit)
75 {
76         pos_type const last = lastPrintablePos(lt, rit);
77         ParagraphList::iterator pit = rit->par();
78
79         int n = 0;
80
81         pos_type p = max(rit->pos(), pit->beginningOfBody());
82         for (; p < last; ++p) {
83                 if (pit->isSeparator(p)) {
84                         ++n;
85                 }
86         }
87         return n;
88 }
89
90
91 // This is called _once_ from LyXText and should at least be moved into
92 // an anonymous namespace there. (Lgb)
93 int numberOfHfills(LyXText const & lt, RowList::iterator rit)
94 {
95         pos_type const last = lastPos(lt, rit);
96         pos_type first = rit->pos();
97         ParagraphList::iterator pit = rit->par();
98
99         // hfill *DO* count at the beginning of paragraphs!
100         if (first) {
101                 while (first < last && pit->isHfill(first)) {
102                         ++first;
103                 }
104         }
105
106         first = max(first, pit->beginningOfBody());
107
108         int n = 0;
109
110         // last, because the end is ignored!
111         for (pos_type p = first; p < last; ++p) {
112                 if (pit->isHfill(p))
113                         ++n;
114         }
115         return n;
116 }
117
118
119 // This is called _once_ from LyXText and should at least be moved into
120 // an anonymous namespace there. (Lgb)
121 int numberOfLabelHfills(LyXText const & lt, RowList::iterator rit)
122 {
123         pos_type last = lastPos(lt, rit);
124         pos_type first = rit->pos();
125         ParagraphList::iterator pit = rit->par();
126
127         // hfill *DO* count at the beginning of paragraphs!
128         if (first) {
129                 while (first < last && pit->isHfill(first))
130                         ++first;
131         }
132
133         last = min(last, pit->beginningOfBody());
134         int n = 0;
135
136         // last, because the end is ignored!
137         for (pos_type p = first; p < last; ++p) {
138                 if (pit->isHfill(p))
139                         ++n;
140         }
141         return n;
142 }
143
144
145 bool hfillExpansion(LyXText const & lt, RowList::iterator rit, pos_type pos)
146 {
147         ParagraphList::iterator pit = rit->par();
148
149         if (!pit->isHfill(pos))
150                 return false;
151
152         // at the end of a row it does not count
153         // unless another hfill exists on the line
154         if (pos >= lastPos(lt, rit)) {
155                 pos_type i = rit->pos();
156                 while (i < pos && !pit->isHfill(i)) {
157                         ++i;
158                 }
159                 if (i == pos) {
160                         return false;
161                 }
162         }
163
164         // at the beginning of a row it does not count, if it is not
165         // the first row of a paragaph
166         if (rit->isParStart())
167                 return true;
168
169         // in some labels it does not count
170         if (pit->layout()->margintype != MARGIN_MANUAL
171             && pos < pit->beginningOfBody())
172                 return false;
173
174         // if there is anything between the first char of the row and
175         // the specified position that is not a newline and not a hfill,
176         // the hfill will count, otherwise not
177         pos_type i = rit->pos();
178         while (i < pos && (pit->isNewline(i) || pit->isHfill(i)))
179                 ++i;
180
181         return i != pos;
182 }