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