]> git.lyx.org Git - lyx.git/blob - src/insets/InsetPhantom.cpp
Cleanup included headers
[lyx.git] / src / insets / InsetPhantom.cpp
1 /**
2  * \file InsetPhantom.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Uwe Stöhr
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "InsetPhantom.h"
14
15 #include "Buffer.h"
16 #include "BufferParams.h"
17 #include "BufferView.h"
18 #include "Cursor.h"
19 #include "Dimension.h"
20 #include "DispatchResult.h"
21 #include "Exporter.h"
22 #include "FuncRequest.h"
23 #include "FuncStatus.h"
24 #include "LaTeXFeatures.h"
25 #include "Lexer.h"
26 #include "MetricsInfo.h"
27 #include "OutputParams.h"
28 #include "texstream.h"
29 #include "TextClass.h"
30
31 #include "support/docstream.h"
32 #include "support/gettext.h"
33 #include "support/lstrings.h"
34 #include "support/Translator.h"
35
36 #include "frontends/Application.h"
37 #include "frontends/FontMetrics.h"
38 #include "frontends/Painter.h"
39
40 #include <algorithm>
41 #include <sstream>
42
43 using namespace std;
44
45 namespace lyx {
46
47 namespace {
48
49 typedef Translator<string, InsetPhantomParams::Type> PhantomTranslator;
50 typedef Translator<docstring, InsetPhantomParams::Type> PhantomTranslatorLoc;
51
52 PhantomTranslator const init_phantomtranslator()
53 {
54         PhantomTranslator translator("Phantom", InsetPhantomParams::Phantom);
55         translator.addPair("HPhantom", InsetPhantomParams::HPhantom);
56         translator.addPair("VPhantom", InsetPhantomParams::VPhantom);
57         return translator;
58 }
59
60
61 PhantomTranslatorLoc const init_phantomtranslator_loc()
62 {
63         PhantomTranslatorLoc translator(_("Phantom"), InsetPhantomParams::Phantom);
64         translator.addPair(_("HPhantom"), InsetPhantomParams::HPhantom);
65         translator.addPair(_("VPhantom"), InsetPhantomParams::VPhantom);
66         return translator;
67 }
68
69
70 PhantomTranslator const & phantomtranslator()
71 {
72         static PhantomTranslator const translator =
73             init_phantomtranslator();
74         return translator;
75 }
76
77
78 PhantomTranslatorLoc const & phantomtranslator_loc()
79 {
80         static PhantomTranslatorLoc const translator =
81             init_phantomtranslator_loc();
82         return translator;
83 }
84
85 } // namespace
86
87
88 InsetPhantomParams::InsetPhantomParams()
89         : type(Phantom)
90 {}
91
92
93 void InsetPhantomParams::write(ostream & os) const
94 {
95         string const label = phantomtranslator().find(type);
96         os << "Phantom " << label << "\n";
97 }
98
99
100 void InsetPhantomParams::read(Lexer & lex)
101 {
102         string label;
103         lex >> label;
104         if (lex)
105                 type = phantomtranslator().find(label);
106 }
107
108
109 /////////////////////////////////////////////////////////////////////
110 //
111 // InsetPhantom
112 //
113 /////////////////////////////////////////////////////////////////////
114
115 InsetPhantom::InsetPhantom(Buffer * buf, string const & label)
116         : InsetCollapsible(buf)
117 {
118         setDrawFrame(false);
119         params_.type = phantomtranslator().find(label);
120 }
121
122
123 InsetPhantom::~InsetPhantom()
124 {
125         hideDialogs("phantom", this);
126 }
127
128
129 docstring InsetPhantom::layoutName() const
130 {
131         return from_ascii("Phantom:" + phantomtranslator().find(params_.type));
132 }
133
134
135 void InsetPhantom::draw(PainterInfo & pi, int x, int y) const
136 {
137         // draw the text
138         InsetCollapsible::draw(pi, x, y);
139
140         // draw the inset marker
141         drawMarkers(pi, x, y);
142
143         // draw the arrow(s)
144         static int const arrow_size = 4;
145         ColorCode const origcol = pi.base.font.color();
146         pi.base.font.setColor(Color_special);
147         pi.base.font.setColor(origcol);
148         Dimension const dim = dimension(*pi.base.bv);
149
150         if (params_.type == InsetPhantomParams::Phantom ||
151                 params_.type == InsetPhantomParams::VPhantom) {
152                 // y1---------
153                 //           / \.
154                 // y2-----  / | \.
155                 //            |
156                 //            |
157                 // y3-----  \ | /
158                 //           \ /
159                 // y4---------
160                 //          | | |
161                 //         /  |  \.
162                 //        x1  x2 x3
163
164                 int const x2 = x + dim.wid / 2;
165                 int const x1 = x2 - arrow_size;
166                 int const x3 = x2 + arrow_size;
167
168                 int const y1 = y - dim.asc;
169                 int const y2 = y1 + arrow_size;
170                 int const y4 = y + dim.des;
171                 int const y3 = y4 - arrow_size;
172
173                 // top arrow
174                 pi.pain.line(x2, y1, x1, y2, Color_added_space);
175                 pi.pain.line(x2, y1, x3, y2, Color_added_space);
176
177                 // bottom arrow
178                 pi.pain.line(x2, y4, x1, y3, Color_added_space);
179                 pi.pain.line(x2, y4, x3, y3, Color_added_space);
180
181                 // joining line
182                 pi.pain.line(x2, y1, x2, y4, Color_added_space);
183         }
184
185         if (params_.type == InsetPhantomParams::Phantom ||
186                 params_.type == InsetPhantomParams::HPhantom) {
187                 // y1----   /          \.
188                 //        /              \.
189                 // y2--- <---------------->
190                 //        \              /
191                 // y3----   \          /
192                 //       |   |        |   |
193                 //      x1  x2       x3  x4
194
195                 x += leftOffset(pi.base.bv);
196                 int const x1 = x;
197                 int const x2 = x + arrow_size;
198                 int const x4 = x + dim.wid - leftOffset(pi.base.bv) - rightOffset(pi.base.bv);
199                 int const x3 = x4 - arrow_size;
200
201                 int const y2 = y + (dim.des - dim.asc) / 2;
202                 int const y1 = y2 - arrow_size;
203                 int const y3 = y2 + arrow_size;
204
205                 // left arrow
206                 pi.pain.line(x1, y2, x2, y3, Color_added_space);
207                 pi.pain.line(x1, y2, x2, y1, Color_added_space);
208
209                 // right arrow
210                 pi.pain.line(x4, y2, x3, y3, Color_added_space);
211                 pi.pain.line(x4, y2, x3, y1, Color_added_space);
212
213                 // joining line
214                 pi.pain.line(x1, y2, x4, y2, Color_added_space);
215         }
216 }
217
218
219 void InsetPhantom::write(ostream & os) const
220 {
221         params_.write(os);
222         InsetCollapsible::write(os);
223 }
224
225
226 void InsetPhantom::read(Lexer & lex)
227 {
228         params_.read(lex);
229         InsetCollapsible::read(lex);
230 }
231
232
233 void InsetPhantom::setButtonLabel()
234 {
235         docstring const label = phantomtranslator_loc().find(params_.type);
236         setLabel(label);
237 }
238
239
240 bool InsetPhantom::showInsetDialog(BufferView * bv) const
241 {
242         bv->showDialog("phantom", params2string(params()),
243                 const_cast<InsetPhantom *>(this));
244         return true;
245 }
246
247
248 void InsetPhantom::doDispatch(Cursor & cur, FuncRequest & cmd)
249 {
250         switch (cmd.action()) {
251
252         case LFUN_INSET_MODIFY:
253                 cur.recordUndoInset(this);
254                 string2params(to_utf8(cmd.argument()), params_);
255                 setButtonLabel();
256                 cur.forceBufferUpdate();
257                 break;
258
259         case LFUN_INSET_DIALOG_UPDATE:
260                 cur.bv().updateDialog("phantom", params2string(params()));
261                 break;
262
263         default:
264                 InsetCollapsible::doDispatch(cur, cmd);
265                 break;
266         }
267 }
268
269
270 bool InsetPhantom::getStatus(Cursor & cur, FuncRequest const & cmd,
271                 FuncStatus & flag) const
272 {
273         switch (cmd.action()) {
274
275         case LFUN_INSET_MODIFY:
276                 if (cmd.getArg(0) == "phantom") {
277                         InsetPhantomParams params;
278                         string2params(to_utf8(cmd.argument()), params);
279                         flag.setOnOff(params_.type == params.type);
280                 }
281                 flag.setEnabled(true);
282                 return true;
283
284         case LFUN_INSET_DIALOG_UPDATE:
285                 flag.setEnabled(true);
286                 return true;
287
288         default:
289                 return InsetCollapsible::getStatus(cur, cmd, flag);
290         }
291 }
292
293
294 docstring InsetPhantom::toolTip(BufferView const &, int, int) const
295 {
296         docstring const res = phantomtranslator_loc().find(params_.type);
297         return toolTipText(res + from_ascii(": "));
298 }
299
300
301 void InsetPhantom::latex(otexstream & os, OutputParams const & runparams) const
302 {
303         if (runparams.moving_arg)
304                 os << "\\protect";
305
306         switch (params_.type) {
307         case InsetPhantomParams::Phantom:
308                 os << "\\phantom{";
309                 break;
310         case InsetPhantomParams::HPhantom:
311                 os << "\\hphantom{";
312                 break;
313         case InsetPhantomParams::VPhantom:
314                 os << "\\vphantom{";
315                 break;
316         default:
317                 os << "\\phantom{";
318                 break;
319         }
320         InsetCollapsible::latex(os, runparams);
321         os << "}";
322 }
323
324
325 int InsetPhantom::plaintext(odocstringstream & os,
326                             OutputParams const & runparams, size_t max_length) const
327 {
328         switch (params_.type) {
329         case InsetPhantomParams::Phantom:
330                 os << '[' << buffer().B_("phantom") << ":";
331                 break;
332         case InsetPhantomParams::HPhantom:
333                 os << '[' << buffer().B_("hphantom") << ":";
334                 break;
335         case InsetPhantomParams::VPhantom:
336                 os << '[' << buffer().B_("vphantom") << ":";
337                 break;
338         default:
339                 os << '[' << buffer().B_("phantom") << ":";
340                 break;
341         }
342         InsetCollapsible::plaintext(os, runparams, max_length);
343         os << "]";
344
345         return PLAINTEXT_NEWLINE;
346 }
347
348
349 void InsetPhantom::docbook(XMLStream &, OutputParams const &) const
350 {
351         return;
352 }
353
354
355 docstring InsetPhantom::xhtml(XMLStream &, OutputParams const &) const
356 {
357         return docstring();
358 }
359
360 string InsetPhantom::contextMenuName() const
361 {
362         return "context-phantom";
363 }
364
365
366 string InsetPhantom::params2string(InsetPhantomParams const & params)
367 {
368         ostringstream data;
369         data << "phantom" << ' ';
370         params.write(data);
371         return data.str();
372 }
373
374
375 void InsetPhantom::string2params(string const & in, InsetPhantomParams & params)
376 {
377         params = InsetPhantomParams();
378
379         if (in.empty())
380                 return;
381
382         istringstream data(in);
383         Lexer lex;
384         lex.setStream(data);
385         lex.setContext("InsetPhantom::string2params");
386         lex >> "phantom" >> "Phantom";
387
388         params.read(lex);
389 }
390
391
392 } // namespace lyx