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