]> git.lyx.org Git - lyx.git/blob - src/ParagraphParameters.cpp
72b2286b1284588385a5adaa924fa863dbae2f14
[lyx.git] / src / ParagraphParameters.cpp
1 /**
2  * \file ParagraphParameters.cpp
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 "Layout.h"
20 #include "Lexer.h"
21 #include "Paragraph.h"
22
23 #include "support/debug.h"
24 #include "support/docstring.h"
25 #include "support/lstrings.h"
26
27 #include <sstream>
28
29 using namespace std;
30 using namespace lyx::support;
31
32 namespace lyx {
33
34
35 //NOTE The order of these MUST be the same as in Layout.h.
36 static char const * const string_align[] = {
37         "block", "left", "right", "center", "default", ""
38 };
39
40
41 ParagraphParameters::ParagraphParameters()
42         : noindent_(false),
43                 start_of_appendix_(false), appendix_(false),
44           align_(LYX_ALIGN_LAYOUT), depth_(0)
45 {}
46
47
48 void ParagraphParameters::clear()
49 {
50         operator=(ParagraphParameters());
51 }
52
53
54 depth_type ParagraphParameters::depth() const
55 {
56         return depth_;
57 }
58
59
60 bool ParagraphParameters::sameLayout(ParagraphParameters const & pp) const
61 {
62         return align_ == pp.align_
63                 && spacing_ == pp.spacing_
64                 && noindent_ == pp.noindent_
65                 && depth_ == pp.depth_;
66 }
67
68
69 Spacing const & ParagraphParameters::spacing() const
70 {
71         return spacing_;
72 }
73
74
75 void ParagraphParameters::spacing(Spacing const & s)
76 {
77         spacing_ = s;
78 }
79
80
81 bool ParagraphParameters::noindent() const
82 {
83         return noindent_;
84 }
85
86
87 void ParagraphParameters::noindent(bool ni)
88 {
89         noindent_ = ni;
90 }
91
92
93 LyXAlignment ParagraphParameters::align() const
94 {
95         return align_;
96 }
97
98
99 void ParagraphParameters::align(LyXAlignment la)
100 {
101         align_ = la;
102 }
103
104
105 void ParagraphParameters::depth(depth_type d)
106 {
107         depth_ = d;
108 }
109
110
111 bool ParagraphParameters::startOfAppendix() const
112 {
113         return start_of_appendix_;
114 }
115
116
117 void ParagraphParameters::startOfAppendix(bool soa)
118 {
119         start_of_appendix_ = soa;
120 }
121
122
123 bool ParagraphParameters::appendix() const
124 {
125         return appendix_;
126 }
127
128
129 void ParagraphParameters::appendix(bool a)
130 {
131         appendix_ = a;
132 }
133
134
135 docstring const & ParagraphParameters::labelString() const
136 {
137         return labelstring_;
138 }
139
140
141 void ParagraphParameters::labelString(docstring const & ls)
142 {
143         labelstring_ = ls;
144 }
145
146
147 docstring const & ParagraphParameters::labelWidthString() const
148 {
149         return labelwidthstring_;
150 }
151
152
153 void ParagraphParameters::labelWidthString(docstring const & lws)
154 {
155         labelwidthstring_ = lws;
156 }
157
158
159 Length const & ParagraphParameters::leftIndent() const
160 {
161         return leftindent_;
162 }
163
164
165 void ParagraphParameters::leftIndent(Length const & li)
166 {
167         leftindent_ = li;
168 }
169
170
171 void ParagraphParameters::read(string const & str, bool merge)
172 {
173         istringstream is(str);
174         Lexer lex;
175         lex.setStream(is);
176         read(lex, merge);
177 }
178
179
180 void ParagraphParameters::read(Lexer & lex, bool merge)
181 {
182         if (!merge)
183                 clear();
184         while (lex.isOK()) {
185                 lex.nextToken();
186                 string const token = lex.getString();
187
188                 if (token.empty())
189                         continue;
190
191                 if (token[0] != '\\') {
192                         lex.pushToken(token);
193                         break;
194                 }
195
196                 if (token == "\\noindent") {
197                         noindent(true);
198                 } else if (token == "\\indent") {
199                         //not found in LyX files but can be used with lfuns
200                         noindent(false);
201                 } else if (token == "\\indent-toggle") {
202                         //not found in LyX files but can be used with lfuns
203                         noindent(!noindent());
204                 } else if (token == "\\leftindent") {
205                         lex.next();
206                         Length value(lex.getString());
207                         leftIndent(value);
208                 } else if (token == "\\start_of_appendix") {
209                         startOfAppendix(true);
210                 } else if (token == "\\paragraph_spacing") {
211                         lex.next();
212                         string const tmp = rtrim(lex.getString());
213                         if (tmp == "default") {
214                                 //not found in LyX files but can be used with lfuns
215                                 spacing(Spacing(Spacing::Default));
216                         } else if (tmp == "single") {
217                                 spacing(Spacing(Spacing::Single));
218                         } else if (tmp == "onehalf") {
219                                 spacing(Spacing(Spacing::Onehalf));
220                         } else if (tmp == "double") {
221                                 spacing(Spacing(Spacing::Double));
222                         } else if (tmp == "other") {
223                                 lex.next();
224                                 spacing(Spacing(Spacing::Other,
225                                                  lex.getString()));
226                         } else {
227                                 lex.printError("Unknown spacing token: '$$Token'");
228                         }
229                 } else if (token == "\\align") {
230                         lex.next();
231                         int tmpret = findToken(string_align, lex.getString());
232                         if (tmpret == -1)
233                                 ++tmpret;
234                         align(LyXAlignment(1 << tmpret));
235                 } else if (token == "\\labelwidthstring") {
236                         lex.eatLine();
237                         labelWidthString(lex.getDocString());
238                 } else {
239                         lex.pushToken(token);
240                         break;
241                 }
242         }
243 }
244
245
246 void ParagraphParameters::apply(
247                 ParagraphParameters const & params, Layout const & layout)
248 {
249         spacing(params.spacing());
250         // does the layout allow the new alignment?
251         if (params.align() & layout.alignpossible)
252                 align(params.align());
253         labelWidthString(params.labelWidthString());
254         noindent(params.noindent());
255 }
256
257
258 void ParagraphParameters::write(ostream & os) const
259 {
260         // Maybe the paragraph has special spacing
261         spacing().writeFile(os, true);
262
263         // The labelwidth string used in lists.
264         if (!labelWidthString().empty())
265                 os << "\\labelwidthstring "
266                    << to_utf8(labelWidthString()) << '\n';
267
268         // Start of appendix?
269         if (startOfAppendix())
270                 os << "\\start_of_appendix\n";
271
272         // Noindent?
273         if (noindent())
274                 os << "\\noindent\n";
275
276         // Do we have a manual left indent?
277         if (!leftIndent().zero())
278                 os << "\\leftindent " << leftIndent().asString() << '\n';
279
280         // Alignment?
281         if (align() != LYX_ALIGN_LAYOUT) {
282                 int h = 0;
283                 switch (align()) {
284                 case LYX_ALIGN_LEFT: h = 1; break;
285                 case LYX_ALIGN_RIGHT: h = 2; break;
286                 case LYX_ALIGN_CENTER: h = 3; break;
287                 default: h = 0; break;
288                 }
289                 os << "\\align " << string_align[h] << '\n';
290         }
291 }
292
293
294 void params2string(Paragraph const & par, string & data)
295 {
296         // A local copy
297         ParagraphParameters params = par.params();
298
299         // This needs to be done separately
300         params.labelWidthString(par.getLabelWidthString());
301
302         ostringstream os;
303         params.write(os);
304
305         Layout const & layout = par.layout();
306
307         // Is alignment possible
308         os << "\\alignpossible " << layout.alignpossible << '\n';
309
310         /// set default alignment
311         os << "\\aligndefault " << layout.align << '\n';
312
313         /// paragraph is always in inset. This is redundant.
314         os << "\\ininset " << 1 << '\n';
315
316         data = os.str();
317 }
318
319
320 LyXErr & operator<<(LyXErr & os, ParagraphParameters const & parp) {
321         parp.write(os.stream());
322         return os;
323 }
324
325
326 /*
327 bool operator==(ParagraphParameeters const & ps1,
328                 ParagraphParameeters const & ps2)
329 {
330         return
331                    ps1.spacing == ps2.spacing
332                 && ps1.noindent == ps2.noindent
333                 && ps1.align == ps2.align
334                 && ps1.depth == ps2.depth
335                 && ps1.start_of_appendix == ps2.start_of_appendix
336                 && ps1.appendix == ps2.appendix
337                 && ps1.labelstring == ps2.labelstring
338                 && ps1.labelwidthstring == ps2.labelwidthstring
339                 && ps1.leftindent == ps2.leftindent;
340 }
341 */
342
343
344 } // namespace lyx