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