]> git.lyx.org Git - features.git/blob - src/insets/insetert.C
adjust
[features.git] / src / insets / insetert.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1998 The LyX Team.
7  *
8  *======================================================*/
9
10 #include <config.h>
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 #include "insetert.h"
17 #include "gettext.h"
18 #include "lyxfont.h"
19 #include "buffer.h"
20 #include "insets/insettext.h"
21 #include "support/LOstream.h"
22 #include "lyx_gui_misc.h"
23 #include "BufferView.h"
24 #include "LyXView.h"
25 #include "lyxtext.h"
26 #include "frontends/Dialogs.h"
27 #include "debug.h"
28
29 using std::ostream;
30
31 void InsetERT::init()
32 {
33         setButtonLabel();
34         labelfont = LyXFont(LyXFont::ALL_SANE);
35         labelfont.decSize();
36         labelfont.decSize();
37         labelfont.setColor(LColor::latex);
38         setInsetName("ERT");
39                 
40 }
41
42
43 InsetERT::InsetERT(bool collapsed)
44         : InsetCollapsable(collapsed)
45 {
46         if (collapsed)
47                 status_ = Collapsed;
48         else
49                 status_ = Open;
50         init();
51 }
52
53
54 InsetERT::InsetERT(InsetERT const & in, bool same_id)
55         : InsetCollapsable(in, same_id), status_(in.status_)
56 {
57         init();
58 }
59
60
61 Inset * InsetERT::clone(Buffer const &, bool same_id) const
62 {
63         return new InsetERT(*const_cast<InsetERT *>(this), same_id);
64 }
65
66
67 InsetERT::InsetERT(string const & contents, bool collapsed)
68         : InsetCollapsable(collapsed)
69 {
70         LyXFont font(LyXFont::ALL_INHERIT);
71         font.setFamily(LyXFont::TYPEWRITER_FAMILY);
72         font.setColor(LColor::latex);
73         string::const_iterator cit = contents.begin();
74         string::const_iterator end = contents.end();
75         Paragraph::size_type pos = 0;
76         for (; cit != end; ++cit) {
77                 inset.paragraph()->insertChar(pos++, *cit, font);
78         }
79         // the init has to be after the initialization of the paragraph
80         // because of the label settings (draw_label for ert insets).
81         init();
82 }
83
84
85 InsetERT::~InsetERT()
86 {
87         hideDialog();
88 }
89
90
91 void InsetERT::read(Buffer const * buf, LyXLex & lex)
92 {
93         bool token_found = false;
94         if (lex.isOK()) {
95                 lex.next();
96                 string const token = lex.getString();
97                 if (token == "status") {
98                         lex.next();
99                         string const tmp_token = lex.getString();
100                         
101                         if (tmp_token == "Inlined") {
102                                 status_ = Inlined;
103                         } else if (tmp_token == "Collapsed") {
104                                 status_ = Collapsed;
105                         } else {
106                                 // leave this as default!
107                                 status_ = Open;
108                         }
109                         
110                         token_found = true;
111                 } else {
112                         lyxerr << "InsetERT::Read: Missing 'status'-tag!"
113                                    << std::endl;
114                         // take countermeasures
115                         lex.pushToken(token);
116                 }
117         }
118         InsetCollapsable::read(buf, lex);
119         if (!token_found) {
120                 if (collapsed_) {
121                         status_ = Collapsed;
122                 } else {
123                         status_ = Open;
124                 }
125         }
126         setButtonLabel();
127 }
128
129
130 void InsetERT::write(Buffer const * buf, ostream & os) const 
131 {
132         string st;
133
134         switch(status_) {
135         case Open: 
136                 st = "Open";
137                 break;
138         case Collapsed:
139                 st = "Collapsed";
140                 break;
141         case Inlined:
142                 st = "Inlined";
143                 break;
144         }
145
146         os << getInsetName() << "\n"
147            << "status "<< st << "\n";
148         InsetCollapsable::write(buf, os);
149 }
150
151
152 string const InsetERT::editMessage() const 
153 {
154         return _("Opened ERT Inset");
155 }
156
157
158 bool InsetERT::insertInset(BufferView *, Inset *)
159 {
160         return false;
161 }
162
163
164 void InsetERT::setFont(BufferView *, LyXFont const &, bool, bool selectall)
165 {
166         // if selectall is activated then the fontchange was an outside general
167         // fontchange and this messages is not needed
168         if (!selectall)
169                 WriteAlert(_("Impossible Operation!"),
170                            _("Not permitted to change font-types inside ERT-insets!"),
171                            _("Sorry."));
172 }
173
174
175 void InsetERT::edit(BufferView * bv, int x, int y, unsigned int button)
176 {
177         InsetCollapsable::edit(bv, x, y, button);
178         set_latex_font(bv);
179 }
180
181
182 Inset::EDITABLE InsetERT::editable() const
183 {
184         if (status_ == Collapsed)
185                 return IS_EDITABLE;
186         return HIGHLY_EDITABLE;
187 }
188
189
190 void InsetERT::edit(BufferView * bv, bool front)
191 {
192         InsetCollapsable::edit(bv, front);
193         set_latex_font(bv);
194 }
195
196
197 void InsetERT::insetButtonRelease(BufferView * bv, int x, int y, int button)
198 {
199         if (button == 3) {
200                 showInsetDialog(bv);
201                 return;
202         }
203         if ((x >= 0)  && (x < button_length) &&
204             (y >= button_top_y) &&  (y <= button_bottom_y))
205         {
206 //              if (collapsed_) {
207 //                      setLabel(_("ERT"));
208 //              } else {
209 //                      setLabel(get_new_label());
210 //              }
211                 if (collapsed_) {
212                         status(bv, Open);
213 //                      collapsed_ = false;
214 //                      inset.insetButtonRelease(bv, 0, 0, button);
215 //                      inset.setUpdateStatus(bv, InsetText::FULL);
216 //                      bv->updateInset(this, true);
217                 } else {
218                         status(bv, Collapsed);
219 //                      collapsed_ = true;
220 //                      bv->unlockInset(this);
221 //                      bv->updateInset(this, true);
222                 }
223         } else if (!collapsed_ && (y > button_bottom_y)) {
224                 LyXFont font(LyXFont::ALL_SANE);
225                 int yy = ascent(bv, font) + y -
226                     (ascent_collapsed() +
227                      descent_collapsed() +
228                      inset.ascent(bv, font));
229                 inset.insetButtonRelease(bv, x, yy, button);
230         }
231 }
232
233
234 int InsetERT::latex(Buffer const *, std::ostream & os, bool /*fragile*/,
235                     bool /*free_spc*/) const
236 {
237         Paragraph * par = inset.paragraph();
238         while (par) {
239                 Paragraph::size_type siz = inset.paragraph()->size();
240                 for (Paragraph::size_type i = 0; i != siz; ++i) {
241                         char c = inset.paragraph()->getChar(i);
242                         switch (c) {
243                         case Paragraph::META_NEWLINE:
244                                 os << '\n';
245                                 break;
246                         default:
247                                 os << c;
248                                 break;
249                         }
250                 }
251                 par = par->next();
252         }
253         
254         return 1;
255 }
256
257
258 int InsetERT::ascii(Buffer const *,
259                     std::ostream &, int /*linelen*/) const 
260 {
261         return 0;
262 }
263
264
265 int InsetERT::linuxdoc(Buffer const *, std::ostream &) const
266 {
267         return 0;
268 }
269
270
271 int InsetERT::docBook(Buffer const *, std::ostream &) const
272 {
273         return 0;
274 }
275
276
277 UpdatableInset::RESULT
278 InsetERT::localDispatch(BufferView * bv, kb_action action, string const & arg)
279 {
280         UpdatableInset::RESULT result = DISPATCHED_NOUPDATE;
281
282         if (!inset.paragraph()->size()) {
283                 set_latex_font(bv);
284         }
285
286         switch(action) {
287         case LFUN_LAYOUT:
288                 bv->owner()->setLayout(inset.paragraph()->getLayout());
289                 break;
290         default:
291                 result = InsetCollapsable::localDispatch(bv, action, arg);
292         }
293         switch(action) {
294         case LFUN_BREAKPARAGRAPH:
295         case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
296                 set_latex_font(bv);
297                 break;
298         
299         default:
300                 break;
301         }
302         return result;
303 }
304
305
306 string const InsetERT::get_new_label() const
307 {
308         string la;
309         Paragraph::size_type const max_length = 15;
310
311         Paragraph::size_type const p_siz = inset.paragraph()->size();
312         Paragraph::size_type const n = std::min(max_length, p_siz);
313         int i = 0;
314         int j = 0;
315         for(; i < n && j < p_siz; ++j) {
316                 if (inset.paragraph()->isInset(j))
317                         continue;
318                 la += inset.paragraph()->getChar(j);
319                 ++i;
320         }
321         if (i > 0 && j < p_siz) {
322                 la += "...";
323         }
324         if (la.empty()) {
325                 la = _("ERT");
326         }
327         return la;
328 }
329
330
331 void InsetERT::setButtonLabel() 
332 {
333         if (status_ == Collapsed) {
334                 setLabel(get_new_label());
335         } else {
336                 setLabel(_("ERT"));
337         }
338 }
339
340
341 bool InsetERT::checkInsertChar(LyXFont & font)
342 {
343         LyXFont f(LyXFont::ALL_INHERIT);
344         font = f;
345         font.setFamily(LyXFont::TYPEWRITER_FAMILY);
346         font.setColor(LColor::latex);
347         return true;
348 }
349
350
351 int InsetERT::ascent(BufferView * bv, LyXFont const & font) const
352 {
353         if (!inlined())
354                 return InsetCollapsable::ascent(bv, font);
355
356         return inset.ascent(bv, font);
357 }
358
359
360 int InsetERT::descent(BufferView * bv, LyXFont const & font) const
361 {
362         if (!inlined())
363                 return InsetCollapsable::descent(bv, font);
364
365         return inset.descent(bv, font);
366 }
367
368
369 int InsetERT::width(BufferView * bv, LyXFont const & font) const
370 {
371         if (!inlined())
372                 return InsetCollapsable::width(bv, font);
373
374         return inset.width(bv, font);
375 }
376
377
378 void InsetERT::draw(BufferView * bv, LyXFont const & f, 
379                     int baseline, float & x, bool cleared) const
380 {
381         Painter & pain = bv->painter();
382
383         button_length = width_collapsed();
384         button_top_y = -ascent(bv, f);
385         button_bottom_y = -ascent(bv, f) + ascent_collapsed() +
386                 descent_collapsed();
387
388         if (!isOpen()) {
389                 draw_collapsed(pain, baseline, x);
390                 x += TEXT_TO_INSET_OFFSET;
391                 return;
392         }
393
394         float old_x = x;
395
396         if (!owner())
397                 x += static_cast<float>(scroll());
398
399         if (!cleared && (inset.need_update == InsetText::FULL ||
400                          inset.need_update == InsetText::INIT ||
401                          top_x != int(x) ||
402                          top_baseline != baseline))
403         {
404                 // we don't need anymore to clear here we just have to tell
405                 // the underlying LyXText that it should do the RowClear!
406                 inset.setUpdateStatus(bv, InsetText::FULL);
407                 bv->text->status(bv, LyXText::CHANGED_IN_DRAW);
408                 return;
409         }
410
411         top_x = int(x);
412         top_baseline = baseline;
413
414         int const bl = baseline - ascent(bv, f) + ascent_collapsed();
415
416         if (inlined()) {
417                 inset.draw(bv, f, baseline, x, cleared);
418         } else {
419                 draw_collapsed(pain, bl, old_x);
420                 inset.draw(bv, f, 
421                                    bl + descent_collapsed() + inset.ascent(bv, f),
422                                    x, cleared);
423         }
424         need_update = NONE;
425 }
426
427
428 void InsetERT::set_latex_font(BufferView * bv)
429 {
430         LyXFont font(LyXFont::ALL_INHERIT);
431
432         font.setFamily(LyXFont::TYPEWRITER_FAMILY);
433         font.setColor(LColor::latex);
434         inset.getLyXText(bv)->setFont(bv, font, false);
435 }
436
437
438 void InsetERT::status(BufferView * bv, ERTStatus const st)
439 {
440         if (st != status_) {
441                 status_ = st;
442                 switch(st) {
443                 case Inlined:
444                         inset.setAutoBreakRows(false);
445                         break;
446                 case Open:
447                         inset.setAutoBreakRows(true);
448                         collapsed_ = false;
449                         need_update = FULL;
450                         setButtonLabel();
451                         break;
452                 case Collapsed:
453                         inset.setAutoBreakRows(true);
454                         collapsed_ = true;
455                         need_update = FULL;
456                         setButtonLabel();
457                         bv->unlockInset(this);
458                         break;
459                 }
460                 bv->updateInset(this, true);
461         }
462 }
463
464
465 bool InsetERT::showInsetDialog(BufferView * bv) const
466 {
467         bv->owner()->getDialogs()->showERT(const_cast<InsetERT *>(this));
468         return true;
469 }
470
471
472 void InsetERT::open(BufferView * bv)
473 {
474         if (!collapsed_)
475                 return;
476         status(bv, Open);
477 }
478
479
480 void InsetERT::close(BufferView * bv)
481 {
482         if (collapsed_)
483                 return;
484         status(bv, Collapsed);
485 }