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