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