]> git.lyx.org Git - lyx.git/blob - src/lyxrow_funcs.C
next try...
[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
13 using std::max;
14 using std::min;
15
16
17 bool isParEnd(LyXText const & lt,
18         ParagraphList::iterator pit, RowList::iterator rit)
19 {
20         RowList::iterator next_row = boost::next(rit);
21         return next_row == lt.rows().end() || lt.getPar(next_row) != pit;
22 }
23
24
25 pos_type lastPos(LyXText const & lt,
26         ParagraphList::iterator pit, RowList::iterator rit)
27 {
28         if (pit->empty())
29                 return 0;
30
31         if (isParEnd(lt, pit, rit))
32                 return pit->size() - 1;
33
34         return boost::next(rit)->pos() - 1;
35 }
36
37
38 namespace {
39
40 bool nextRowIsAllInset(
41         ParagraphList::iterator pit, RowList::iterator rit, pos_type last)
42 {
43         if (last + 1 >= pit->size())
44                 return false;
45
46         if (!pit->isInset(last + 1))
47                 return false;
48
49         InsetOld const * i = pit->getInset(last + 1);
50         return i->needFullRow() || i->display();
51 }
52
53 } // anon namespace
54
55
56 pos_type lastPrintablePos(LyXText const & lt,
57         ParagraphList::iterator pit, RowList::iterator rit)
58 {
59         pos_type const last = lastPos(lt, pit, rit);
60
61         // if this row is an end of par, just act like lastPos()
62         if (isParEnd(lt, pit, rit))
63                 return last;
64
65         if (!nextRowIsAllInset(pit, rit, last) && pit->isSeparator(last))
66                 return last - 1;
67
68         return last;
69 }
70
71
72 int numberOfSeparators(LyXText const & lt,
73         ParagraphList::iterator pit, RowList::iterator rit)
74 {
75         pos_type const last = lastPrintablePos(lt, pit, rit);
76         int n = 0;
77         pos_type p = max(rit->pos(), pit->beginningOfBody());
78         for ( ; p < last; ++p)
79                 if (pit->isSeparator(p))
80                         ++n;
81         return n;
82 }
83
84
85 // This is called _once_ from LyXText and should at least be moved into
86 // an anonymous namespace there. (Lgb)
87 int numberOfHfills(LyXText const & lt,
88         ParagraphList::iterator pit, RowList::iterator rit)
89 {
90         pos_type const last = lastPos(lt, pit, rit);
91         pos_type first = rit->pos();
92
93         // hfill *DO* count at the beginning of paragraphs!
94         if (first) {
95                 while (first < last && pit->isHfill(first))
96                         ++first;
97         }
98
99         first = max(first, pit->beginningOfBody());
100
101         int n = 0;
102
103         // last, because the end is ignored!
104         for (pos_type p = first; p < last; ++p) {
105                 if (pit->isHfill(p))
106                         ++n;
107         }
108         return n;
109 }
110
111
112 // This is called _once_ from LyXText and should at least be moved into
113 // an anonymous namespace there. (Lgb)
114 int numberOfLabelHfills(LyXText const & lt,
115         ParagraphList::iterator pit, RowList::iterator rit)
116 {
117         pos_type last = lastPos(lt, pit, rit);
118         pos_type first = rit->pos();
119
120         // hfill *DO* count at the beginning of paragraphs!
121         if (first) {
122                 while (first < last && pit->isHfill(first))
123                         ++first;
124         }
125
126         last = min(last, pit->beginningOfBody());
127         int n = 0;
128
129         // last, because the end is ignored!
130         for (pos_type p = first; p < last; ++p) {
131                 if (pit->isHfill(p))
132                         ++n;
133         }
134         return n;
135 }
136
137
138 bool hfillExpansion(LyXText const & lt,
139         ParagraphList::iterator pit, RowList::iterator rit, pos_type pos)
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, pit, 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 }