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