]> git.lyx.org Git - lyx.git/blob - src/insets/inset.h
another fix
[lyx.git] / src / insets / inset.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  *
5  *           LyX, The Document Processor
6  *
7  *           Copyright 1995-2001 the LyX Team.
8  *
9  * ====================================================== */
10
11 #ifndef INSET_H
12 #define INSET_H
13
14 #ifdef __GNUG__
15 #pragma interface
16 #endif
17
18 #include <vector>
19 #include "LString.h"
20 #include "LColor.h"
21 #include "frontends/mouse_state.h"
22
23 class LyXFont;
24 class BufferView;
25 class Buffer;
26 class Painter;
27 class LyXText;
28 class LyXLex;
29 class Paragraph;
30 class LyXCursor;
31 class FuncRequest;
32 class WordLangTuple;
33
34 struct LaTeXFeatures;
35
36 namespace grfx {
37         class PreviewLoader;
38 }
39
40 /// Insets
41 class Inset {
42 public:
43         /** This is not quite the correct place for this enum. I think
44             the correct would be to let each subclass of Inset declare
45             its own enum code. Actually the notion of an Inset::Code
46             should be avoided, but I am not sure how this could be done
47             in a cleaner way. */
48         enum Code {
49                 ///
50                 NO_CODE,
51                 ///
52                 TOC_CODE,  // do these insets really need a code? (ale)
53                 ///
54                 QUOTE_CODE,
55                 ///
56                 MARK_CODE,
57                 ///
58                 REF_CODE, // 5
59                 ///
60                 URL_CODE,
61                 ///
62                 HTMLURL_CODE,
63                 ///
64                 SEPARATOR_CODE,
65                 ///
66                 ENDING_CODE,
67                 ///
68                 LABEL_CODE, // 10
69                 ///
70                 NOTE_CODE,
71                 ///
72                 ACCENT_CODE,
73                 ///
74                 MATH_CODE,
75                 ///
76                 INDEX_CODE,
77                 ///
78                 INCLUDE_CODE, // 15
79                 ///
80                 GRAPHICS_CODE,
81                 ///
82                 PARENT_CODE,
83                 ///
84                 BIBTEX_CODE,
85                 ///
86                 TEXT_CODE,
87                 ///
88                 ERT_CODE, // 20
89                 ///
90                 FOOT_CODE,
91                 ///
92                 MARGIN_CODE,
93                 ///
94                 FLOAT_CODE,
95                 ///
96                 MINIPAGE_CODE,
97                 ///
98                 SPECIALCHAR_CODE, // 25
99                 ///
100                 TABULAR_CODE,
101                 ///
102                 EXTERNAL_CODE,
103 #if 0
104                 ///
105                 THEOREM_CODE,
106 #endif
107                 ///
108                 CAPTION_CODE,
109                 ///
110                 MATHMACRO_CODE, // 30
111                 ///
112                 ERROR_CODE,
113                 ///
114                 CITE_CODE,
115                 ///
116                 FLOAT_LIST_CODE,
117                 ///
118                 INDEX_PRINT_CODE,
119                 ///
120                 OPTARG_CODE
121         };
122
123         ///
124         enum {
125                 ///
126                 TEXT_TO_INSET_OFFSET = 2
127         };
128
129         ///
130         enum EDITABLE {
131                 ///
132                 NOT_EDITABLE = 0,
133                 ///
134                 IS_EDITABLE,
135                 ///
136                 HIGHLY_EDITABLE
137         };
138
139         /** Dispatch result codes
140             Now that nested updatable insets are allowed, the local dispatch
141             becomes a bit complex, just two possible results (boolean)
142             are not enough.
143
144             DISPATCHED          = the inset catched the action
145             DISPATCHED_NOUPDATE = the inset catched the action and no update
146                                   is needed here to redraw the inset
147             FINISHED            = the inset must be unlocked as a result
148                                   of the action
149             FINISHED_RIGHT      = FINISHED, but put the cursor to the RIGHT of
150                                   the inset.
151             FINISHED_UP         = FINISHED, but put the cursor UP of
152                                   the inset.
153             FINISHED_DOWN       = FINISHED, but put the cursor DOWN of
154                                   the inset.
155             UNDISPATCHED        = the action was not catched, it should be
156                                   dispatched by lower level insets
157         */
158         enum RESULT {
159                 UNDISPATCHED = 0,
160                 DISPATCHED,
161                 DISPATCHED_NOUPDATE,
162                 FINISHED,
163                 FINISHED_RIGHT,
164                 FINISHED_UP,
165                 FINISHED_DOWN
166         };
167
168         /// To convert old binary dispatch results
169         RESULT DISPATCH_RESULT(bool b) {
170                 return b ? DISPATCHED : FINISHED;
171         }
172
173         ///
174         Inset();
175         ///
176         Inset(Inset const & in, bool same_id = false);
177         ///
178         virtual ~Inset() {}
179         ///
180         virtual int ascent(BufferView *, LyXFont const &) const = 0;
181         ///
182         virtual int descent(BufferView *, LyXFont const &) const = 0;
183         ///
184         virtual int width(BufferView *, LyXFont const &) const = 0;
185         ///
186         virtual void draw(BufferView *, LyXFont const &,
187                           int baseline, float & x, bool cleared) const = 0;
188         /// update the inset representation
189         virtual void update(BufferView *, LyXFont const &, bool = false)
190                 {}
191         /// what appears in the minibuffer when opening
192         virtual string const editMessage() const;
193         ///
194         virtual void edit(BufferView *, int x, int y, mouse_button::state button);
195         ///
196         virtual void edit(BufferView *, bool front = true);
197         ///
198         virtual EDITABLE editable() const;
199         /// 
200         virtual RESULT localDispatch(FuncRequest const & cmd);
201         ///
202         virtual bool isTextInset() const { return false; }
203         ///
204         virtual bool doClearArea() const { return true; }
205         ///
206         virtual bool autoDelete() const;
207         /// returns true the inset can hold an inset of given type
208         virtual bool insetAllowed(Inset::Code) const { return false; }
209         /// wrapper around the above
210         bool insetAllowed(Inset * in) const;
211         ///
212         virtual void write(Buffer const *, std::ostream &) const = 0;
213         ///
214         virtual void read(Buffer const *, LyXLex & lex) = 0;
215         /** returns the number of rows (\n's) of generated tex code.
216             fragile == true means, that the inset should take care about
217             fragile commands by adding a \protect before.
218             If the free_spc (freespacing) variable is set, then this inset
219             is in a free-spacing paragraph.
220         */
221         virtual int latex(Buffer const *, std::ostream &, bool fragile,
222                           bool free_spc) const = 0;
223         ///
224         virtual int ascii(Buffer const *,
225                           std::ostream &, int linelen = 0) const = 0;
226         ///
227         virtual int linuxdoc(Buffer const *, std::ostream &) const = 0;
228         ///
229         virtual int docbook(Buffer const *, std::ostream &, bool) const = 0;
230         /// Updates needed features for this inset.
231         virtual void validate(LaTeXFeatures & features) const;
232         ///
233         virtual bool deletable() const;
234
235         /// returns LyX code associated with the inset. Used for TOC, ...)
236         virtual Inset::Code lyxCode() const { return NO_CODE; }
237
238         virtual std::vector<string> const getLabelList() const {
239                 return std::vector<string>();
240         }
241
242         ///
243         virtual Inset * clone(Buffer const &, bool same_ids = false) const = 0;
244
245         /// returns true to override begin and end inset in file
246         virtual bool directWrite() const;
247
248         /// Returns true if the inset should be centered alone
249         virtual bool display() const { return false; }
250         /// Changes the display state of the inset
251         virtual void display(bool) {}
252         ///
253         /// returns true if this inset needs a row on it's own
254         ///
255         virtual bool needFullRow() const { return false; }
256         ///
257         void setInsetName(string const & s) { name_ = s; }
258         ///
259         string const & getInsetName() const { return name_; }
260         ///
261         void setOwner(Inset * inset) { owner_ = inset; }
262         ///
263         Inset * owner() const { return owner_; }
264         ///
265         void parOwner(Paragraph * par) { par_owner_ = par; }
266         ///
267         Paragraph * parOwner() const {return par_owner_; }
268         ///
269         void setBackgroundColor(LColor::color);
270         ///
271         LColor::color backgroundColor() const;
272         ///
273         int x() const { return top_x; }
274         ///
275         int y() const { return top_baseline; }
276         //
277         // because we could have fake text insets and have to call this
278         // inside them without cast!!!
279         ///
280         virtual LyXText * getLyXText(BufferView const *,
281                                      bool const recursive = false) const;
282         ///
283         virtual void deleteLyXText(BufferView *, bool = true) const {}
284         ///
285         virtual void resizeLyXText(BufferView *, bool /*force*/= false) const {}
286         /// returns the actuall scroll-value
287         virtual int scroll(bool recursive=true) const {
288                 if (!recursive || !owner_)
289                         return scx;
290                 return 0;
291         }
292         /// try to get a paragraph pointer from it's id if we have a
293         /// paragraph to give back!
294         virtual Paragraph * getParFromID(int /* id */) const {
295                 return 0;
296         }
297         /// try to get a inset pointer from it's id if we have
298         /// an inset to give back!
299         virtual Inset * getInsetFromID(int /* id */) const {
300                 return 0;
301         }
302         /// if this insets owns paragraphs (f.ex. InsetText) then it
303         /// should return it's very first one!
304         virtual Paragraph * firstParagraph() const {
305                 return 0;
306         }
307
308         ///
309         virtual Paragraph * getFirstParagraph(int /*num*/) const {
310                 return 0;
311         }
312
313         /// return the cursor if we own one otherwise giv'em just the
314         /// BufferView cursor to work with.
315         virtual LyXCursor const & cursor(BufferView * bview) const;
316         /// id functions
317         int id() const;
318         ///
319         void id(int id_arg);
320
321         /// used to toggle insets
322         // is the inset open?
323         virtual bool isOpen() const { return false; }
324         /// open the inset
325         virtual void open(BufferView *) {}
326         /// close the inset
327         virtual void close(BufferView *) const {}
328         /// check if the font of the char we want inserting is correct
329         /// and modify it if it is not.
330         virtual bool checkInsertChar(LyXFont &);
331         /// we need this here because collapsed insets are only EDITABLE
332         virtual void setFont(BufferView *, LyXFont const &,
333                          bool toggleall = false, bool selectall = false);
334         ///
335         // needed for spellchecking text
336         ///
337         virtual bool allowSpellcheck() { return false; }
338
339         // should this inset be handled like a normal charater
340         virtual bool isChar() const { return false; }
341         // is this equivalent to a letter?
342         virtual bool isLetter() const { return false; }
343         // is this equivalent to a space (which is BTW different from
344         // a line separator)?
345         virtual bool isSpace() const { return false; }
346         // should we break lines after this inset?
347         virtual bool isLineSeparator() const { return false; }
348         // if this inset has paragraphs should they be output all as default
349         // paragraphs with "Standard" layout?
350         virtual bool forceDefaultParagraphs(Inset const *) const;
351         /** returns true if, when outputing LaTeX, font changes should
352             be closed before generating this inset. This is needed for
353             insets that may contain several paragraphs */
354         virtual bool noFontChange() const { return false; }
355         //
356         virtual void getDrawFont(LyXFont &) const {}
357         /* needed for widths which are % of something
358            returns the value of \textwidth in this inset. Most of the
359            time this is the width of the workarea, but if there is a
360            minipage somewhere, it will be the width of this minipage */
361         virtual int latexTextWidth(BufferView *) const;
362
363         /** Adds a LaTeX snippet to the Preview Loader for transformation
364          *  into a bitmap image. Does not start the laoding process.
365          *
366          *  Most insets have no interest in this capability, so the method
367          *  defaults to empty.
368          */
369         virtual void addPreview(grfx::PreviewLoader &) const {}
370
371         /** Find the PreviewLoader, add a LaTeX snippet to it and
372          *  start the loading process.
373          *
374          *  Most insets have no interest in this capability, so the method
375          *  defaults to empty.
376          */
377         virtual void generatePreview() const {}
378
379 protected:
380         ///
381         mutable int top_x;
382         ///
383         mutable bool topx_set; /* have we already drawn ourself! */
384         ///
385         mutable int top_baseline;
386         ///
387         mutable int scx;
388         ///
389         unsigned int id_;
390         ///
391         static unsigned int inset_id;
392
393 private:
394         ///
395         Inset * owner_;
396         /// the paragraph in which this inset has been inserted
397         Paragraph * par_owner_;
398         ///
399         string name_;
400         ///
401         LColor::color background_color_;
402 };
403
404
405 inline
406 bool Inset::insetAllowed(Inset * in) const
407 {
408         return insetAllowed(in->lyxCode());
409 }
410
411
412 inline
413 bool Inset::checkInsertChar(LyXFont &)
414 {
415         return false;
416 }
417
418 //  Updatable Insets. These insets can be locked and receive
419 //  directly user interaction. Currently used only for mathed.
420 //  Note that all pure methods from Inset class are pure here too.
421 //  [Alejandro 080596]
422
423 /** Extracted from Matthias notes:
424  *
425  * An inset can simple call LockInset in it's edit call and *ONLY*
426  * in it's edit call.
427  *
428  * Unlocking is either done by LyX or the inset itself with a
429  * UnlockInset-call
430  *
431  * During the lock, all button and keyboard events will be modified
432  * and send to the inset through the following inset-features. Note that
433  * Inset::insetUnlock will be called from inside UnlockInset. It is meant
434  * to contain the code for restoring the menus and things like this.
435  *
436  * If a inset wishes any redraw and/or update it just has to call
437  * updateInset(this).
438  *
439  * It's is completly irrelevant, where the inset is. UpdateInset will
440  * find it in any paragraph in any buffer.
441  * Of course the_locking_inset and the insets in the current paragraph/buffer
442  *  are checked first, so no performance problem should occur.
443  */
444 class UpdatableInset : public Inset {
445 public:
446         ///
447         UpdatableInset();
448         ///
449         UpdatableInset(UpdatableInset const & in, bool same_id = false);
450
451         /// check if the font of the char we want inserting is correct
452         /// and modify it if it is not.
453         virtual bool checkInsertChar(LyXFont &);
454         ///
455         virtual EDITABLE editable() const;
456
457         ///
458         virtual void toggleInsetCursor(BufferView *);
459         ///
460         virtual void showInsetCursor(BufferView *, bool show = true);
461         ///
462         virtual void hideInsetCursor(BufferView *);
463         ///
464         virtual void fitInsetCursor(BufferView *) const;
465         ///
466         virtual void getCursorPos(BufferView *, int &, int &) const {}
467         ///
468         virtual void insetUnlock(BufferView *);
469         ///
470         virtual void edit(BufferView *, int x, int y, mouse_button::state button);
471         ///
472         virtual void edit(BufferView *, bool front = true);
473         ///
474         virtual void draw(BufferView *, LyXFont const &,
475                           int baseline, float & x, bool cleared) const;
476         ///
477         virtual bool insertInset(BufferView *, Inset *) { return false; }
478         ///
479         virtual UpdatableInset * getLockingInset() const {
480                 return const_cast<UpdatableInset *>(this);
481         }
482         ///
483         virtual UpdatableInset * getFirstLockingInsetOfType(Inset::Code c)
484                 { return (c == lyxCode()) ? this : 0; }
485         ///
486         virtual int insetInInsetY() const { return 0; }
487         ///
488         virtual bool updateInsetInInset(BufferView *, Inset *)
489                 { return false; }
490         ///
491         virtual bool lockInsetInInset(BufferView *, UpdatableInset *)
492                 { return false; }
493         ///
494         virtual bool unlockInsetInInset(BufferView *, UpdatableInset *,
495                                         bool /*lr*/ = false)
496                 { return false; }
497         ///  An updatable inset could handle lyx editing commands
498         virtual RESULT localDispatch(FuncRequest const & cmd);
499         ///
500         bool isCursorVisible() const { return cursor_visible_; }
501         ///
502         virtual int getMaxWidth(BufferView * bv, UpdatableInset const *) const;
503         ///
504         int scroll(bool recursive = true) const {
505                 // We need this method to not clobber the real method in Inset
506                 return Inset::scroll(recursive);
507         }
508         ///
509         virtual bool showInsetDialog(BufferView *) const { return false; }
510         ///
511         virtual void nodraw(bool b) const {
512                 block_drawing_ = b;
513         }
514         ///
515         virtual bool nodraw() const {
516                 return block_drawing_;
517         }
518         ///
519         // needed for spellchecking text
520         ///
521         virtual bool allowSpellcheck() { return false; }
522         ///
523         virtual WordLangTuple const
524         selectNextWordToSpellcheck(BufferView *, float & value) const;
525         ///
526         virtual void selectSelectedWord(BufferView *) { return; }
527         ///
528         virtual void toggleSelection(BufferView *, bool /*kill_selection*/) {
529                 return;
530         }
531         ///
532         // needed for search/replace functionality
533         ///
534         virtual bool searchForward(BufferView *, string const &,
535                                    bool = true, bool = false);
536         ///
537         virtual bool searchBackward(BufferView *, string const &,
538                                     bool = true, bool = false);
539
540 protected:
541         ///
542         void toggleCursorVisible() const {
543                 cursor_visible_ = !cursor_visible_;
544         }
545         ///
546         void setCursorVisible(bool b) const {
547                 cursor_visible_ = b;
548         }
549         /// scrolls to absolute position in bufferview-workwidth * sx units
550         void scroll(BufferView *, float sx) const;
551         /// scrolls offset pixels
552         void scroll(BufferView *, int offset) const;
553
554 private:
555         ///
556         mutable bool cursor_visible_;
557         ///
558         mutable bool block_drawing_;
559 };
560
561 inline
562 bool UpdatableInset::checkInsertChar(LyXFont &)
563 {
564         return true;
565 }
566
567 /**
568  * returns true if pointer argument is valid
569  * and points to an editable inset
570  */
571 inline bool isEditableInset(Inset * i)
572 {
573         return i && i->editable();
574 }
575
576 /**
577  * returns true if pointer argument is valid
578  * and points to a highly editable inset
579  */
580 inline bool isHighlyEditableInset(Inset * i)
581 {
582         return i && i->editable() == Inset::HIGHLY_EDITABLE;
583 }
584
585 #endif