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