]> git.lyx.org Git - features.git/blob - src/insets/InsetNewline.cpp
Merge the two linebreak insets into one.
[features.git] / src / insets / InsetNewline.cpp
1 /**
2  * \file InsetNewline.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Jürgen Spitzmüller
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetNewline.h"
15
16 #include "FuncRequest.h"
17 #include "FuncStatus.h"
18 #include "Dimension.h"
19 #include "Lexer.h"
20 #include "MetricsInfo.h"
21 #include "OutputParams.h"
22
23 #include "frontends/FontMetrics.h"
24 #include "frontends/Painter.h"
25
26 #include "support/debug.h"
27 #include "support/docstring.h"
28 #include "support/docstream.h"
29
30 using namespace std;
31
32 namespace lyx {
33
34 InsetNewline::InsetNewline()
35 {}
36
37 void InsetNewlineParams::write(ostream & os) const
38 {
39         string command;
40         switch (kind) {
41         case InsetNewlineParams::NEWLINE:
42                 os << "newline";
43                 break;
44         case InsetNewlineParams::LINEBREAK:
45                 os <<  "linebreak";
46                 break;
47         }
48 }
49
50
51 void InsetNewlineParams::read(Lexer & lex)
52 {
53         lex.next();
54         string const command = lex.getString();
55
56         if (command == "newline")
57                 kind = InsetNewlineParams::NEWLINE;
58         else if (command == "linebreak")
59                 kind = InsetNewlineParams::LINEBREAK;
60         else
61                 lex.printError("InsetNewline: Unknown kind: `$$Token'");
62
63         string token;
64         lex >> token;
65         if (!lex)
66                 return;
67         if (token != "\\end_inset")
68                 lex.printError("Missing \\end_inset at this point. "
69                                "Read: `$$Token'");
70 }
71
72
73 void InsetNewline::write(ostream & os) const
74 {
75         os << "Newline ";
76         params_.write(os);
77 }
78
79
80 void InsetNewline::read(Lexer & lex)
81 {
82         params_.read(lex);
83 }
84
85
86 void InsetNewline::metrics(MetricsInfo & mi, Dimension & dim) const
87 {
88         frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
89         dim.asc = fm.maxAscent();
90         dim.des = fm.maxDescent();
91         dim.wid = fm.width('n');
92 }
93
94
95 void InsetNewline::doDispatch(Cursor & cur, FuncRequest & cmd)
96 {
97         switch (cmd.action) {
98
99         case LFUN_INSET_MODIFY: {
100                 InsetNewlineParams params;
101                 InsetNewlineMailer::string2params(to_utf8(cmd.argument()), params);
102                 params_.kind = params.kind;
103                 break;
104         }
105
106         default:
107                 Inset::doDispatch(cur, cmd);
108                 break;
109         }
110 }
111
112
113 bool InsetNewline::getStatus(Cursor & cur, FuncRequest const & cmd,
114         FuncStatus & status) const
115 {
116         switch (cmd.action) {
117         // we handle these
118         case LFUN_INSET_MODIFY:
119                 if (cmd.getArg(0) == "newline") {
120                         InsetNewlineParams params;
121                         InsetNewlineMailer::string2params(to_utf8(cmd.argument()), params);
122                         status.setOnOff(params_.kind == params.kind);
123                 } else
124                         status.enabled(true);
125                 return true;
126         default:
127                 return Inset::getStatus(cur, cmd, status);
128         }
129 }
130
131
132 ColorCode InsetNewline::ColorName() const
133 {
134         switch (params_.kind) {
135                 case InsetNewlineParams::NEWLINE:
136                         return Color_eolmarker;
137                         break;
138                 case InsetNewlineParams::LINEBREAK:
139                         return Color_pagebreak;
140                         break;
141                 default:
142                         return Color_eolmarker;
143                         break;
144         }
145 }
146
147
148 int InsetNewline::latex(odocstream & os, OutputParams const &) const
149 {
150         switch (params_.kind) {
151                 case InsetNewlineParams::NEWLINE:
152                         os << "\\\\\n";
153                         break;
154                 case InsetNewlineParams::LINEBREAK:
155                         os << "\\linebreak{}\n";
156                         break;
157                 default:
158                         os << "\\\\\n";
159                         break;
160         }
161         return 0;
162 }
163
164
165 int InsetNewline::plaintext(odocstream & os, OutputParams const &) const
166 {
167         os << '\n';
168         return PLAINTEXT_NEWLINE;
169 }
170
171
172 int InsetNewline::docbook(odocstream & os, OutputParams const &) const
173 {
174         os << '\n';
175         return 0;
176 }
177
178
179 void InsetNewline::draw(PainterInfo & pi, int x, int y) const
180 {
181         FontInfo font;
182         font.setColor(ColorName());
183
184         frontend::FontMetrics const & fm = theFontMetrics(pi.base.font);
185         int const wid = fm.width('n');
186         int const asc = fm.maxAscent();
187
188         int xp[3];
189         int yp[3];
190
191         yp[0] = int(y - 0.875 * asc * 0.75);
192         yp[1] = int(y - 0.500 * asc * 0.75);
193         yp[2] = int(y - 0.125 * asc * 0.75);
194
195         if (pi.ltr_pos) {
196                 xp[0] = int(x + wid * 0.375);
197                 xp[1] = int(x);
198                 xp[2] = int(x + wid * 0.375);
199         } else {
200                 xp[0] = int(x + wid * 0.625);
201                 xp[1] = int(x + wid);
202                 xp[2] = int(x + wid * 0.625);
203         }
204
205         pi.pain.lines(xp, yp, 3, ColorName());
206
207         yp[0] = int(y - 0.500 * asc * 0.75);
208         yp[1] = int(y - 0.500 * asc * 0.75);
209         yp[2] = int(y - asc * 0.75);
210
211         if (pi.ltr_pos) {
212                 xp[0] = int(x);
213                 xp[1] = int(x + wid);
214                 xp[2] = int(x + wid);
215         } else {
216                 xp[0] = int(x + wid);
217                 xp[1] = int(x);
218                 xp[2] = int(x);
219         }
220
221         pi.pain.lines(xp, yp, 3, ColorName());
222
223         if (params_.kind == InsetNewlineParams::LINEBREAK) {
224
225                 yp[2] = int(y - 0.500 * asc * 0.75);
226
227                 if (pi.ltr_pos) {
228                         xp[0] = int(x + 1.3 * wid);
229                         xp[1] = int(x + 2 * wid);
230                         xp[2] = int(x + 2 * wid);
231                 } else {
232                         xp[0] = int(x - 0.3 * wid);
233                         xp[1] = int(x - wid);
234                         xp[2] = int(x - wid);
235                 }
236                 pi.pain.lines(xp, yp, 3, ColorName());
237
238                 yp[0] = int(y - 0.875 * asc * 0.75);
239                 yp[1] = int(y - 0.500 * asc * 0.75);
240                 yp[2] = int(y - 0.125 * asc * 0.75);
241         
242                 if (pi.ltr_pos) {
243                         xp[0] = int(x + 2 * wid * 0.813);
244                         xp[1] = int(x + 2 * wid);
245                         xp[2] = int(x + 2 * wid * 0.813);
246                 } else {
247                         xp[0] = int(x - wid * 0.625);
248                         xp[1] = int(x - wid);
249                         xp[2] = int(x - wid * 0.625);
250                 }
251                 pi.pain.lines(xp, yp, 3, ColorName());
252         }
253 }
254
255
256 docstring InsetNewline::contextMenu(BufferView const &, int, int) const
257 {
258         return from_ascii("context-newline");
259 }
260
261
262 string const InsetNewlineMailer::name_ = "newline";
263
264
265 InsetNewlineMailer::InsetNewlineMailer(InsetNewline & inset)
266         : inset_(inset)
267 {}
268
269
270 string const InsetNewlineMailer::inset2string(Buffer const &) const
271 {
272         return params2string(inset_.params());
273 }
274
275
276 void InsetNewlineMailer::string2params(string const & in, InsetNewlineParams & params)
277 {
278         params = InsetNewlineParams();
279         if (in.empty())
280                 return;
281
282         istringstream data(in);
283         Lexer lex(0,0);
284         lex.setStream(data);
285
286         string name;
287         lex >> name;
288         if (!lex || name != name_)
289                 return print_mailer_error("InsetNewlineMailer", in, 1, name_);
290
291         params.read(lex);
292 }
293
294
295 string const InsetNewlineMailer::params2string(InsetNewlineParams const & params)
296 {
297         ostringstream data;
298         data << name_ << ' ';
299         params.write(data);
300         return data.str();
301 }
302
303
304 } // namespace lyx