]> git.lyx.org Git - lyx.git/blob - src/insets/InsetNote.cpp
1406d0c6873d26340279730d7e140fd0fb230d00
[lyx.git] / src / insets / InsetNote.cpp
1 /**
2  * \file InsetNote.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  * \author Martin Vermeer
8  * \author Jürgen Spitzmüller
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "InsetNote.h"
16
17 #include "Buffer.h"
18 #include "BufferView.h"
19 #include "Cursor.h"
20 #include "debug.h"
21 #include "DispatchResult.h"
22 #include "Exporter.h"
23 #include "FuncRequest.h"
24 #include "FuncStatus.h"
25 #include "gettext.h"
26 #include "LaTeXFeatures.h"
27 #include "Lexer.h"
28 #include "MetricsInfo.h"
29 #include "OutputParams.h"
30
31 #include "support/Translator.h"
32
33 #include <algorithm>
34 #include <sstream>
35
36
37 namespace lyx {
38
39 using std::string;
40 using std::auto_ptr;
41 using std::istringstream;
42 using std::ostream;
43 using std::ostringstream;
44
45
46 namespace {
47
48 typedef Translator<std::string, InsetNoteParams::Type> NoteTranslator;
49 typedef Translator<docstring, InsetNoteParams::Type> NoteTranslatorLoc;
50
51 NoteTranslator const init_notetranslator()
52 {
53         NoteTranslator translator("Note", InsetNoteParams::Note);
54         translator.addPair("Comment", InsetNoteParams::Comment);
55         translator.addPair("Greyedout", InsetNoteParams::Greyedout);
56         translator.addPair("Framed", InsetNoteParams::Framed);
57         translator.addPair("Shaded", InsetNoteParams::Shaded);
58         return translator;
59 }
60
61
62 NoteTranslatorLoc const init_notetranslator_loc()
63 {
64         NoteTranslatorLoc translator(_("Note"), InsetNoteParams::Note);
65         translator.addPair(_("Comment"), InsetNoteParams::Comment);
66         translator.addPair(_("Greyed out"), InsetNoteParams::Greyedout);
67         translator.addPair(_("Framed"), InsetNoteParams::Framed);
68         translator.addPair(_("Shaded"), InsetNoteParams::Shaded);
69         return translator;
70 }
71
72
73 NoteTranslator const & notetranslator()
74 {
75         static NoteTranslator translator = init_notetranslator();
76         return translator;
77 }
78
79
80 NoteTranslatorLoc const & notetranslator_loc()
81 {
82         static NoteTranslatorLoc translator = init_notetranslator_loc();
83         return translator;
84 }
85
86 } // anon
87
88
89
90
91 InsetNoteParams::InsetNoteParams()
92         : type(Note)
93 {}
94
95
96 void InsetNoteParams::write(ostream & os) const
97 {
98         string const label = notetranslator().find(type);
99         os << "Note " << label << "\n";
100 }
101
102
103 void InsetNoteParams::read(Lexer & lex)
104 {
105         string label;
106         lex >> label;
107         if (lex)
108                 type = notetranslator().find(label);
109 }
110
111
112 void InsetNote::init()
113 {
114         setButtonLabel();
115 }
116
117
118 InsetNote::InsetNote(BufferParams const & bp, string const & label)
119         : InsetCollapsable(bp)
120 {
121         params_.type = notetranslator().find(label);
122         init();
123 }
124
125
126 InsetNote::InsetNote(InsetNote const & in)
127         : InsetCollapsable(in), params_(in.params_)
128 {
129         init();
130 }
131
132
133 InsetNote::~InsetNote()
134 {
135         InsetNoteMailer(*this).hideDialog();
136 }
137
138
139 auto_ptr<Inset> InsetNote::doClone() const
140 {
141         return auto_ptr<Inset>(new InsetNote(*this));
142 }
143
144
145 docstring const InsetNote::editMessage() const
146 {
147         return _("Opened Note Inset");
148 }
149
150
151 Inset::DisplayType InsetNote::display() const
152 {
153         switch (params_.type) {
154         case InsetNoteParams::Framed:
155         case InsetNoteParams::Shaded:
156                 return AlignLeft;
157         default:
158                 return Inline;
159         }
160 }
161
162
163 void InsetNote::write(Buffer const & buf, ostream & os) const
164 {
165         params_.write(os);
166         InsetCollapsable::write(buf, os);
167 }
168
169
170 void InsetNote::read(Buffer const & buf, Lexer & lex)
171 {
172         params_.read(lex);
173         InsetCollapsable::read(buf, lex);
174         setButtonLabel();
175 }
176
177
178 void InsetNote::setButtonLabel()
179 {
180         docstring const label = notetranslator_loc().find(params_.type);
181         setLabel(label);
182
183         Font font(Font::ALL_SANE);
184         font.decSize();
185         font.decSize();
186
187         Color_color c;
188         switch (params_.type) {
189         case InsetNoteParams::Note:
190                 c = Color::note;
191                 break;
192         case InsetNoteParams::Comment:
193                 c = Color::comment;
194                 break;
195         case InsetNoteParams::Greyedout:
196                 c = Color::greyedout;
197                 break;
198         case InsetNoteParams::Framed:
199                 c = Color::greyedout;
200                 break;
201         case InsetNoteParams::Shaded:
202                 c = Color::greyedout;
203                 break;
204         }
205         font.setColor(c);
206         setLabelFont(font);
207 }
208
209
210 Color_color InsetNote::backgroundColor() const
211 {
212         Color_color c;
213         switch (params_.type) {
214         case InsetNoteParams::Note:
215                 c = Color::notebg;
216                 break;
217         case InsetNoteParams::Comment:
218                 c = Color::commentbg;
219                 break;
220         case InsetNoteParams::Greyedout:
221                 c = Color::greyedoutbg;
222                 break;
223         case InsetNoteParams::Framed:
224                 c = Color::greyedoutbg;
225                 break;
226         case InsetNoteParams::Shaded:
227                 c = Color::shadedbg;
228                 break;
229         }
230         return c;
231 }
232
233
234 bool InsetNote::showInsetDialog(BufferView * bv) const
235 {
236         InsetNoteMailer(const_cast<InsetNote &>(*this)).showDialog(bv);
237         return true;
238 }
239
240
241 void InsetNote::doDispatch(Cursor & cur, FuncRequest & cmd)
242 {
243         switch (cmd.action) {
244
245         case LFUN_INSET_MODIFY:
246                 InsetNoteMailer::string2params(to_utf8(cmd.argument()), params_);
247                 setButtonLabel();
248                 break;
249
250         case LFUN_INSET_DIALOG_UPDATE:
251                 InsetNoteMailer(*this).updateDialog(&cur.bv());
252                 break;
253
254         case LFUN_MOUSE_RELEASE:
255                 if (cmd.button() == mouse_button::button3 && hitButton(cmd))
256                         InsetNoteMailer(*this).showDialog(&cur.bv());
257                 else
258                         InsetCollapsable::doDispatch(cur, cmd);
259                 break;
260
261         default:
262                 InsetCollapsable::doDispatch(cur, cmd);
263                 break;
264         }
265 }
266
267
268 bool InsetNote::getStatus(Cursor & cur, FuncRequest const & cmd,
269                 FuncStatus & flag) const
270 {
271         switch (cmd.action) {
272
273         case LFUN_INSET_MODIFY:
274         case LFUN_INSET_DIALOG_UPDATE:
275                 flag.enabled(true);
276                 return true;
277
278         default:
279                 return InsetCollapsable::getStatus(cur, cmd, flag);
280         }
281 }
282
283
284 int InsetNote::latex(Buffer const & buf, odocstream & os,
285                      OutputParams const & runparams_in) const
286 {
287         if (params_.type == InsetNoteParams::Note)
288                 return 0;
289
290         OutputParams runparams(runparams_in);
291         string type;
292         if (params_.type == InsetNoteParams::Comment) {
293                 type = "comment";
294                 runparams.inComment = true;
295                 // Ignore files that are exported inside a comment
296                 runparams.exportdata.reset(new ExportData);
297         } else if (params_.type == InsetNoteParams::Greyedout)
298                 type = "lyxgreyedout";
299         else if (params_.type == InsetNoteParams::Framed)
300                 type = "framed";
301         else if (params_.type == InsetNoteParams::Shaded)
302                 type = "shaded";
303
304         odocstringstream ss;
305         ss << "%\n\\begin{" << from_ascii(type) << "}\n";
306         InsetText::latex(buf, ss, runparams);
307         ss << "\n\\end{" << from_ascii(type) << "}\n";
308         // the space after the comment in 'a[comment] b' will be eaten by the
309         // comment environment since the space before b is ignored with the
310         // following latex output:
311         //
312         // a%
313         // \begin{comment}
314         // comment
315         // \end{comment}
316         //  b
317         //
318         // Adding {} before ' b' fixes this.
319         if (params_.type == InsetNoteParams::Comment)
320                 ss << "{}";
321
322         docstring const str = ss.str();
323         os << str;
324         runparams_in.encoding = runparams.encoding;
325         // Return how many newlines we issued.
326         return int(std::count(str.begin(), str.end(), '\n'));
327 }
328
329
330 int InsetNote::plaintext(Buffer const & buf, odocstream & os,
331                          OutputParams const & runparams_in) const
332 {
333         if (params_.type == InsetNoteParams::Note)
334                 return 0;
335
336         OutputParams runparams(runparams_in);
337         if (params_.type == InsetNoteParams::Comment) {
338                 runparams.inComment = true;
339                 // Ignore files that are exported inside a comment
340                 runparams.exportdata.reset(new ExportData);
341         }
342         os << '[' << buf.B_("note") << ":\n";
343         InsetText::plaintext(buf, os, runparams);
344         os << "\n]";
345
346         return PLAINTEXT_NEWLINE + 1; // one char on a separate line
347 }
348
349
350 int InsetNote::docbook(Buffer const & buf, odocstream & os,
351                        OutputParams const & runparams_in) const
352 {
353         if (params_.type == InsetNoteParams::Note)
354                 return 0;
355
356         OutputParams runparams(runparams_in);
357         if (params_.type == InsetNoteParams::Comment) {
358                 os << "<remark>\n";
359                 runparams.inComment = true;
360                 // Ignore files that are exported inside a comment
361                 runparams.exportdata.reset(new ExportData);
362         }
363
364         int const n = InsetText::docbook(buf, os, runparams);
365
366         if (params_.type == InsetNoteParams::Comment)
367                 os << "\n</remark>\n";
368
369         // Return how many newlines we issued.
370         //return int(count(str.begin(), str.end(), '\n'));
371         return n + 1 + 2;
372 }
373
374
375 void InsetNote::validate(LaTeXFeatures & features) const
376 {
377         if (params_.type == InsetNoteParams::Comment)
378                 features.require("verbatim");
379         if (params_.type == InsetNoteParams::Greyedout) {
380                 features.require("color");
381                 features.require("lyxgreyedout");
382         }
383         if (params_.type == InsetNoteParams::Shaded) {
384                 features.require("color");
385                 features.require("framed");
386         }
387         if (params_.type == InsetNoteParams::Framed)
388                 features.require("framed");
389         InsetText::validate(features);
390 }
391
392
393
394 string const InsetNoteMailer::name_("note");
395
396 InsetNoteMailer::InsetNoteMailer(InsetNote & inset)
397         : inset_(inset)
398 {}
399
400
401 string const InsetNoteMailer::inset2string(Buffer const &) const
402 {
403         return params2string(inset_.params());
404 }
405
406
407 string const InsetNoteMailer::params2string(InsetNoteParams const & params)
408 {
409         ostringstream data;
410         data << name_ << ' ';
411         params.write(data);
412         return data.str();
413 }
414
415
416 void InsetNoteMailer::string2params(string const & in,
417                                     InsetNoteParams & params)
418 {
419         params = InsetNoteParams();
420
421         if (in.empty())
422                 return;
423
424         istringstream data(in);
425         Lexer lex(0,0);
426         lex.setStream(data);
427
428         string name;
429         lex >> name;
430         if (!lex || name != name_)
431                 return print_mailer_error("InsetNoteMailer", in, 1, name_);
432
433         // This is part of the inset proper that is usually swallowed
434         // by Text::readInset
435         string id;
436         lex >> id;
437         if (!lex || id != "Note")
438                 return print_mailer_error("InsetBoxMailer", in, 2, "Note");
439
440         params.read(lex);
441 }
442
443
444 } // namespace lyx