]> git.lyx.org Git - lyx.git/blob - src/ParagraphParameters.C
Point fix, earlier forgotten
[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 #include "ParameterStruct.h"
19 #include "tex-strings.h"
20 #include "lyxlex.h"
21
22 #include "buffer.h"
23 #include "BufferView.h"
24 #include "Lsstream.h"
25 #include "gettext.h"
26 #include "paragraph.h"
27 #include "lyxtext.h"
28 #include "Lsstream.h"
29
30 #include "frontends/LyXView.h"
31
32 #include "support/lstrings.h"
33
34 #include <iostream>
35
36 using namespace lyx::support;
37
38 using std::ostream;
39
40 // Initialize static member var.
41 ShareContainer<ParameterStruct> ParagraphParameters::container;
42
43 ParagraphParameters::ParagraphParameters()
44 {
45         ParameterStruct tmp;
46         set_from_struct(tmp);
47 }
48
49
50 void ParagraphParameters::clear()
51 {
52         ParameterStruct tmp(*param);
53         tmp.line_top = false;
54         tmp.line_bottom = false;
55         tmp.pagebreak_top = false;
56         tmp.pagebreak_bottom = false;
57         tmp.added_space_top = VSpace(VSpace::NONE);
58         tmp.added_space_bottom = VSpace(VSpace::NONE);
59         tmp.spacing.set(Spacing::Default);
60         tmp.align = LYX_ALIGN_LAYOUT;
61         tmp.depth = 0;
62         tmp.noindent = false;
63         tmp.labelstring.erase();
64         tmp.labelwidthstring.erase();
65         tmp.start_of_appendix = false;
66         set_from_struct(tmp);
67 }
68
69
70 bool ParagraphParameters::sameLayout(ParagraphParameters const & pp) const
71 {
72         return param->align == pp.param->align &&
73                 param->line_bottom == pp.param->line_bottom &&
74                 param->pagebreak_bottom == pp.param->pagebreak_bottom &&
75                 param->added_space_bottom == pp.param->added_space_bottom &&
76
77                 param->line_top == pp.param->line_top &&
78                 param->pagebreak_top == pp.param->pagebreak_top &&
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 bool ParagraphParameters::lineTop() const
150 {
151         return param->line_top;
152 }
153
154
155 void ParagraphParameters::lineTop(bool lt)
156 {
157         ParameterStruct tmp(*param);
158         tmp.line_top = lt;
159         set_from_struct(tmp);
160 }
161
162
163 bool ParagraphParameters::lineBottom() const
164 {
165         return param->line_bottom;
166 }
167
168
169 void ParagraphParameters::lineBottom(bool lb)
170 {
171         ParameterStruct tmp(*param);
172         tmp.line_bottom = lb;
173         set_from_struct(tmp);
174 }
175
176
177 bool ParagraphParameters::pagebreakTop() const
178 {
179         return param->pagebreak_top;
180 }
181
182
183 void ParagraphParameters::pagebreakTop(bool pbt)
184 {
185         ParameterStruct tmp(*param);
186         tmp.pagebreak_top = pbt;
187         set_from_struct(tmp);
188 }
189
190
191 bool ParagraphParameters::pagebreakBottom() const
192 {
193         return param->pagebreak_bottom;
194 }
195
196
197 void ParagraphParameters::pagebreakBottom(bool pbb)
198 {
199         ParameterStruct tmp(*param);
200         tmp.pagebreak_bottom = pbb;
201         set_from_struct(tmp);
202 }
203
204
205 LyXAlignment ParagraphParameters::align() const
206 {
207         return param->align;
208 }
209
210
211 void ParagraphParameters::align(LyXAlignment la)
212 {
213         ParameterStruct tmp(*param);
214         tmp.align = la;
215         set_from_struct(tmp);
216 }
217
218
219 void ParagraphParameters::depth(depth_type d)
220 {
221         ParameterStruct tmp(*param);
222         tmp.depth = d;
223         set_from_struct(tmp);
224 }
225
226
227 bool ParagraphParameters::startOfAppendix() const
228 {
229         return param->start_of_appendix;
230 }
231
232
233 void ParagraphParameters::startOfAppendix(bool soa)
234 {
235         ParameterStruct tmp(*param);
236         tmp.start_of_appendix = soa;
237         set_from_struct(tmp);
238 }
239
240
241 bool ParagraphParameters::appendix() const
242 {
243         return param->appendix;
244 }
245
246
247 void ParagraphParameters::appendix(bool a)
248 {
249         ParameterStruct tmp(*param);
250         tmp.appendix = a;
251         set_from_struct(tmp);
252 }
253
254
255 string const & ParagraphParameters::labelString() const
256 {
257         return param->labelstring;
258 }
259
260
261 void ParagraphParameters::labelString(string const & ls)
262 {
263         ParameterStruct tmp(*param);
264         tmp.labelstring = ls;
265         set_from_struct(tmp);
266 }
267
268
269 string const & ParagraphParameters::labelWidthString() const
270 {
271         return param->labelwidthstring;
272 }
273
274
275 void ParagraphParameters::labelWidthString(string const & lws)
276 {
277         ParameterStruct tmp(*param);
278         tmp.labelwidthstring = lws;
279         set_from_struct(tmp);
280 }
281
282
283 LyXLength const & ParagraphParameters::leftIndent() const
284 {
285         return param->leftindent;
286 }
287
288
289 void ParagraphParameters::leftIndent(LyXLength const & li)
290 {
291         ParameterStruct tmp(*param);
292         tmp.leftindent = li;
293         set_from_struct(tmp);
294 }
295
296
297 void ParagraphParameters::read(LyXLex & lex)
298 {
299         while (lex.isOK()) {
300                 lex.nextToken();
301                 string const token = lex.getString();
302
303                 if (token.empty())
304                         continue;
305
306                 if (token[0] != '\\') {
307                         lex.pushToken(token);
308                         break;
309                 }
310
311                 if (token == "\\noindent") {
312                         noindent(true);
313                 } else if (token == "\\leftindent") {
314                         lex.nextToken();
315                         LyXLength value(lex.getString());
316                         leftIndent(value);
317                 } else if (token == "\\fill_top") {
318                         spaceTop(VSpace(VSpace::VFILL));
319                 } else if (token == "\\fill_bottom") {
320                         spaceBottom(VSpace(VSpace::VFILL));
321                 } else if (token == "\\line_top") {
322                         lineTop(true);
323                 } else if (token == "\\line_bottom") {
324                         lineBottom(true);
325                 } else if (token == "\\pagebreak_top") {
326                         pagebreakTop(true);
327                 } else if (token == "\\pagebreak_bottom") {
328                         pagebreakBottom(true);
329                 } else if (token == "\\start_of_appendix") {
330                         startOfAppendix(true);
331                 } else if (token == "\\paragraph_spacing") {
332                         lex.next();
333                         string const tmp = rtrim(lex.getString());
334                         if (tmp == "single") {
335                                 spacing(Spacing(Spacing::Single));
336                         } else if (tmp == "onehalf") {
337                                 spacing(Spacing(Spacing::Onehalf));
338                         } else if (tmp == "double") {
339                                 spacing(Spacing(Spacing::Double));
340                         } else if (tmp == "other") {
341                                 lex.next();
342                                 spacing(Spacing(Spacing::Other,
343                                                  lex.getFloat()));
344                         } else {
345                                 lex.printError("Unknown spacing token: '$$Token'");
346                         }
347                 } else if (token == "\\align") {
348                         int tmpret = lex.findToken(string_align);
349                         if (tmpret == -1)
350                                 ++tmpret;
351                         align(LyXAlignment(1 << tmpret));
352                 } else if (token == "\\added_space_top") {
353                         lex.nextToken();
354                         VSpace value = VSpace(lex.getString());
355                         // only add the length when value > 0 or
356                         // with option keep
357                         if ((value.length().len().value() != 0) ||
358                             value.keep() ||
359                             (value.kind() != VSpace::LENGTH))
360                                 spaceTop(value);
361                 } else if (token == "\\added_space_bottom") {
362                         lex.nextToken();
363                         VSpace value = VSpace(lex.getString());
364                         // only add the length when value > 0 or
365                         // with option keep
366                         if ((value.length().len().value() != 0) ||
367                            value.keep() ||
368                             (value.kind() != VSpace::LENGTH))
369                                 spaceBottom(value);
370                 } else if (token == "\\labelwidthstring") {
371                         lex.eatLine();
372                         labelWidthString(lex.getString());
373                 } else {
374                         lex.pushToken(token);
375                         break;
376                 }
377         }
378 }
379
380
381 void ParagraphParameters::write(ostream & os) const
382 {
383         // Maybe some vertical spaces.
384         if (spaceTop().kind() != VSpace::NONE)
385                 os << "\\added_space_top "
386                    << spaceTop().asLyXCommand() << ' ';
387         if (spaceBottom().kind() != VSpace::NONE)
388                 os << "\\added_space_bottom "
389                    << spaceBottom().asLyXCommand() << ' ';
390
391         // Maybe the paragraph has special spacing
392         spacing().writeFile(os, true);
393
394         // The labelwidth string used in lists.
395         if (!labelWidthString().empty())
396                 os << "\\labelwidthstring "
397                    << labelWidthString() << '\n';
398
399         // Lines above or below?
400         if (lineTop())
401                 os << "\\line_top ";
402         if (lineBottom())
403                 os << "\\line_bottom ";
404
405         // Pagebreaks above or below?
406         if (pagebreakTop())
407                 os << "\\pagebreak_top ";
408         if (pagebreakBottom())
409                 os << "\\pagebreak_bottom ";
410
411         // Start of appendix?
412         if (startOfAppendix())
413                 os << "\\start_of_appendix ";
414
415         // Noindent?
416         if (noindent())
417                 os << "\\noindent ";
418
419         // Do we have a manual left indent?
420         if (!leftIndent().zero())
421                 os << "\\leftindent " << leftIndent().asString()
422                    << ' ';
423
424         // Alignment?
425         if (align() != LYX_ALIGN_LAYOUT) {
426                 int h = 0;
427                 switch (align()) {
428                 case LYX_ALIGN_LEFT: h = 1; break;
429                 case LYX_ALIGN_RIGHT: h = 2; break;
430                 case LYX_ALIGN_CENTER: h = 3; break;
431                 default: h = 0; break;
432                 }
433                 os << "\\align " << string_align[h] << ' ';
434         }
435 }
436
437
438
439 void setParagraphParams(BufferView & bv, string const & data)
440 {
441         istringstream is(STRCONV(data));
442         LyXLex lex(0,0);
443         lex.setStream(is);
444
445         ParagraphParameters params;
446         params.read(lex);
447
448         LyXText * text = bv.getLyXText();
449         text->setParagraph(params.lineTop(),
450                            params.lineBottom(),
451                            params.pagebreakTop(),
452                            params.pagebreakBottom(),
453                            params.spaceTop(),
454                            params.spaceBottom(),
455                            params.spacing(),
456                            params.align(),
457                            params.labelWidthString(),
458                            params.noindent());
459
460         bv.update();
461         bv.owner()->message(_("Paragraph layout set"));
462 }
463
464
465 void params2string(Paragraph const & par, string & data)
466 {
467         // A local copy
468         ParagraphParameters params = par.params();
469
470         // This needs to be done separately
471         params.labelWidthString(par.getLabelWidthString());
472
473         // Alignment
474         LyXLayout_ptr const & layout = par.layout();
475         if (params.align() == LYX_ALIGN_LAYOUT)
476                 params.align(layout->align);
477
478         ostringstream os;
479         params.write(os);
480
481         // Is alignment possible
482         os << '\n' << "\\alignpossible " << layout->alignpossible << '\n';
483
484         /// set default alignment
485         os << "\\aligndefault " << layout->align << '\n';
486
487         /// is paragraph in inset
488         os << "\\ininset " << (par.inInset()?1:0) << '\n';
489
490         data = STRCONV(os.str());
491 }