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