]> git.lyx.org Git - lyx.git/blob - src/VSpace.cpp
Capitalize labels of floats, etc. Fixes #11993.
[lyx.git] / src / VSpace.cpp
1 /**
2  * \file VSpace.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Matthias Ettrich
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "VSpace.h"
14
15 #include "Buffer.h"
16 #include "BufferParams.h"
17 #include "BufferView.h"
18 #include "support/gettext.h"
19 #include "TextMetrics.h" // for defaultRowHeight()
20
21 #include "support/convert.h"
22 #include "support/Length.h"
23 #include "support/lstrings.h"
24
25 #include "support/lassert.h"
26
27 using namespace std;
28 using namespace lyx::support;
29
30
31 namespace lyx {
32
33 //
34 //  VSpace class
35 //
36
37 VSpace::VSpace()
38         : kind_(DEFSKIP), len_(), keep_(false)
39 {}
40
41
42 VSpace::VSpace(VSpaceKind k)
43         : kind_(k), len_(), keep_(false)
44 {}
45
46
47 VSpace::VSpace(Length const & l)
48         : kind_(LENGTH), len_(l), keep_(false)
49 {}
50
51
52 VSpace::VSpace(GlueLength const & l)
53         : kind_(LENGTH), len_(l), keep_(false)
54 {}
55
56
57 VSpace::VSpace(string const & data)
58         : kind_(DEFSKIP), len_(), keep_(false)
59 {
60         if (data.empty())
61                 return;
62
63         string input = rtrim(data);
64
65         size_t const length = input.length();
66
67         if (length > 1 && input[length - 1] == '*') {
68                 keep_ = true;
69                 input.erase(length - 1);
70         }
71
72         if (prefixIs(input, "defskip"))
73                 kind_ = DEFSKIP;
74         else if (prefixIs(input, "smallskip"))
75                 kind_ = SMALLSKIP;
76         else if (prefixIs(input, "medskip"))
77                 kind_ = MEDSKIP;
78         else if (prefixIs(input, "bigskip"))
79                 kind_ = BIGSKIP;
80         else if (prefixIs(input, "halfline"))
81                 kind_ = HALFLINE;
82         else if (prefixIs(input, "fullline"))
83                 kind_ = FULLLINE;
84         else if (prefixIs(input, "vfill"))
85                 kind_ = VFILL;
86         else if (isValidGlueLength(input, &len_))
87                 kind_ = LENGTH;
88         else if (isStrDbl(input)) {
89                 // This last one is for reading old .lyx files
90                 // without units in added_space_top/bottom.
91                 // Let unit default to centimeters here.
92                 kind_ = LENGTH;
93                 len_  = GlueLength(Length(convert<double>(input), Length::CM));
94         }
95 }
96
97
98 bool VSpace::operator==(VSpace const & other) const
99 {
100         if (kind_ != other.kind_)
101                 return false;
102
103         if (kind_ != LENGTH)
104                 return this->keep_ == other.keep_;
105
106         if (len_ != other.len_)
107                 return false;
108
109         return keep_ == other.keep_;
110 }
111
112
113 string const VSpace::asLyXCommand() const
114 {
115         string result;
116         switch (kind_) {
117         case DEFSKIP:
118                 result = "defskip";
119                 break;
120         case SMALLSKIP:
121                 result = "smallskip";
122                 break;
123         case MEDSKIP:
124                 result = "medskip";
125                 break;
126         case BIGSKIP:
127                 result = "bigskip";
128                 break;
129         case HALFLINE:
130                 result = "halfline";
131                 break;
132         case FULLLINE:
133                 result = "fullline";
134                 break;
135         case VFILL:
136                 result = "vfill";
137                 break;
138         case LENGTH:
139                 result = len_.asString();
140                 break;
141         }
142         if (keep_)
143                 result += '*';
144         return result;
145 }
146
147
148 string const VSpace::asLatexCommand(BufferParams const & params) const
149 {
150         switch (kind_) {
151         case DEFSKIP:
152                 return params.getDefSkip().asLatexCommand(params);
153
154         case SMALLSKIP:
155                 return keep_ ? "\\vspace*{\\smallskipamount}" : "\\smallskip{}";
156
157         case MEDSKIP:
158                 return keep_ ? "\\vspace*{\\medskipamount}" : "\\medskip{}";
159
160         case BIGSKIP:
161                 return keep_ ? "\\vspace*{\\bigskipamount}" : "\\bigskip{}";
162         
163         case HALFLINE:
164                 return keep_ ? "\\vspace*{.5\\baselineskip}" : "\\vspace{.5\\baselineskip}";
165
166         case FULLLINE:
167                 return keep_ ? "\\vspace*{\\baselineskip}" : "\\vspace{\\baselineskip}";
168
169         case VFILL:
170                 return keep_ ? "\\vspace*{\\fill}" : "\\vfill{}";
171
172         case LENGTH:
173                 return keep_ ? "\\vspace*{" + len_.asLatexString() + '}'
174                         : "\\vspace{" + len_.asLatexString() + '}';
175
176         default:
177                 LATTEST(false);
178                 // fall through in release mode
179         }
180         return string();
181 }
182
183
184 docstring const VSpace::asGUIName() const
185 {
186         docstring result;
187         switch (kind_) {
188         case DEFSKIP:
189                 result = _("Default skip");
190                 break;
191         case SMALLSKIP:
192                 result = _("Small skip");
193                 break;
194         case MEDSKIP:
195                 result = _("Medium skip");
196                 break;
197         case BIGSKIP:
198                 result = _("Big skip");
199                 break;
200         case HALFLINE:
201                 result = _("Half line height");
202                 break;
203         case FULLLINE:
204                 result = _("Line height");
205                 break;
206         case VFILL:
207                 result = _("Vertical fill");
208                 break;
209         case LENGTH:
210                 result = from_ascii(len_.asString());
211                 break;
212         }
213         if (keep_)
214                 result += ", " + _("protected");
215         return result;
216 }
217
218
219 string VSpace::asHTMLLength() const
220 {
221         string result;
222         switch (kind_) {
223                 case DEFSKIP:
224                         result = "2ex";
225                         break;
226                 case SMALLSKIP:
227                         result = "1ex";
228                         break;
229                 case MEDSKIP:
230                         result = "3ex";
231                         break;
232                 case BIGSKIP:
233                         result = "5ex";
234                         break;
235                 case HALFLINE:
236                         result = "0.6em";
237                         break;
238                 case FULLLINE:
239                         result = "1.2em";
240                         break;
241                 case LENGTH: {
242                         Length tmp = len_.len();
243                         if (tmp.value() > 0)
244                                 result = tmp.asHTMLString();
245                 }
246                 case VFILL:
247                         break;
248         }
249         return result;
250 }
251
252
253 int VSpace::inPixels(BufferView const & bv) const
254 {
255         // Height of a normal line in pixels (zoom factor considered)
256         int const default_height = defaultRowHeight();
257
258         switch (kind_) {
259
260         case DEFSKIP:
261                 return bv.buffer().params().getDefSkip().inPixels(bv);
262
263         // This is how the skips are normally defined by LaTeX.
264         // But there should be some way to change this per document.
265         case SMALLSKIP:
266                 return int(default_height / 4);
267
268         case MEDSKIP:
269                 return int(default_height / 2);
270
271         case BIGSKIP:
272                 return default_height;
273
274         case VFILL:
275                 // leave space for the vfill symbol
276                 return 3 * default_height;
277
278         case HALFLINE:
279                 return int(default_height / 2);
280
281         case FULLLINE:
282                 return default_height;
283
284         case LENGTH:
285                 return bv.inPixels(len_.len());
286
287         default:
288                 LATTEST(false);
289                 // fall through in release mode
290         }
291         return 0;
292 }
293
294
295 } // namespace lyx