]> git.lyx.org Git - features.git/blob - src/insets/Inset.h
Whitespace cleanup
[features.git] / src / insets / Inset.h
1 // -*- C++ -*-
2 /**
3  * \file Inset.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Alejandro Aguilar Sierra
8  * \author Jürgen Vigna
9  * \author Lars Gullik Bjønnes
10  * \author Matthias Ettrich
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #ifndef INSETBASE_H
16 #define INSETBASE_H
17
18 #include "Changes.h"
19 #include "Dimension.h"
20
21 #include "support/docstream.h"
22
23 #include <boost/signal.hpp>
24
25 #include <memory>
26 #include <vector>
27
28 namespace lyx {
29
30 class Buffer;
31 class BufferParams;
32 class BufferView;
33 class CursorSlice;
34 class FuncRequest;
35 class FuncStatus;
36 class InsetMath;
37 class InsetText;
38 class LaTeXFeatures;
39 class Color_color;
40 class Cursor;
41 class Lexer;
42 class Text;
43 class MetricsInfo;
44 class Dimension;
45 class PainterInfo;
46 class OutputParams;
47 class TocList;
48
49
50 namespace graphics { class PreviewLoader; }
51
52
53 /// Common base class to all insets
54
55 // Do not add _any_ (non-static) data members as this would inflate
56 // everything storing large quantities of insets. Mathed e.g. would
57 // suffer.
58
59 class Inset : public boost::noncopyable {
60 public:
61         ///
62         typedef ptrdiff_t  difference_type;
63         /// short of anything else reasonable
64         typedef size_t     size_type;
65         /// type for cell indices
66         typedef size_t     idx_type;
67         /// type for cursor positions
68         typedef ptrdiff_t  pos_type;
69         /// type for row numbers
70         typedef size_t     row_type;
71         /// type for column numbers
72         typedef size_t     col_type;
73
74         /// virtual base class destructor
75         virtual ~Inset() { destroyed();}
76         /// replicate ourselves
77         std::auto_ptr<Inset> clone() const;
78
79         /// identification as math inset
80         virtual InsetMath * asInsetMath() { return 0; }
81         /// true for 'math' math inset, but not for e.g. mbox
82         virtual bool inMathed() const { return false; }
83
84         /// the real dispatcher
85         void dispatch(Cursor & cur, FuncRequest & cmd);
86         /**
87          * \returns true if this function made a definitive decision on
88          * whether the inset wants to handle the request \p cmd or not.
89          * The result of this decision is put into \p status.
90          *
91          * Every request that is enabled in this method needs to be handled
92          * in doDispatch(). Normally we have a 1:1 relationship between the
93          * requests handled in getStatus() and doDispatch(), but there are
94          * some exceptions:
95          * - A request that is disabled in getStatus() does not need to
96          *   appear in doDispatch(). It is guaranteed that doDispatch()
97          *   is never called with this request.
98          * - A few requests are en- or disabled in Inset::getStatus().
99          *   These need to be handled in the doDispatch() methods of the
100          *   derived insets, since Inset::doDispatch() has not enough
101          *   information to handle them.
102          * - LFUN_MOUSE_* need not to be handled in getStatus(), because these
103          *   are dispatched directly
104          */
105         virtual bool getStatus(Cursor & cur, FuncRequest const & cmd,
106                 FuncStatus & status) const;
107
108         /// cursor enters
109         virtual void edit(Cursor & cur, bool left);
110         /// cursor enters
111         virtual Inset * editXY(Cursor & cur, int x, int y);
112
113         /// compute the size of the object returned in dim
114         /// \retval true if metrics changed.
115         virtual bool metrics(MetricsInfo & mi, Dimension & dim) const = 0;
116         /// draw inset and update (xo, yo)-cache
117         virtual void draw(PainterInfo & pi, int x, int y) const = 0;
118         /// draw inset selection if necessary
119         virtual void drawSelection(PainterInfo &, int, int) const {}
120         ///
121         virtual bool editing(BufferView * bv) const;
122         ///
123         virtual bool showInsetDialog(BufferView *) const { return false; }
124
125         /// draw inset decoration if necessary.
126         /// This can use \c drawMarkers() for example.
127         virtual void drawDecoration(PainterInfo &, int, int) const {}
128         /// draw four angular markers
129         void drawMarkers(PainterInfo & pi, int x, int y) const;
130         /// draw two angular markers
131         void drawMarkers2(PainterInfo & pi, int x, int y) const;
132         /// add space for markers
133         void metricsMarkers(Dimension & dim, int framesize = 1) const;
134         /// add space for markers
135         void metricsMarkers2(Dimension & dim, int framesize = 1) const;
136         /// last drawn position for 'important' insets
137         int xo(BufferView const & bv) const;
138         /// last drawn position for 'important' insets
139         int yo(BufferView const & bv) const;
140         /// set x/y drawing position cache if available
141         virtual void setPosCache(PainterInfo const &, int, int) const;
142         /// do we cover screen position x/y?
143         virtual bool covers(BufferView const & bv, int x, int y) const;
144         /// get the screen positions of the cursor (see note in Cursor.cpp)
145         virtual void cursorPos(BufferView const & bv,
146                 CursorSlice const & sl, bool boundary, int & x, int & y) const;
147
148         /// is this an inset that can be moved into?
149         virtual bool isActive() const { return nargs() > 0; }
150         /// Where should we go when we press the up or down cursor key?
151         virtual bool idxUpDown(Cursor & cur, bool up) const;
152         /// Move one cell to the left
153         virtual bool idxLeft(Cursor &) const { return false; }
154         /// Move one cell to the right
155         virtual bool idxRight(Cursor &) const { return false; }
156
157         /// Move one physical cell up
158         virtual bool idxNext(Cursor &) const { return false; }
159         /// Move one physical cell down
160         virtual bool idxPrev(Cursor &) const { return false; }
161
162         /// Target pos when we enter the inset from the left by pressing "Right"
163         virtual bool idxFirst(Cursor &) const { return false; }
164         /// Target pos when we enter the inset from the right by pressing "Left"
165         virtual bool idxLast(Cursor &) const { return false; }
166
167         /// Delete a cell and move cursor
168         virtual bool idxDelete(idx_type &) { return false; }
169         /// pulls cell after pressing erase
170         virtual void idxGlue(idx_type) {}
171         /// returns list of cell indices that are "between" from and to for
172         /// selection purposes
173         virtual bool idxBetween(idx_type idx, idx_type from, idx_type to) const;
174
175         /// to which column belongs a cell with a given index?
176         virtual col_type col(idx_type) const { return 0; }
177         /// to which row belongs a cell with a given index?
178         virtual row_type row(idx_type) const { return 0; }
179         /// cell idex corresponding to row and column;
180         virtual idx_type index(row_type row, col_type col) const;
181         /// any additional x-offset when drawing a cell?
182         virtual int cellXOffset(idx_type) const { return 0; }
183         /// any additional y-offset when drawing a cell?
184         virtual int cellYOffset(idx_type) const { return 0; }
185         /// number of embedded cells
186         virtual size_t nargs() const { return 0; }
187         /// number of rows in gridlike structures
188         virtual size_t nrows() const { return 0; }
189         /// number of columns in gridlike structures
190         virtual size_t ncols() const { return 0; }
191         /// is called when the cursor leaves this inset
192         //  returns true if cursor is now invalid.
193         virtual bool notifyCursorLeaves(Cursor &) { return false; }
194         /// is called when the mouse enter or leave this inset
195         /// return true if this inset needs repaint
196         virtual bool setMouseHover(bool) { return false; }
197
198         /// request "external features"
199         virtual void validate(LaTeXFeatures &) const {}
200         /// Appends \c list with all labels found within this inset.
201         virtual void getLabelList(Buffer const &,
202                                   std::vector<docstring> & /* list */) const {}
203
204         /// describe content if cursor inside
205         virtual void infoize(odocstream &) const {}
206         /// describe content if cursor behind
207         virtual void infoize2(odocstream &) const {}
208
209         enum {
210                 PLAINTEXT_NEWLINE = 10000
211         };
212
213         /// plain text output in ucs4 encoding
214         /// return the number of characters; in case of multiple lines of
215         /// output, add PLAINTEXT_NEWLINE to the number of chars in the last line
216         virtual int plaintext(Buffer const &, odocstream &,
217                               OutputParams const &) const = 0;
218         /// docbook output
219         virtual int docbook(Buffer const &, odocstream & os,
220                             OutputParams const &) const;
221         /// the string that is passed to the TOC
222         virtual void textString(Buffer const &, odocstream &) const {}
223
224         /** This enum indicates by which means the inset can be modified:
225         - NOT_EDITABLE: the inset's content cannot be modified at all
226           (e.g. printindex, insetspecialchar)
227         - IS_EDITABLE: content can be edited via dialog (e.g. bibtex, index, url)
228         - HIGHLY_EDITABLE: content can be edited on screen (normally means that
229           insettext is contained, e.g. collapsables, tabular) */
230         // FIXME: This has not yet been fully implemented to math insets
231         enum EDITABLE {
232                 ///
233                 NOT_EDITABLE = 0,
234                 ///
235                 IS_EDITABLE,
236                 ///
237                 HIGHLY_EDITABLE
238         };
239         /// what appears in the minibuffer when opening
240         virtual docstring const editMessage() const;
241         ///
242         virtual EDITABLE editable() const;
243         /// can we go further down on mouse click?
244         virtual bool descendable() const { return false; }
245         /// does this contain text that can be change track marked in DVI?
246         virtual bool canTrackChanges() const { return false; }
247         /// is this inset based on the TextInset class?
248         virtual InsetText const * asTextInset() const { return 0; }
249         /// return true if the inset should be removed automatically
250         virtual bool autoDelete() const;
251
252         /** This is not quite the correct place for this enum. I think
253             the correct would be to let each subclass of Inset declare
254             its own enum code. Actually the notion of an Inset::Code
255             should be avoided, but I am not sure how this could be done
256             in a cleaner way. */
257         enum Code {
258                 ///
259                 NO_CODE, // 0
260                 ///
261                 TOC_CODE,  // do these insets really need a code? (ale)
262                 ///
263                 QUOTE_CODE,
264                 ///
265                 MARK_CODE,
266                 ///
267                 REF_CODE,
268                 ///
269                 URL_CODE, // 5
270                 ///
271                 HTMLURL_CODE,
272                 ///
273                 SEPARATOR_CODE,
274                 ///
275                 ENDING_CODE,
276                 ///
277                 LABEL_CODE,
278                 ///
279                 NOTE_CODE, // 10
280                 ///
281                 ACCENT_CODE,
282                 ///
283                 MATH_CODE,
284                 ///
285                 INDEX_CODE,
286                 ///
287                 INCLUDE_CODE,
288                 ///
289                 GRAPHICS_CODE, // 15
290                 ///
291                 BIBITEM_CODE,
292                 ///
293                 BIBTEX_CODE,
294                 ///
295                 TEXT_CODE,
296                 ///
297                 ERT_CODE,
298                 ///
299                 FOOT_CODE, // 20
300                 ///
301                 MARGIN_CODE,
302                 ///
303                 FLOAT_CODE,
304                 ///
305                 WRAP_CODE,
306                 ///
307                 SPACE_CODE, // 25
308                 ///
309                 SPECIALCHAR_CODE,
310                 ///
311                 TABULAR_CODE,
312                 ///
313                 EXTERNAL_CODE,
314 #if 0
315                 ///
316                 THEOREM_CODE,
317 #endif
318                 ///
319                 CAPTION_CODE,
320                 ///
321                 MATHMACRO_CODE, // 30
322                 ///
323                 CITE_CODE,
324                 ///
325                 FLOAT_LIST_CODE,
326                 ///
327                 INDEX_PRINT_CODE,
328                 ///
329                 OPTARG_CODE, // 35
330                 ///
331                 ENVIRONMENT_CODE,
332                 ///
333                 HFILL_CODE,
334                 ///
335                 NEWLINE_CODE,
336                 ///
337                 LINE_CODE,
338                 ///
339                 BRANCH_CODE, // 40
340                 ///
341                 BOX_CODE,
342                 ///
343                 CHARSTYLE_CODE,
344                 ///
345                 VSPACE_CODE,
346                 ///
347                 MATHMACROARG_CODE,
348                 ///
349                 NOMENCL_CODE, // 45
350                 ///
351                 NOMENCL_PRINT_CODE,
352                 ///
353                 PAGEBREAK_CODE,
354                 ///
355                 LISTINGS_CODE
356         };
357
358         /** returns the Code corresponding to the \c name.
359          *  Eg, translate("branch") == BRANCH_CODE
360          */
361         static Code translate(std::string const & name);
362
363         /// returns true if the inset can hold an inset of given type
364         virtual bool insetAllowed(Code) const { return false; }
365         /// if this inset has paragraphs should they be output all as default
366         /// paragraphs with the default layout of the text class?
367         virtual bool forceDefaultParagraphs(idx_type) const { return false; }
368         /// Is the width forced to some value?
369         virtual bool hasFixedWidth() const { return false; }
370
371         ///
372         virtual docstring name() const { return from_ascii("unknown"); }
373         /// used to toggle insets
374         /// is the inset open?
375         /// should this inset be handled like a normal charater
376         virtual bool isChar() const { return false; }
377         /// is this equivalent to a letter?
378         virtual bool isLetter() const { return false; }
379         /// is this equivalent to a space (which is BTW different from
380         /// a line separator)?
381         virtual bool isSpace() const { return false; }
382
383         enum DisplayType {
384                 Inline = 0,
385                 AlignLeft,
386                 AlignCenter,
387                 AlignRight
388         };
389
390         /// should we have a non-filled line before this inset?
391         virtual DisplayType display() const { return Inline; }
392         /// should we break lines after this inset?
393         virtual bool isLineSeparator() const { return false; }
394         /// should paragraph indendation be ommitted in any case?
395         virtual bool neverIndent(Buffer const &) const { return false; }
396         /// dumps content to lyxerr
397         virtual void dump() const;
398         /// write inset in .lyx format
399         virtual void write(Buffer const &, std::ostream &) const {}
400         /// read inset in .lyx format
401         virtual void read(Buffer const &, Lexer &) {}
402         /** Export the inset to LaTeX.
403          *  Don't use a temporary stringstream if the final output is
404          *  supposed to go to a file.
405          *  \sa Buffer::writeLaTeXSource for the reason.
406          *  \return the number of rows (\n's) of generated LaTeX code.
407          */
408         virtual int latex(Buffer const &, odocstream &,
409                           OutputParams const &) const { return 0; }
410         /// returns true to override begin and end inset in file
411         virtual bool directWrite() const;
412         ///
413         virtual bool allowSpellCheck() const { return false; }
414
415         /// if this insets owns text cells (e.g. InsetText) return cell num
416         virtual Text * getText(int /*num*/) const { return 0; }
417
418         /** Adds a LaTeX snippet to the Preview Loader for transformation
419          *  into a bitmap image. Does not start the laoding process.
420          *
421          *  Most insets have no interest in this capability, so the method
422          *  defaults to empty.
423          */
424         virtual void addPreview(graphics::PreviewLoader &) const {}
425         /// Add an entry to the TocList
426         virtual void addToToc(TocList &, Buffer const &) const {}
427
428 public:
429         /// returns LyX code associated with the inset. Used for TOC, ...)
430         virtual Code lyxCode() const { return NO_CODE; }
431
432         /// -1: text mode, 1: math mode, 0 undecided
433         enum mode_type {UNDECIDED_MODE, TEXT_MODE, MATH_MODE};
434         /// return text or mathmode if that is possible to determine
435         virtual mode_type currentMode() const { return UNDECIDED_MODE; }
436         /// returns whether this inset is allowed in other insets of given mode
437         virtual bool allowedIn(mode_type) const { return true; }
438         /**
439          * Is this inset allowed within a font change?
440          *
441          * FIXME: noFontChange means currently that the font change is closed
442          * in LaTeX before the inset, and that the contents of the inset
443          * will be in default font. This should be changed so that the inset
444          * changes the font again.
445          */
446         virtual bool noFontChange() const { return false; }
447
448         /// set the change for the entire inset
449         virtual void setChange(Change const &) {}
450         /// accept the changes within the inset
451         virtual void acceptChanges(BufferParams const &) {};
452         /// reject the changes within the inset
453         virtual void rejectChanges(BufferParams const &) {};
454
455         /// inset width.
456         int width() const { return dim_.wid; }
457         /// inset ascent.
458         int ascent() const { return dim_.asc; }
459         /// inset descent.
460         int descent() const { return dim_.des; }
461         ///
462         int scroll() const { return 0; }
463         ///
464         void setBackgroundColor(Color_color);
465         ///
466         Color_color backgroundColor() const;
467         ///
468         enum CollapseStatus {
469                 Collapsed,
470                 Inlined,
471                 Open
472         };
473         ///
474         virtual void setStatus(Cursor &, CollapseStatus) {}
475         //
476         enum { TEXT_TO_INSET_OFFSET = 4 };
477
478         /// This signal is emitted when the inset is destroyed.
479         boost::signal<void()> destroyed;
480
481 protected:
482         Inset();
483         Inset(Inset const & i);
484         ///
485         Inset & operator=(Inset const &);
486         /** The real dispatcher.
487          *  Gets normally called from Cursor::dispatch(). Cursor::dispatch()
488          *  assumes the common case of 'LFUN handled, need update'.
489          *  This has to be overriden by calling Cursor::undispatched() or
490          *  Cursor::noUpdate() if appropriate.
491          *  If you need to call the dispatch method of some inset directly
492          *  you may have to explicitly request an update at that place. Don't
493          *  do it in doDispatch(), since that causes nested updates when
494          *  called from Cursor::dispatch(), and these can lead to crashes.
495          *  \sa getStatus
496          */
497         virtual void doDispatch(Cursor & cur, FuncRequest & cmd);
498
499         /// Cached dimensions of the inset.
500         mutable Dimension dim_;
501 private:
502         virtual std::auto_ptr<Inset> doClone() const = 0;
503         /** We store the Color::color value as an int to get Color.h out
504          *  of the header file.
505          */
506         int background_color_;
507 };
508
509
510 /**
511  * returns true if pointer argument is valid
512  * and points to an editable inset
513  */
514 bool isEditableInset(Inset const * inset);
515
516
517 /**
518  * returns true if pointer argument is valid
519  * and points to a highly editable inset
520  */
521 bool isHighlyEditableInset(Inset const * inset);
522
523 /** \c Inset_code is a wrapper for Inset::Code.
524  *  It can be forward-declared and passed as a function argument without
525  *  having to expose Inset.h.
526  */
527
528 class Inset_code {
529         Inset::Code val_;
530 public:
531         Inset_code(Inset::Code val) : val_(val) {}
532         operator Inset::Code() const { return val_; }
533 };
534
535
536
537 } // namespace lyx
538
539 #endif