]> git.lyx.org Git - lyx.git/blob - src/insets/InsetNote.cpp
Rename files in src/support, step one.
[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 "LCursor.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 "LColor.h"
27 #include "LyXLex.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(LyXLex & 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         setInsetName(from_ascii("Note"));
116         setButtonLabel();
117 }
118
119
120 InsetNote::InsetNote(BufferParams const & bp, string const & label)
121         : InsetCollapsable(bp)
122 {
123         params_.type = notetranslator().find(label);
124         init();
125 }
126
127
128 InsetNote::InsetNote(InsetNote const & in)
129         : InsetCollapsable(in), params_(in.params_)
130 {
131         init();
132 }
133
134
135 InsetNote::~InsetNote()
136 {
137         InsetNoteMailer(*this).hideDialog();
138 }
139
140
141 auto_ptr<InsetBase> InsetNote::doClone() const
142 {
143         return auto_ptr<InsetBase>(new InsetNote(*this));
144 }
145
146
147 docstring const InsetNote::editMessage() const
148 {
149         return _("Opened Note Inset");
150 }
151
152
153 void InsetNote::write(Buffer const & buf, ostream & os) const
154 {
155         params_.write(os);
156         InsetCollapsable::write(buf, os);
157 }
158
159
160 void InsetNote::read(Buffer const & buf, LyXLex & lex)
161 {
162         params_.read(lex);
163         InsetCollapsable::read(buf, lex);
164         setButtonLabel();
165 }
166
167
168 void InsetNote::setButtonLabel()
169 {
170         docstring const label = notetranslator_loc().find(params_.type);
171         setLabel(label);
172
173         LyXFont font(LyXFont::ALL_SANE);
174         font.decSize();
175         font.decSize();
176
177         switch (params_.type) {
178         case InsetNoteParams::Note:
179                 font.setColor(LColor::note);
180                 setBackgroundColor(LColor::notebg);
181                 break;
182         case InsetNoteParams::Comment:
183                 font.setColor(LColor::comment);
184                 setBackgroundColor(LColor::commentbg);
185                 break;
186         case InsetNoteParams::Greyedout:
187                 font.setColor(LColor::greyedout);
188                 setBackgroundColor(LColor::greyedoutbg);
189                 break;
190         case InsetNoteParams::Framed:
191                 font.setColor(LColor::greyedout);
192                 setBackgroundColor(LColor::greyedoutbg);
193                 break;
194         case InsetNoteParams::Shaded:
195                 font.setColor(LColor::greyedout);
196                 setBackgroundColor(LColor::shadedbg);
197                 break;
198         }
199         setLabelFont(font);
200 }
201
202
203 bool InsetNote::showInsetDialog(BufferView * bv) const
204 {
205         InsetNoteMailer(const_cast<InsetNote &>(*this)).showDialog(bv);
206         return true;
207 }
208
209
210 void InsetNote::doDispatch(LCursor & cur, FuncRequest & cmd)
211 {
212         switch (cmd.action) {
213
214         case LFUN_INSET_MODIFY:
215                 InsetNoteMailer::string2params(to_utf8(cmd.argument()), params_);
216                 setButtonLabel();
217                 break;
218
219         case LFUN_INSET_DIALOG_UPDATE:
220                 InsetNoteMailer(*this).updateDialog(&cur.bv());
221                 break;
222
223         case LFUN_MOUSE_RELEASE:
224                 if (cmd.button() == mouse_button::button3 && hitButton(cmd))
225                         InsetNoteMailer(*this).showDialog(&cur.bv());
226                 else
227                         InsetCollapsable::doDispatch(cur, cmd);
228                 break;
229
230         default:
231                 InsetCollapsable::doDispatch(cur, cmd);
232                 break;
233         }
234 }
235
236
237 bool InsetNote::getStatus(LCursor & cur, FuncRequest const & cmd,
238                 FuncStatus & flag) const
239 {
240         switch (cmd.action) {
241
242         case LFUN_INSET_MODIFY:
243         case LFUN_INSET_DIALOG_UPDATE:
244                 flag.enabled(true);
245                 return true;
246
247         default:
248                 return InsetCollapsable::getStatus(cur, cmd, flag);
249         }
250 }
251
252
253 int InsetNote::latex(Buffer const & buf, odocstream & os,
254                      OutputParams const & runparams_in) const
255 {
256         if (params_.type == InsetNoteParams::Note)
257                 return 0;
258
259         OutputParams runparams(runparams_in);
260         string type;
261         if (params_.type == InsetNoteParams::Comment) {
262                 type = "comment";
263                 runparams.inComment = true;
264                 // Ignore files that are exported inside a comment
265                 runparams.exportdata.reset(new ExportData);
266         } else if (params_.type == InsetNoteParams::Greyedout)
267                 type = "lyxgreyedout";
268         else if (params_.type == InsetNoteParams::Framed)
269                 type = "framed";
270         else if (params_.type == InsetNoteParams::Shaded)
271                 type = "shaded";
272
273         odocstringstream ss;
274         ss << "%\n\\begin{" << from_ascii(type) << "}\n";
275         InsetText::latex(buf, ss, runparams);
276         ss << "\n\\end{" << from_ascii(type) << "}\n";
277         // the space after the comment in 'a[comment] b' will be eaten by the
278         // comment environment since the space before b is ignored with the
279         // following latex output:
280         //
281         // a%
282         // \begin{comment}
283         // comment
284         // \end{comment}
285         //  b
286         //
287         // Adding {} before ' b' fixes this.
288         if (params_.type == InsetNoteParams::Comment)
289                 ss << "{}";
290
291         docstring const str = ss.str();
292         os << str;
293         runparams_in.encoding = runparams.encoding;
294         // Return how many newlines we issued.
295         return int(lyx::count(str.begin(), str.end(), '\n'));
296 }
297
298
299 int InsetNote::plaintext(Buffer const & buf, odocstream & os,
300                          OutputParams const & runparams_in) const
301 {
302         if (params_.type == InsetNoteParams::Note)
303                 return 0;
304
305         OutputParams runparams(runparams_in);
306         if (params_.type == InsetNoteParams::Comment) {
307                 runparams.inComment = true;
308                 // Ignore files that are exported inside a comment
309                 runparams.exportdata.reset(new ExportData);
310         }
311         os << '[' << _("note") << ":\n";
312         InsetText::plaintext(buf, os, runparams);
313         os << "\n]";
314
315         return PLAINTEXT_NEWLINE + 1; // one char on a separate line
316 }
317
318
319 int InsetNote::docbook(Buffer const & buf, odocstream & os,
320                        OutputParams const & runparams_in) const
321 {
322         if (params_.type == InsetNoteParams::Note)
323                 return 0;
324
325         OutputParams runparams(runparams_in);
326         if (params_.type == InsetNoteParams::Comment) {
327                 os << "<remark>\n";
328                 runparams.inComment = true;
329                 // Ignore files that are exported inside a comment
330                 runparams.exportdata.reset(new ExportData);
331         }
332
333         int const n = InsetText::docbook(buf, os, runparams);
334
335         if (params_.type == InsetNoteParams::Comment)
336                 os << "\n</remark>\n";
337
338         // Return how many newlines we issued.
339         //return int(count(str.begin(), str.end(), '\n'));
340         return n + 1 + 2;
341 }
342
343
344 void InsetNote::validate(LaTeXFeatures & features) const
345 {
346         if (params_.type == InsetNoteParams::Comment)
347                 features.require("verbatim");
348         if (params_.type == InsetNoteParams::Greyedout) {
349                 features.require("color");
350                 features.require("lyxgreyedout");
351         }
352         if (params_.type == InsetNoteParams::Shaded) {
353                 features.require("color");
354                 features.require("framed");
355         }
356         if (params_.type == InsetNoteParams::Framed)
357                 features.require("framed");
358         InsetText::validate(features);
359 }
360
361
362
363 string const InsetNoteMailer::name_("note");
364
365 InsetNoteMailer::InsetNoteMailer(InsetNote & inset)
366         : inset_(inset)
367 {}
368
369
370 string const InsetNoteMailer::inset2string(Buffer const &) const
371 {
372         return params2string(inset_.params());
373 }
374
375
376 string const InsetNoteMailer::params2string(InsetNoteParams const & params)
377 {
378         ostringstream data;
379         data << name_ << ' ';
380         params.write(data);
381         return data.str();
382 }
383
384
385 void InsetNoteMailer::string2params(string const & in,
386                                     InsetNoteParams & params)
387 {
388         params = InsetNoteParams();
389
390         if (in.empty())
391                 return;
392
393         istringstream data(in);
394         LyXLex lex(0,0);
395         lex.setStream(data);
396
397         string name;
398         lex >> name;
399         if (!lex || name != name_)
400                 return print_mailer_error("InsetNoteMailer", in, 1, name_);
401
402         // This is part of the inset proper that is usually swallowed
403         // by LyXText::readInset
404         string id;
405         lex >> id;
406         if (!lex || id != "Note")
407                 return print_mailer_error("InsetBoxMailer", in, 2, "Note");
408
409         params.read(lex);
410 }
411
412
413 } // namespace lyx