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