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