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