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