]> git.lyx.org Git - lyx.git/blob - src/insets/insetert.C
Cruft removal, small clean-up, no functional changes.
[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 "debug.h"
20 #include "dispatchresult.h"
21 #include "funcrequest.h"
22 #include "gettext.h"
23 #include "language.h"
24 #include "LColor.h"
25 #include "lyxlex.h"
26 #include "metricsinfo.h"
27 #include "paragraph.h"
28
29 #include "frontends/Alert.h"
30 #include "frontends/LyXView.h"
31
32 #include "support/std_sstream.h"
33
34 using lyx::pos_type;
35
36 using std::endl;
37 using std::min;
38
39 using std::auto_ptr;
40 using std::istringstream;
41 using std::ostream;
42 using std::ostringstream;
43 using std::string;
44
45
46 void InsetERT::init()
47 {
48         setButtonLabel();
49
50         LyXFont font(LyXFont::ALL_SANE);
51         font.decSize();
52         font.decSize();
53         font.setColor(LColor::latex);
54         setLabelFont(font);
55
56         setInsetName("ERT");
57 }
58
59
60 InsetERT::InsetERT(BufferParams const & bp, bool collapsed)
61         : InsetCollapsable(bp, collapsed)
62 {
63         status_ = collapsed ? Collapsed : Open;
64         init();
65 }
66
67
68 InsetERT::InsetERT(InsetERT const & in)
69         : InsetCollapsable(in)
70 {
71         init();
72 }
73
74
75 auto_ptr<InsetBase> InsetERT::clone() const
76 {
77         return auto_ptr<InsetBase>(new InsetERT(*this));
78 }
79
80
81 InsetERT::InsetERT(BufferParams const & bp,
82                    Language const * l, string const & contents, bool collapsed)
83         : InsetCollapsable(bp, collapsed)
84 {
85         status_ = collapsed ? Collapsed : Open;
86
87         LyXFont font(LyXFont::ALL_INHERIT, l);
88         string::const_iterator cit = contents.begin();
89         string::const_iterator end = contents.end();
90         pos_type pos = 0;
91         for (; cit != end; ++cit) {
92                 inset.paragraphs().begin()->insertChar(pos++, *cit, font);
93         }
94         // the init has to be after the initialization of the paragraph
95         // because of the label settings (draw_label for ert insets).
96         init();
97 }
98
99
100 InsetERT::~InsetERT()
101 {
102         InsetERTMailer(*this).hideDialog();
103 }
104
105
106 void InsetERT::read(Buffer const & buf, LyXLex & lex)
107 {
108         bool token_found = false;
109         if (lex.isOK()) {
110                 lex.next();
111                 string const token = lex.getString();
112                 if (token == "status") {
113                         lex.next();
114                         string const tmp_token = lex.getString();
115
116                         if (tmp_token == "Inlined") {
117                                 status_ = Inlined;
118                         } else if (tmp_token == "Collapsed") {
119                                 status_ = Collapsed;
120                         } else {
121                                 // leave this as default!
122                                 status_ = Open;
123                         }
124
125                         token_found = true;
126                 } else {
127                         lyxerr << "InsetERT::Read: Missing 'status'-tag!"
128                                    << endl;
129                         // take countermeasures
130                         lex.pushToken(token);
131                 }
132         }
133         inset.read(buf, lex);
134
135         if (!token_found) {
136                 if (isOpen())
137                         status_ = Open;
138                 else
139                         status_ = Collapsed;
140         }
141         setButtonLabel();
142 }
143
144
145 void InsetERT::write(Buffer const & buf, ostream & os) const
146 {
147         string st;
148
149         switch (status_) {
150         case Open:
151                 st = "Open";
152                 break;
153         case Collapsed:
154                 st = "Collapsed";
155                 break;
156         case Inlined:
157                 st = "Inlined";
158                 break;
159         }
160
161         os << getInsetName() << "\n" << "status "<< st << "\n";
162
163         //inset.writeParagraphData(buf, os);
164         string const layout(buf.params().getLyXTextClass().defaultLayoutName());
165         ParagraphList::iterator par = inset.paragraphs().begin();
166         ParagraphList::iterator end = inset.paragraphs().end();
167         for (; par != end; ++par) {
168                 os << "\n\\begin_layout " << layout << "\n";
169                 pos_type siz = par->size();
170                 for (pos_type i = 0; i < siz; ++i) {
171                         Paragraph::value_type c = par->getChar(i);
172                         switch (c) {
173                         case Paragraph::META_INSET:
174                                 if (par->getInset(i)->lyxCode() != InsetOld::NEWLINE_CODE) {
175                                         lyxerr << "Element is not allowed in insertERT"
176                                                << endl;
177                                 } else {
178                                         par->getInset(i)->write(buf, os);
179                                 }
180                                 break;
181
182                         case '\\':
183                                 os << "\n\\backslash \n";
184                                 break;
185                         default:
186                                 os << c;
187                                 break;
188                         }
189                 }
190                 os << "\n\\end_layout\n";
191         }
192 }
193
194
195 string const InsetERT::editMessage() const
196 {
197         return _("Opened ERT Inset");
198 }
199
200
201 void InsetERT::updateStatus(bool swap) const
202 {
203         if (status_ != Inlined) {
204                 if (isOpen())
205                         status_ = swap ? Collapsed : Open;
206                 else
207                         status_ = swap ? Open : Collapsed;
208                 setButtonLabel();
209         }
210 }
211
212
213 void InsetERT::lfunMousePress(FuncRequest const & cmd)
214 {
215         if (status_ == Inlined)
216                 inset.dispatch(cmd);
217         else {
218                 idx_type idx = 0;
219                 pos_type pos = 0;
220                 InsetCollapsable::priv_dispatch(cmd, idx, pos);
221         }
222 }
223
224
225 bool InsetERT::lfunMouseRelease(FuncRequest const & cmd)
226 {
227         BufferView * bv = cmd.view();
228
229         if (cmd.button() == mouse_button::button3) {
230                 showInsetDialog(bv);
231                 return true;
232         }
233
234         if (status_ != Inlined && hitButton(cmd)) {
235                 updateStatus(true);
236         } else {
237                 FuncRequest cmd1 = cmd;
238 #warning metrics?
239                 cmd1.y = ascent() + cmd.y - inset.ascent();
240
241                 // inlined is special - the text appears above
242                 if (status_ == Inlined)
243                         inset.dispatch(cmd1);
244                 else if (isOpen() && cmd.y > buttonDim().y2) {
245                         cmd1.y -= height_collapsed();
246                         inset.dispatch(cmd1);
247                 }
248         }
249         return false;
250 }
251
252
253 void InsetERT::lfunMouseMotion(FuncRequest const & cmd)
254 {
255         if (status_ == Inlined)
256                 inset.dispatch(cmd);
257         else {
258                 idx_type idx = 0;
259                 pos_type pos = 0;
260                 InsetCollapsable::priv_dispatch(cmd, idx, pos);
261         }
262 }
263
264
265 int InsetERT::latex(Buffer const &, ostream & os,
266                     OutputParams const &) const
267 {
268         ParagraphList::iterator par = inset.paragraphs().begin();
269         ParagraphList::iterator end = inset.paragraphs().end();
270
271         int lines = 0;
272         while (par != end) {
273                 pos_type siz = par->size();
274                 for (pos_type i = 0; i < siz; ++i) {
275                         // ignore all struck out text
276                         if (isDeletedText(*par, i))
277                                 continue;
278
279                         if (par->isNewline(i)) {
280                                 os << '\n';
281                                 ++lines;
282                         } else {
283                                 os << par->getChar(i);
284                         }
285                 }
286                 ++par;
287                 if (par != end) {
288                         os << "\n";
289                         ++lines;
290                 }
291         }
292
293         return lines;
294 }
295
296
297 int InsetERT::plaintext(Buffer const &, ostream &,
298                     OutputParams const & /*runparams*/) const
299 {
300         return 0;
301 }
302
303
304 int InsetERT::linuxdoc(Buffer const &, ostream & os,
305                        OutputParams const &)const
306 {
307         ParagraphList::iterator par = inset.paragraphs().begin();
308         ParagraphList::iterator end = inset.paragraphs().end();
309
310         int lines = 0;
311         while (par != end) {
312                 pos_type siz = par->size();
313                 for (pos_type i = 0; i < siz; ++i) {
314                         if (par->isNewline(i)) {
315                                 os << '\n';
316                                 ++lines;
317                         } else {
318                                 os << par->getChar(i);
319                         }
320                 }
321                 ++par;
322                 if (par != end) {
323                         os << "\n";
324                         lines ++;
325                 }
326         }
327
328         return lines;
329 }
330
331
332 int InsetERT::docbook(Buffer const &, ostream & os,
333                       OutputParams const &) const
334 {
335         ParagraphList::iterator par = inset.paragraphs().begin();
336         ParagraphList::iterator end = inset.paragraphs().end();
337
338         int lines = 0;
339         while (par != end) {
340                 pos_type siz = par->size();
341                 for (pos_type i = 0; i < siz; ++i) {
342                         if (par->isNewline(i)) {
343                                 os << '\n';
344                                 ++lines;
345                         } else {
346                                 os << par->getChar(i);
347                         }
348                 }
349                 ++par;
350                 if (par != end) {
351                         os << "\n";
352                         lines ++;
353                 }
354         }
355
356         return lines;
357 }
358
359
360 void InsetERT::edit(BufferView * bv, bool left)
361 {
362         if (status_ == Inlined)
363                 inset.edit(bv, left);
364         else
365                 InsetCollapsable::edit(bv, left);
366         updateStatus();
367 }
368
369
370 DispatchResult
371 InsetERT::priv_dispatch(FuncRequest const & cmd, idx_type & idx, pos_type & pos)
372 {
373         switch (cmd.action) {
374
375         case LFUN_MOUSE_PRESS:
376                 lfunMousePress(cmd);
377                 return DispatchResult(true, true);
378
379         case LFUN_MOUSE_MOTION:
380                 lfunMouseMotion(cmd);
381                 return DispatchResult(true, true);
382
383         case LFUN_MOUSE_RELEASE:
384                 lfunMouseRelease(cmd);
385                 return DispatchResult(true, true);
386
387         case LFUN_INSET_MODIFY:
388                 InsetERTMailer::string2params(cmd.argument, status_);
389                 setButtonLabel();
390                 return DispatchResult(true, true);
391
392         case LFUN_LAYOUT:
393         case LFUN_BOLD:
394         case LFUN_CODE:
395         case LFUN_DEFAULT:
396         case LFUN_EMPH:
397         case LFUN_FREEFONT_APPLY:
398         case LFUN_FREEFONT_UPDATE:
399         case LFUN_NOUN:
400         case LFUN_ROMAN:
401         case LFUN_SANS:
402         case LFUN_FRAK:
403         case LFUN_ITAL:
404         case LFUN_FONT_SIZE:
405         case LFUN_FONT_STATE:
406         case LFUN_UNDERLINE:
407                 return DispatchResult(true);
408
409         default:
410                 return InsetCollapsable::priv_dispatch(cmd, idx, pos);
411         }
412 }
413
414
415 void InsetERT::setButtonLabel() const
416 {
417         setLabel(status_ == Collapsed ? getNewLabel(_("ERT")) : _("ERT"));
418 }
419
420
421 bool InsetERT::insetAllowed(InsetOld::Code code) const
422 {
423         return code == InsetOld::NEWLINE_CODE;
424 }
425
426
427 void InsetERT::metrics(MetricsInfo & mi, Dimension & dim) const
428 {
429         LyXFont tmpfont = mi.base.font;
430         getDrawFont(mi.base.font);
431         InsetCollapsable::metrics(mi, dim);
432         mi.base.font = tmpfont;
433         dim_ = dim;
434 }
435
436
437 void InsetERT::draw(PainterInfo & pi, int x, int y) const
438 {
439         LyXFont tmpfont = pi.base.font;
440         getDrawFont(pi.base.font);
441         InsetCollapsable::draw(pi, x, y);
442         pi.base.font = tmpfont;
443 }
444
445
446 void InsetERT::setStatus(CollapseStatus st)
447 {
448         status_ = st;
449         setButtonLabel();
450 }
451
452
453 bool InsetERT::showInsetDialog(BufferView * bv) const
454 {
455         InsetERTMailer(const_cast<InsetERT &>(*this)).showDialog(bv);
456         return true;
457 }
458
459
460 void InsetERT::getDrawFont(LyXFont & font) const
461 {
462         font = LyXFont(LyXFont::ALL_INHERIT, latex_language);
463         font.setFamily(LyXFont::TYPEWRITER_FAMILY);
464         font.setColor(LColor::latex);
465 }
466
467
468 string const InsetERTMailer::name_("ert");
469
470 InsetERTMailer::InsetERTMailer(InsetERT & inset)
471         : inset_(inset)
472 {}
473
474
475 string const InsetERTMailer::inset2string(Buffer const &) const
476 {
477         return params2string(inset_.status());
478 }
479
480
481 void InsetERTMailer::string2params(string const & in,
482                                    InsetCollapsable::CollapseStatus & status)
483 {
484         status = InsetCollapsable::Collapsed;
485         if (in.empty())
486                 return;
487
488         istringstream data(in);
489         LyXLex lex(0,0);
490         lex.setStream(data);
491
492         string name;
493         lex >> name;
494         if (name != name_)
495                 return print_mailer_error("InsetERTMailer", in, 1, name_);
496
497         int s;
498         lex >> s;
499         if (lex)
500                 status = static_cast<InsetCollapsable::CollapseStatus>(s);
501 }
502
503
504 string const
505 InsetERTMailer::params2string(InsetCollapsable::CollapseStatus status)
506 {
507         ostringstream data;
508         data << name_ << ' ' << status;
509         return data.str();
510 }