]> git.lyx.org Git - lyx.git/blob - src/VSpace.cpp
Add Benjamin Piwowarski to contributors. Welcome to LyX!
[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 "Length.h"
20 #include "Text.h"
21 #include "TextMetrics.h" // for defaultRowHeight()
22
23 #include "support/convert.h"
24 #include "support/lstrings.h"
25
26 #include "support/lassert.h"
27
28 using namespace std;
29 using namespace lyx::support;
30
31
32 namespace lyx {
33
34 //
35 //  VSpace class
36 //
37
38 VSpace::VSpace()
39         : kind_(DEFSKIP), len_(), keep_(false)
40 {}
41
42
43 VSpace::VSpace(VSpaceKind k)
44         : kind_(k), len_(), keep_(false)
45 {}
46
47
48 VSpace::VSpace(Length const & l)
49         : kind_(LENGTH), len_(l), keep_(false)
50 {}
51
52
53 VSpace::VSpace(GlueLength const & l)
54         : kind_(LENGTH), len_(l), keep_(false)
55 {}
56
57
58 VSpace::VSpace(string const & data)
59         : kind_(DEFSKIP), len_(), keep_(false)
60 {
61         if (data.empty())
62                 return;
63
64         string input = rtrim(data);
65
66         size_t const length = input.length();
67
68         if (length > 1 && input[length - 1] == '*') {
69                 keep_ = true;
70                 input.erase(length - 1);
71         }
72
73         if (prefixIs(input, "defskip"))
74                 kind_ = DEFSKIP;
75         else if (prefixIs(input, "smallskip"))
76                 kind_ = SMALLSKIP;
77         else if (prefixIs(input, "medskip"))
78                 kind_ = MEDSKIP;
79         else if (prefixIs(input, "bigskip"))
80                 kind_ = BIGSKIP;
81         else if (prefixIs(input, "vfill"))
82                 kind_ = VFILL;
83         else if (isValidGlueLength(input, &len_))
84                 kind_ = LENGTH;
85         else if (isStrDbl(input)) {
86                 // This last one is for reading old .lyx files
87                 // without units in added_space_top/bottom.
88                 // Let unit default to centimeters here.
89                 kind_ = LENGTH;
90                 len_  = GlueLength(Length(convert<double>(input), Length::CM));
91         }
92 }
93
94
95 bool VSpace::operator==(VSpace const & other) const
96 {
97         if (kind_ != other.kind_)
98                 return false;
99
100         if (kind_ != LENGTH)
101                 return this->keep_ == other.keep_;
102
103         if (len_ != other.len_)
104                 return false;
105
106         return keep_ == other.keep_;
107 }
108
109
110 string const VSpace::asLyXCommand() const
111 {
112         string result;
113         switch (kind_) {
114         case DEFSKIP:   result = "defskip";      break;
115         case SMALLSKIP: result = "smallskip";    break;
116         case MEDSKIP:   result = "medskip";      break;
117         case BIGSKIP:   result = "bigskip";      break;
118         case VFILL:     result = "vfill";        break;
119         case LENGTH:    result = len_.asString(); break;
120         }
121         if (keep_)
122                 result += '*';
123         return result;
124 }
125
126
127 string const VSpace::asLatexCommand(BufferParams const & params) const
128 {
129         switch (kind_) {
130         case DEFSKIP:
131                 return params.getDefSkip().asLatexCommand(params);
132
133         case SMALLSKIP:
134                 return keep_ ? "\\vspace*{\\smallskipamount}" : "\\smallskip{}";
135
136         case MEDSKIP:
137                 return keep_ ? "\\vspace*{\\medskipamount}" : "\\medskip{}";
138
139         case BIGSKIP:
140                 return keep_ ? "\\vspace*{\\bigskipamount}" : "\\bigskip{}";
141
142         case VFILL:
143                 return keep_ ? "\\vspace*{\\fill}" : "\\vfill{}";
144
145         case LENGTH:
146                 return keep_ ? "\\vspace*{" + len_.asLatexString() + '}'
147                         : "\\vspace{" + len_.asLatexString() + '}';
148
149         default:
150                 LASSERT(false, /**/);
151                 return string();
152         }
153 }
154
155
156 docstring const VSpace::asGUIName() const
157 {
158         docstring result;
159         switch (kind_) {
160         case DEFSKIP:
161                 result = _("Default skip");
162                 break;
163         case SMALLSKIP:
164                 result = _("Small skip");
165                 break;
166         case MEDSKIP:
167                 result = _("Medium skip");
168                 break;
169         case BIGSKIP:
170                 result = _("Big skip");
171                 break;
172         case VFILL:
173                 result = _("Vertical fill");
174                 break;
175         case LENGTH:
176                 result = from_ascii(len_.asString());
177                 break;
178         }
179         if (keep_)
180                 result += ", " + _("protected");
181         return result;
182 }
183
184
185 string VSpace::asHTMLLength() const 
186 {
187         string result;
188         switch (kind_) {
189                 case DEFSKIP:   result = "2ex"; break;
190                 case SMALLSKIP: result = "1ex"; break;
191                 case MEDSKIP:   result = "3ex"; break;
192                 case BIGSKIP:   result = "5ex"; break;
193                 case LENGTH: {
194                         Length tmp = len_.len();
195                         if (tmp.value() > 0)
196                                 result = tmp.asHTMLString();
197                 }
198                 case VFILL:     break;
199         }
200         return result;
201 }
202
203
204 int VSpace::inPixels(BufferView const & bv) const
205 {
206         // Height of a normal line in pixels (zoom factor considered)
207         int const default_height = defaultRowHeight();
208
209         switch (kind_) {
210
211         case DEFSKIP:
212                 return bv.buffer().params().getDefSkip().inPixels(bv);
213
214         // This is how the skips are normally defined by LateX.
215         // But there should be some way to change this per document.
216         case SMALLSKIP:
217                 return default_height / 4;
218
219         case MEDSKIP:
220                 return default_height / 2;
221
222         case BIGSKIP:
223                 return default_height;
224
225         case VFILL:
226                 // leave space for the vfill symbol
227                 return 3 * default_height;
228
229         case LENGTH:
230                 return len_.len().inPixels(bv.workWidth());
231
232         default:
233                 LASSERT(false, /**/);
234                 return 0;
235         }
236 }
237
238
239 } // namespace lyx