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