]> git.lyx.org Git - lyx.git/blob - src/ParagraphParameters.cpp
document my LFUN changes in the past
[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 "Buffer.h"
20 #include "support/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 //FIXME This needs to be made a real method, so that getStatus()
264 //can return sensible information.
265 bool ParagraphParameters::canApply(
266         ParagraphParameters const & /*params*/, Layout const & /*layout*/)
267 {
268         return true;
269 }
270
271
272 void ParagraphParameters::write(ostream & os) const
273 {
274         // Maybe the paragraph has special spacing
275         spacing().writeFile(os, true);
276
277         // The labelwidth string used in lists.
278         if (!labelWidthString().empty())
279                 os << "\\labelwidthstring "
280                    << to_utf8(labelWidthString()) << '\n';
281
282         // Start of appendix?
283         if (startOfAppendix())
284                 os << "\\start_of_appendix\n";
285
286         // Noindent?
287         if (noindent())
288                 os << "\\noindent\n";
289
290         // Do we have a manual left indent?
291         if (!leftIndent().zero())
292                 os << "\\leftindent " << leftIndent().asString() << '\n';
293
294         // Alignment?
295         if (align() != LYX_ALIGN_LAYOUT) {
296                 int h = 0;
297                 switch (align()) {
298                 case LYX_ALIGN_LEFT: h = 1; break;
299                 case LYX_ALIGN_RIGHT: h = 2; break;
300                 case LYX_ALIGN_CENTER: h = 3; break;
301                 default: h = 0; break;
302                 }
303                 os << "\\align " << string_align[h] << '\n';
304         }
305 }
306
307
308 void params2string(Paragraph const & par, string & data)
309 {
310         // A local copy
311         ParagraphParameters params = par.params();
312
313         // This needs to be done separately
314         params.labelWidthString(par.getLabelWidthString());
315
316         ostringstream os;
317         params.write(os);
318
319         LayoutPtr const & layout = par.layout();
320
321         // Is alignment possible
322         os << "\\alignpossible " << layout->alignpossible << '\n';
323
324         /// set default alignment
325         os << "\\aligndefault " << layout->align << '\n';
326
327         /// paragraph is always in inset. This is redundant.
328         os << "\\ininset " << 1 << '\n';
329
330         data = os.str();
331 }
332
333
334 /*
335 bool operator==(ParagraphParameeters const & ps1,
336                 ParagraphParameeters const & ps2)
337 {
338         return
339                    ps1.spacing == ps2.spacing
340                 && ps1.noindent == ps2.noindent
341                 && ps1.align == ps2.align
342                 && ps1.depth == ps2.depth
343                 && ps1.start_of_appendix == ps2.start_of_appendix
344                 && ps1.appendix == ps2.appendix
345                 && ps1.labelstring == ps2.labelstring
346                 && ps1.labelwidthstring == ps2.labelwidthstring
347                 && ps1.leftindent == ps2.leftindent;
348 }
349 */
350
351
352 } // namespace lyx