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