]> git.lyx.org Git - lyx.git/blob - src/insets/insetert.C
fix LFUN enum values (some of them were broken by r13801)
[lyx.git] / src / insets / insetert.C
1 /**
2  * \file insetert.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Vigna
7  * \author Lars Gullik Bjønnes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "insetert.h"
15
16 #include "buffer.h"
17 #include "bufferparams.h"
18 #include "BufferView.h"
19 #include "cursor.h"
20 #include "debug.h"
21 #include "dispatchresult.h"
22 #include "funcrequest.h"
23 #include "FuncStatus.h"
24 #include "gettext.h"
25 #include "language.h"
26 #include "LColor.h"
27 #include "LyXAction.h"
28 #include "lyxlex.h"
29 #include "lyxtextclass.h"
30 #include "metricsinfo.h"
31 #include "ParagraphParameters.h"
32 #include "paragraph.h"
33
34 #include "frontends/Alert.h"
35 #include "frontends/LyXView.h"
36
37 #include <sstream>
38
39 using lyx::pos_type;
40 using lyx::support::token;
41
42 using std::endl;
43 using std::min;
44
45 using std::auto_ptr;
46 using std::istringstream;
47 using std::ostream;
48 using std::ostringstream;
49 using std::string;
50
51
52 void InsetERT::init()
53 {
54         setButtonLabel();
55
56         LyXFont font(LyXFont::ALL_SANE);
57         font.decSize();
58         font.decSize();
59         font.setColor(LColor::latex);
60         setLabelFont(font);
61         text_.current_font.setLanguage(latex_language);
62         text_.real_current_font.setLanguage(latex_language);
63
64         setInsetName("ERT");
65 }
66
67
68 InsetERT::InsetERT(BufferParams const & bp, CollapseStatus status)
69         : InsetCollapsable(bp, status)
70 {
71         init();
72 }
73
74
75 InsetERT::InsetERT(InsetERT const & in)
76         : InsetCollapsable(in)
77 {
78         init();
79 }
80
81
82 auto_ptr<InsetBase> InsetERT::doClone() const
83 {
84         return auto_ptr<InsetBase>(new InsetERT(*this));
85 }
86
87
88 #if 0
89 InsetERT::InsetERT(BufferParams const & bp,
90                    Language const *, string const & contents, CollapseStatus status)
91         : InsetCollapsable(bp, status)
92 {
93         LyXFont font(LyXFont::ALL_INHERIT, latex_language);
94         paragraphs().begin()->insert(0, contents, font);
95
96         // the init has to be after the initialization of the paragraph
97         // because of the label settings (draw_label for ert insets).
98         init();
99 }
100 #endif
101
102
103 InsetERT::~InsetERT()
104 {
105         InsetERTMailer(*this).hideDialog();
106 }
107
108
109 void InsetERT::write(Buffer const & buf, ostream & os) const
110 {
111         os << "ERT" << "\n";
112         InsetCollapsable::write(buf, os);
113 }
114
115
116 void InsetERT::read(Buffer const & buf, LyXLex & lex)
117 {
118         InsetCollapsable::read(buf, lex);
119
120         // Force default font
121         // This avoids paragraphs in buffer language that would have a
122         // foreign language after a document langauge change, and it ensures
123         // that all new text in ERT gets the "latex" language, since new text
124         // inherits the language from the last position of the existing text.
125         // As a side effect this makes us also robust against bugs in LyX
126         // that might lead to font changes in ERT in .lyx files.
127         LyXFont font(LyXFont::ALL_INHERIT, latex_language);
128         ParagraphList::iterator par = paragraphs().begin();
129         ParagraphList::iterator const end = paragraphs().end();
130         while (par != end) {
131                 pos_type siz = par->size();
132                 for (pos_type i = 0; i <= siz; ++i) {
133                         par->setFont(i, font);
134                 }
135                 ++par;
136         }
137 }
138
139
140 string const InsetERT::editMessage() const
141 {
142         return _("Opened ERT Inset");
143 }
144
145
146 int InsetERT::latex(Buffer const &, ostream & os,
147                     OutputParams const &) const
148 {
149         ParagraphList::const_iterator par = paragraphs().begin();
150         ParagraphList::const_iterator end = paragraphs().end();
151
152         int lines = 0;
153         while (par != end) {
154                 pos_type siz = par->size();
155                 for (pos_type i = 0; i < siz; ++i) {
156                         // ignore all struck out text
157                         if (isDeletedText(*par, i))
158                                 continue;
159
160                         os << par->getChar(i);
161                 }
162                 ++par;
163                 if (par != end) {
164                         os << "\n";
165                         ++lines;
166                 }
167         }
168
169         return lines;
170 }
171
172
173 int InsetERT::plaintext(Buffer const &, ostream &,
174                     OutputParams const & /*runparams*/) const
175 {
176         return 0;
177 }
178
179
180 int InsetERT::linuxdoc(Buffer const &, ostream & os,
181                        OutputParams const &) const
182 {
183         ParagraphList::const_iterator par = paragraphs().begin();
184         ParagraphList::const_iterator end = paragraphs().end();
185
186         int lines = 0;
187         while (par != end) {
188                 pos_type siz = par->size();
189                 for (pos_type i = 0; i < siz; ++i)
190                         os << par->getChar(i);
191                 ++par;
192                 if (par != end) {
193                         os << "\n";
194                         lines ++;
195                 }
196         }
197
198         return lines;
199 }
200
201
202 int InsetERT::docbook(Buffer const &, ostream & os,
203                       OutputParams const &) const
204 {
205         ParagraphList::const_iterator par = paragraphs().begin();
206         ParagraphList::const_iterator end = paragraphs().end();
207
208         int lines = 0;
209         while (par != end) {
210                 pos_type siz = par->size();
211                 for (pos_type i = 0; i < siz; ++i)
212                         os << par->getChar(i);
213                 ++par;
214                 if (par != end) {
215                         os << "\n";
216                         ++lines;
217                 }
218         }
219
220         return lines;
221 }
222
223
224 void InsetERT::doDispatch(LCursor & cur, FuncRequest & cmd)
225 {
226         //lyxerr << "\nInsetERT::doDispatch (begin): cmd: " << cmd << endl;
227         switch (cmd.action) {
228
229         case LFUN_QUOTE_INSERT: {
230                 // We need to bypass the fancy quotes in LyXText
231                 FuncRequest f(LFUN_SELF_INSERT, "\"");
232                 dispatch(cur, f);
233                 break;
234         }
235         case LFUN_INSET_MODIFY: {
236                 InsetCollapsable::CollapseStatus st;
237                 InsetERTMailer::string2params(cmd.argument, st);
238                 setStatus(cur, st);
239                 break;
240         }
241         case LFUN_PASTE:
242         case LFUN_PRIMARY_SELECTION_PASTE: {
243                 InsetCollapsable::doDispatch(cur, cmd);
244
245                 // Since we can only store plain text, we must reset all
246                 // attributes.
247                 forceParagraphsToDefault(cur);
248                 // FIXME: Change only the pasted paragraphs
249
250                 BufferParams const & bp = cur.buffer().params();
251                 LyXLayout_ptr const layout =
252                         bp.getLyXTextClass().defaultLayout();
253                 LyXFont font = layout->font;
254                 // ERT contents has always latex_language
255                 font.setLanguage(latex_language);
256                 ParagraphList::iterator const end = paragraphs().end();
257                 for (ParagraphList::iterator par = paragraphs().begin();
258                      par != end; ++par) {
259                         // in case par had a manual label
260                         par->setBeginOfBody();
261                         pos_type const siz = par->size();
262                         for (pos_type i = 0; i < siz; ++i) {
263                                 par->setFont(i, font);
264                         }
265                         par->params().clear();
266                 }
267                 break;
268         }
269         default:
270                 // Force any new text to latex_language
271                 // FIXME: This should only be necessary in init(), but
272                 // new paragraphs that are created by pressing enter at the
273                 // start of an existing paragraph get the buffer language
274                 // and not latex_language, so we take this brute force
275                 // approach.
276                 text_.current_font.setLanguage(latex_language);
277                 text_.real_current_font.setLanguage(latex_language);
278
279                 InsetCollapsable::doDispatch(cur, cmd);
280                 break;
281         }
282 }
283
284
285 bool InsetERT::getStatus(LCursor & cur, FuncRequest const & cmd,
286         FuncStatus & status) const
287 {
288         switch (cmd.action) {
289                 // suppress these
290                 case LFUN_ACCENT_ACUTE:
291                 case LFUN_ACCENT_BREVE:
292                 case LFUN_ACCENT_CARON:
293                 case LFUN_ACCENT_CEDILLA:
294                 case LFUN_ACCENT_CIRCLE:
295                 case LFUN_ACCENT_CIRCUMFLEX:
296                 case LFUN_ACCENT_DOT:
297                 case LFUN_ACCENT_GRAVE:
298                 case LFUN_ACCENT_HUNGARIAN_UMLAUT:
299                 case LFUN_ACCENT_MACRON:
300                 case LFUN_ACCENT_OGONEK:
301                 case LFUN_ACCENT_SPECIAL_CARON:
302                 case LFUN_ACCENT_TIE:
303                 case LFUN_ACCENT_TILDE:
304                 case LFUN_ACCENT_UMLAUT:
305                 case LFUN_ACCENT_UNDERBAR:
306                 case LFUN_ACCENT_UNDERDOT:
307                 case LFUN_APPENDIX:
308                 case LFUN_BREAK_LINE:
309                 case LFUN_CAPTION_INSERT:
310                 case LFUN_DEPTH_DECREMENT:
311                 case LFUN_DEPTH_INCREMENT:
312                 case LFUN_DOTS_INSERT:
313                 case LFUN_END_OF_SENTENCE_PERIOD_INSERT:
314                 case LFUN_ENVIRONMENT_INSERT:
315                 case LFUN_ERT_INSERT:
316                 case LFUN_FILE_INSERT:
317                 case LFUN_FLOAT_INSERT:
318                 case LFUN_FLOAT_WIDE_INSERT:
319                 case LFUN_WRAP_INSERT:
320                 case LFUN_FONT_BOLD:
321                 case LFUN_FONT_CODE:
322                 case LFUN_FONT_DEFAULT:
323                 case LFUN_FONT_EMPH:
324                 case LFUN_FONT_FREE_APPLY:
325                 case LFUN_FONT_FREE_UPDATE:
326                 case LFUN_FONT_NOUN:
327                 case LFUN_FONT_ROMAN:
328                 case LFUN_FONT_SANS:
329                 case LFUN_FONT_FRAK:
330                 case LFUN_FONT_ITAL:
331                 case LFUN_FONT_SIZE:
332                 case LFUN_FONT_STATE:
333                 case LFUN_FONT_UNDERLINE:
334                 case LFUN_FOOTNOTE_INSERT:
335                 case LFUN_HFILL_INSERT:
336                 case LFUN_HTML_INSERT:
337                 case LFUN_HYPHENATION_POINT_INSERT:
338                 case LFUN_LIGATURE_BREAK_INSERT:
339                 case LFUN_INDEX_INSERT:
340                 case LFUN_INDEX_PRINT:
341                 case LFUN_LABEL_INSERT:
342                 case LFUN_OPTIONAL_INSERT:
343                 case LFUN_BIBITEM_INSERT:
344                 case LFUN_LINE_INSERT:
345                 case LFUN_PAGEBREAK_INSERT:
346                 case LFUN_LANGUAGE:
347                 case LFUN_LAYOUT:
348                 case LFUN_LAYOUT_PARAGRAPH:
349                 case LFUN_LAYOUT_TABULAR:
350                 case LFUN_MARGINALNOTE_INSERT:
351                 case LFUN_MATH_DISPLAY:
352                 case LFUN_MATH_INSERT:
353                 case LFUN_MATH_MATRIX:
354                 case LFUN_MATH_MODE:
355                 case LFUN_MENU_OPEN:
356                 case LFUN_MENU_SEPARATOR_INSERT:
357                 case LFUN_BRANCH_INSERT:
358                 case LFUN_CHARSTYLE_INSERT:
359                 case LFUN_NOTE_INSERT:
360                 case LFUN_BOX_INSERT:
361                 case LFUN_NOTE_NEXT:
362                 case LFUN_PARAGRAPH_SPACING:
363                 case LFUN_LABEL_GOTO:
364                 case LFUN_REFERENCE_NEXT:
365                 case LFUN_SPACE_INSERT:
366                 case LFUN_SERVER_GOTO_FILE_ROW:
367                 case LFUN_SERVER_NOTIFY:
368                 case LFUN_SERVER_SET_XY:
369                 case LFUN_TABULAR_INSERT:
370                 case LFUN_TOC_INSERT:
371                 case LFUN_URL_INSERT:
372                 case LFUN_FLOAT_LIST:
373                 case LFUN_INSET_INSERT:
374                 case LFUN_PARAGRAPH_PARAMS_APPLY:
375                 case LFUN_PARAGRAPH_UPDATE:
376                 case LFUN_NOACTION:
377                         status.enabled(false);
378                         return true;
379
380                 case LFUN_QUOTE_INSERT:
381                 case LFUN_INSET_MODIFY:
382                 case LFUN_PASTE:
383                 case LFUN_PRIMARY_SELECTION_PASTE:
384                         status.enabled(true);
385                         return true;
386
387                 // this one is difficult to get right. As a half-baked
388                 // solution, we consider only the first action of the sequence
389                 case LFUN_COMMAND_SEQUENCE: {
390                         // argument contains ';'-terminated commands
391                         string const firstcmd = token(cmd.argument, ';', 0);
392                         FuncRequest func(lyxaction.lookupFunc(firstcmd));
393                         func.origin = cmd.origin;
394                         return getStatus(cur, func, status);
395                 }
396
397                 default:
398                         return InsetCollapsable::getStatus(cur, cmd, status);
399         }
400 }
401
402
403 void InsetERT::setButtonLabel()
404 {
405         setLabel(isOpen() ?  _("ERT") : getNewLabel(_("ERT")));
406 }
407
408
409 bool InsetERT::insetAllowed(InsetBase::Code /* code */) const
410 {
411         return false;
412 }
413
414
415 void InsetERT::metrics(MetricsInfo & mi, Dimension & dim) const
416 {
417         LyXFont tmpfont = mi.base.font;
418         getDrawFont(mi.base.font);
419         mi.base.font.realize(tmpfont);
420         InsetCollapsable::metrics(mi, dim);
421         mi.base.font = tmpfont;
422         dim_ = dim;
423 }
424
425
426 void InsetERT::draw(PainterInfo & pi, int x, int y) const
427 {
428         LyXFont tmpfont = pi.base.font;
429         getDrawFont(pi.base.font);
430         pi.base.font.realize(tmpfont);
431         InsetCollapsable::draw(pi, x, y);
432         pi.base.font = tmpfont;
433 }
434
435
436 bool InsetERT::showInsetDialog(BufferView * bv) const
437 {
438         InsetERTMailer(const_cast<InsetERT &>(*this)).showDialog(bv);
439         return true;
440 }
441
442
443 void InsetERT::getDrawFont(LyXFont & font) const
444 {
445         font = LyXFont(LyXFont::ALL_INHERIT, latex_language);
446         font.setFamily(LyXFont::TYPEWRITER_FAMILY);
447         font.setColor(LColor::latex);
448 }
449
450
451 string const InsetERTMailer::name_("ert");
452
453 InsetERTMailer::InsetERTMailer(InsetERT & inset)
454         : inset_(inset)
455 {}
456
457
458 string const InsetERTMailer::inset2string(Buffer const &) const
459 {
460         return params2string(inset_.status());
461 }
462
463
464 void InsetERTMailer::string2params(string const & in,
465                                    InsetCollapsable::CollapseStatus & status)
466 {
467         status = InsetCollapsable::Collapsed;
468         if (in.empty())
469                 return;
470
471         istringstream data(in);
472         LyXLex lex(0,0);
473         lex.setStream(data);
474
475         string name;
476         lex >> name;
477         if (name != name_)
478                 return print_mailer_error("InsetERTMailer", in, 1, name_);
479
480         int s;
481         lex >> s;
482         if (lex)
483                 status = static_cast<InsetCollapsable::CollapseStatus>(s);
484 }
485
486
487 string const
488 InsetERTMailer::params2string(InsetCollapsable::CollapseStatus status)
489 {
490         ostringstream data;
491         data << name_ << ' ' << status;
492         return data.str();
493 }