]> git.lyx.org Git - lyx.git/blob - src/ParagraphParameters.C
90ca29c7303f10a07125579543fcbd9c708a5cde
[lyx.git] / src / ParagraphParameters.C
1 #include <config.h>
2
3 #include "ParagraphParameters.h"
4 #include "ParameterStruct.h"
5 #include "tex-strings.h"
6 #include "lyxlex.h"
7
8 #include "support/lstrings.h"
9
10 #include <iostream>
11
12 using std::ostream;
13
14 // Initialize static member var.
15 ShareContainer<ParameterStruct> ParagraphParameters::container;
16
17 ParagraphParameters::ParagraphParameters()
18 {
19         ParameterStruct tmp;
20         set_from_struct(tmp);
21 }
22
23
24 void ParagraphParameters::clear()
25 {
26         ParameterStruct tmp(*param);
27         tmp.line_top = false;
28         tmp.line_bottom = false;
29         tmp.pagebreak_top = false;
30         tmp.pagebreak_bottom = false;
31         tmp.added_space_top = VSpace(VSpace::NONE);
32         tmp.added_space_bottom = VSpace(VSpace::NONE);
33         tmp.spacing.set(Spacing::Default);
34         tmp.align = LYX_ALIGN_LAYOUT;
35         tmp.depth = 0;
36         tmp.noindent = false;
37         tmp.labelstring.erase();
38         tmp.labelwidthstring.erase();
39         tmp.start_of_appendix = false;
40         set_from_struct(tmp);
41 }
42
43
44 bool ParagraphParameters::sameLayout(ParagraphParameters const & pp) const
45 {
46         return param->align == pp.param->align &&
47                 param->line_bottom == pp.param->line_bottom &&
48                 param->pagebreak_bottom == pp.param->pagebreak_bottom &&
49                 param->added_space_bottom == pp.param->added_space_bottom &&
50
51                 param->line_top == pp.param->line_top &&
52                 param->pagebreak_top == pp.param->pagebreak_top &&
53                 param->added_space_top == pp.param->added_space_top &&
54                 param->spacing == pp.param->spacing &&
55                 param->noindent == pp.param->noindent &&
56                 param->depth == pp.param->depth;
57 }
58
59
60 void ParagraphParameters::set_from_struct(ParameterStruct const & ps)
61 {
62         // get new param from container with tmp as template
63         param = container.get(ps);
64 }
65
66
67 VSpace const & ParagraphParameters::spaceTop() const
68 {
69         return param->added_space_top;
70 }
71
72
73 void ParagraphParameters::spaceTop(VSpace const & vs)
74 {
75         ParameterStruct tmp(*param);
76         tmp.added_space_top = vs;
77         set_from_struct(tmp);
78 }
79
80
81 VSpace const & ParagraphParameters::spaceBottom() const
82 {
83         return param->added_space_bottom;
84 }
85
86
87 void ParagraphParameters::spaceBottom(VSpace const & vs)
88 {
89         ParameterStruct tmp(*param);
90         tmp.added_space_bottom = vs;
91         set_from_struct(tmp);
92 }
93
94
95 Spacing const & ParagraphParameters::spacing() const
96 {
97         return param->spacing;
98 }
99
100
101 void ParagraphParameters::spacing(Spacing const & s)
102 {
103         ParameterStruct tmp(*param);
104         tmp.spacing = s;
105         set_from_struct(tmp);
106 }
107
108
109 bool ParagraphParameters::noindent() const
110 {
111         return param->noindent;
112 }
113
114
115 void ParagraphParameters::noindent(bool ni)
116 {
117         ParameterStruct tmp(*param);
118         tmp.noindent = ni;
119         set_from_struct(tmp);
120 }
121
122
123 bool ParagraphParameters::lineTop() const
124 {
125         return param->line_top;
126 }
127
128
129 void ParagraphParameters::lineTop(bool lt)
130 {
131         ParameterStruct tmp(*param);
132         tmp.line_top = lt;
133         set_from_struct(tmp);
134 }
135
136
137 bool ParagraphParameters::lineBottom() const
138 {
139         return param->line_bottom;
140 }
141
142
143 void ParagraphParameters::lineBottom(bool lb)
144 {
145         ParameterStruct tmp(*param);
146         tmp.line_bottom = lb;
147         set_from_struct(tmp);
148 }
149
150
151 bool ParagraphParameters::pagebreakTop() const
152 {
153         return param->pagebreak_top;
154 }
155
156
157 void ParagraphParameters::pagebreakTop(bool pbt)
158 {
159         ParameterStruct tmp(*param);
160         tmp.pagebreak_top = pbt;
161         set_from_struct(tmp);
162 }
163
164
165 bool ParagraphParameters::pagebreakBottom() const
166 {
167         return param->pagebreak_bottom;
168 }
169
170
171 void ParagraphParameters::pagebreakBottom(bool pbb)
172 {
173         ParameterStruct tmp(*param);
174         tmp.pagebreak_bottom = pbb;
175         set_from_struct(tmp);
176 }
177
178
179 LyXAlignment ParagraphParameters::align() const
180 {
181         return param->align;
182 }
183
184
185 void ParagraphParameters::align(LyXAlignment la)
186 {
187         ParameterStruct tmp(*param);
188         tmp.align = la;
189         set_from_struct(tmp);
190 }
191
192
193 void ParagraphParameters::depth(depth_type d)
194 {
195         ParameterStruct tmp(*param);
196         tmp.depth = d;
197         set_from_struct(tmp);
198 }
199
200
201 bool ParagraphParameters::startOfAppendix() const
202 {
203         return param->start_of_appendix;
204 }
205
206
207 void ParagraphParameters::startOfAppendix(bool soa)
208 {
209         ParameterStruct tmp(*param);
210         tmp.start_of_appendix = soa;
211         set_from_struct(tmp);
212 }
213
214
215 bool ParagraphParameters::appendix() const
216 {
217         return param->appendix;
218 }
219
220
221 void ParagraphParameters::appendix(bool a)
222 {
223         ParameterStruct tmp(*param);
224         tmp.appendix = a;
225         set_from_struct(tmp);
226 }
227
228
229 string const & ParagraphParameters::labelString() const
230 {
231         return param->labelstring;
232 }
233
234
235 void ParagraphParameters::labelString(string const & ls)
236 {
237         ParameterStruct tmp(*param);
238         tmp.labelstring = ls;
239         set_from_struct(tmp);
240 }
241
242
243 string const & ParagraphParameters::labelWidthString() const
244 {
245         return param->labelwidthstring;
246 }
247
248
249 void ParagraphParameters::labelWidthString(string const & lws)
250 {
251         ParameterStruct tmp(*param);
252         tmp.labelwidthstring = lws;
253         set_from_struct(tmp);
254 }
255
256
257 LyXLength const & ParagraphParameters::leftIndent() const
258 {
259         return param->leftindent;
260 }
261
262
263 void ParagraphParameters::leftIndent(LyXLength const & li)
264 {
265         ParameterStruct tmp(*param);
266         tmp.leftindent = li;
267         set_from_struct(tmp);
268 }
269
270
271 void ParagraphParameters::read(LyXLex & lex)
272 {
273         while (lex.isOK()) {
274                 lex.nextToken();
275                 string const token = lex.getString();
276
277                 if (token.empty())
278                         continue;
279
280                 if (token[0] != '\\') {
281                         lex.pushToken(token);
282                         break;
283                 }
284
285                 if (token == "\\noindent") {
286                         noindent(true);
287                 } else if (token == "\\leftindent") {
288                         lex.nextToken();
289                         LyXLength value(lex.getString());
290                         leftIndent(value);
291                 } else if (token == "\\fill_top") {
292                         spaceTop(VSpace(VSpace::VFILL));
293                 } else if (token == "\\fill_bottom") {
294                         spaceBottom(VSpace(VSpace::VFILL));
295                 } else if (token == "\\line_top") {
296                         lineTop(true);
297                 } else if (token == "\\line_bottom") {
298                         lineBottom(true);
299                 } else if (token == "\\pagebreak_top") {
300                         pagebreakTop(true);
301                 } else if (token == "\\pagebreak_bottom") {
302                         pagebreakBottom(true);
303                 } else if (token == "\\start_of_appendix") {
304                         startOfAppendix(true);
305                 } else if (token == "\\paragraph_spacing") {
306                         lex.next();
307                         string const tmp = rtrim(lex.getString());
308                         if (tmp == "single") {
309                                 spacing(Spacing(Spacing::Single));
310                         } else if (tmp == "onehalf") {
311                                 spacing(Spacing(Spacing::Onehalf));
312                         } else if (tmp == "double") {
313                                 spacing(Spacing(Spacing::Double));
314                         } else if (tmp == "other") {
315                                 lex.next();
316                                 spacing(Spacing(Spacing::Other,
317                                                  lex.getFloat()));
318                         } else {
319                                 lex.printError("Unknown spacing token: '$$Token'");
320                         }
321                 } else if (token == "\\align") {
322                         int tmpret = lex.findToken(string_align);
323                         if (tmpret == -1)
324                                 ++tmpret;
325                         int const tmpret2 = int(pow(2.0, tmpret));
326                         align(LyXAlignment(tmpret2));
327                 } else if (token == "\\added_space_top") {
328                         lex.nextToken();
329                         VSpace value = VSpace(lex.getString());
330                         // only add the length when value > 0 or
331                         // with option keep
332                         if ((value.length().len().value() != 0) ||
333                             value.keep() ||
334                             (value.kind() != VSpace::LENGTH))
335                                 spaceTop(value);
336                 } else if (token == "\\added_space_bottom") {
337                         lex.nextToken();
338                         VSpace value = VSpace(lex.getString());
339                         // only add the length when value > 0 or
340                         // with option keep
341                         if ((value.length().len().value() != 0) ||
342                            value.keep() ||
343                             (value.kind() != VSpace::LENGTH))
344                                 spaceBottom(value);
345                 } else if (token == "\\labelwidthstring") {
346                         lex.eatLine();
347                         labelWidthString(lex.getString());
348                 } else {
349                         lex.pushToken(token);
350                         break;
351                 }
352         }
353 }
354
355
356 void ParagraphParameters::write(ostream & os) const
357 {
358         // Maybe some vertical spaces.
359         if (spaceTop().kind() != VSpace::NONE)
360                 os << "\\added_space_top "
361                    << spaceTop().asLyXCommand() << ' ';
362         if (spaceBottom().kind() != VSpace::NONE)
363                 os << "\\added_space_bottom "
364                    << spaceBottom().asLyXCommand() << ' ';
365
366         // Maybe the paragraph has special spacing
367         spacing().writeFile(os, true);
368
369         // The labelwidth string used in lists.
370         if (!labelWidthString().empty())
371                 os << "\\labelwidthstring "
372                    << labelWidthString() << '\n';
373
374         // Lines above or below?
375         if (lineTop())
376                 os << "\\line_top ";
377         if (lineBottom())
378                 os << "\\line_bottom ";
379
380         // Pagebreaks above or below?
381         if (pagebreakTop())
382                 os << "\\pagebreak_top ";
383         if (pagebreakBottom())
384                 os << "\\pagebreak_bottom ";
385
386         // Start of appendix?
387         if (startOfAppendix())
388                 os << "\\start_of_appendix ";
389
390         // Noindent?
391         if (noindent())
392                 os << "\\noindent ";
393
394         // Do we have a manual left indent?
395         if (!leftIndent().zero())
396                 os << "\\leftindent " << leftIndent().asString()
397                    << ' ';
398
399         // Alignment?
400         if (align() != LYX_ALIGN_LAYOUT) {
401                 int h = 0;
402                 switch (align()) {
403                 case LYX_ALIGN_LEFT: h = 1; break;
404                 case LYX_ALIGN_RIGHT: h = 2; break;
405                 case LYX_ALIGN_CENTER: h = 3; break;
406                 default: h = 0; break;
407                 }
408                 os << "\\align " << string_align[h] << ' ';
409         }
410 }