]> git.lyx.org Git - lyx.git/blob - src/lyxtext.h
Fix small bug in reading \set_color in lyxrc
[lyx.git] / src / lyxtext.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *       
7  *           Copyright 1995 Matthias Ettrich
8  *           Copyright 1995-2000 The LyX Team.
9  *
10  * ====================================================== */
11
12 #ifndef LYXTEXT_H
13 #define LYXTEXT_H
14
15 #ifdef __GNUG__
16 #pragma interface
17 #endif
18
19 #include "lyxfont.h"
20 #include "undo.h"
21 #include "lyxcursor.h"
22 #include "lyxparagraph.h"
23 #include "layout.h"
24
25 class Buffer;
26 class BufferParams;
27 class Row;
28 class BufferView;
29 class InsetText;
30
31
32 /**
33   This class holds the mapping between buffer paragraphs and screen rows.
34   */
35 class LyXText {
36 public:
37         ///
38         enum text_status {
39                 ///
40                 UNCHANGED,
41                 ///
42                 NEED_MORE_REFRESH,
43                 ///
44                 NEED_VERY_LITTLE_REFRESH,
45                 ///
46                 CHANGED_IN_DRAW
47         };
48
49         /// Constructor
50         LyXText(BufferView *);
51         LyXText(InsetText *);
52    
53         /// Destructor
54         ~LyXText();
55
56         void init(BufferView *);
57         ///
58         mutable int number_of_rows;
59         ///
60         mutable long height;
61         mutable unsigned int width;
62         /// the current font settings
63         mutable LyXFont current_font;
64         /// the current font
65         mutable LyXFont real_current_font;
66         /// first visible pixel-row is set from LyXScreen!!!
67         unsigned long first;
68         ///
69         BufferView * bv_owner;
70         ///
71         InsetText * inset_owner;
72
73         ///
74         LyXFont GetFont(Buffer const *, LyXParagraph * par,
75                         LyXParagraph::size_type pos) const;
76         ///
77         void SetCharFont(Buffer const *, LyXParagraph * par,
78                          LyXParagraph::size_type pos,
79                          LyXFont const & font);
80         /// returns a pointer to the very first LyXParagraph
81         LyXParagraph * FirstParagraph() const;
82   
83         /// what you expect when pressing <enter> at cursor position
84         void BreakParagraph(BufferView *, char keep_layout = 0);
85
86         /** set layout over selection and make a total rebreak of
87           those paragraphs
88           */
89         LyXParagraph * SetLayout(BufferView *, LyXCursor & actual_cursor,
90                                  LyXCursor & selection_start,
91                                  LyXCursor & selection_end,
92                                  LyXTextClass::size_type layout);
93         void SetLayout(BufferView *, LyXTextClass::size_type layout);
94         
95         /// used in setlayout
96         void MakeFontEntriesLayoutSpecific(Buffer const *, LyXParagraph * par);
97         
98         /** increment depth over selection and make a total rebreak of those 
99           paragraphs
100           */
101         void IncDepth(BufferView *);
102         
103         /** decrement depth over selection and make a total rebreak of those  
104           paragraphs */
105         void DecDepth(BufferView *);
106
107         /** Get the depth at current cursor position
108          */
109         int GetDepth() const { return cursor.par()->GetDepth(); }
110         
111         /** set font over selection and make a total rebreak of those
112           paragraphs.
113           toggleall defaults to false.
114           */
115         void SetFont(BufferView *, LyXFont const &, bool toggleall = false);
116         
117         /** deletes and inserts again all paragaphs between the cursor
118           and the specified par. The Cursor is needed to set the refreshing
119           parameters. 
120           This function is needed after SetLayout and SetFont etc.
121           */
122         void RedoParagraphs(BufferView *, LyXCursor const & cursor,
123                             LyXParagraph const * end_par) const;
124         ///
125         void RedoParagraph(BufferView *) const;
126         
127         ///
128         void ToggleFree(BufferView *, LyXFont const &, bool toggleall = false);
129         
130         /** recalculates the heights of all previous rows of the
131             specified paragraph.  needed, if the last characters font
132             has changed.  
133             */
134         void RedoHeightOfParagraph(BufferView *, LyXCursor const & cursor);
135         
136         /** forces the redrawing of a paragraph. Needed when manipulating a 
137             right address box
138             */ 
139         void RedoDrawingOfParagraph(BufferView *, LyXCursor const & cursor);
140         
141         /** insert a character, moves all the following breaks in the 
142           same Paragraph one to the right and make a little rebreak
143           */
144         void InsertChar(BufferView *, char c);
145         ///
146         void InsertInset(BufferView *, Inset * inset);
147    
148         /** Completes the insertion with a full rebreak.
149             Returns true if something was broken. */
150         bool FullRebreak(BufferView *);
151
152 #ifndef NEW_INSETS
153         ///
154         LyXParagraph::footnote_flag GetFootnoteFlag(int row);
155 #endif
156         ///
157         Row * need_break_row;
158         ///
159         mutable long refresh_y;
160         ///
161         int refresh_height;
162         ///
163         int refresh_width;
164         ///
165         int refresh_x;
166         ///
167         mutable Row * refresh_row;
168         ///
169         int refresh_pos;
170         
171         /** wether the screen needs a refresh,
172            starting with refresh_y
173            */
174         mutable text_status status;
175         
176         /** returns a pointer to the row near the specified y-coordinate
177           (relative to the whole text). y is set to the real beginning
178           of this row
179           */ 
180         Row * GetRowNearY(long & y) const;
181         
182         /** returns the column near the specified x-coordinate of the row 
183          x is set to the real beginning of this column
184          */ 
185         int GetColumnNearX(BufferView *, Row * row, int & x, bool & boundary) const;
186         
187         /** returns a pointer to a specified row. y is set to the beginning
188          of the row
189          */
190         Row * GetRow(LyXParagraph * par,
191                      LyXParagraph::size_type pos, long & y) const;
192
193         /** returns the height of a default row, needed  for scrollbar
194          */
195         int DefaultHeight() const;
196    
197         /** The cursor.
198           Later this variable has to be removed. There should be now internal
199           cursor in a text (and thus not in a buffer). By keeping this it is
200           (I think) impossible to have several views with the same buffer, but
201           the cursor placed at different places.
202           [later]
203           Since the LyXText now has been moved from Buffer to BufferView
204           it should not be absolutely needed to move the cursor...
205           */
206         mutable LyXCursor cursor;
207    
208         /* the selection cursor */
209         /// 
210         mutable bool selection;
211         ///
212         mutable bool mark_set;
213
214         ///
215         mutable LyXCursor sel_cursor;
216         ///
217         LyXCursor sel_start_cursor;
218         ///
219         mutable LyXCursor sel_end_cursor;
220         /// needed for the toggling
221         LyXCursor last_sel_cursor;
222         ///
223         LyXCursor toggle_cursor;
224         ///
225         LyXCursor toggle_end_cursor;
226    
227         /// need the selection cursor:
228         void SetSelection();
229         ///
230         void ClearSelection() const;
231         ///
232         string selectionAsString(Buffer const *) const;
233         
234         /// just selects the word the cursor is in
235         void SelectWord(BufferView *);
236
237         /** 'selects" the next word, where the cursor is not in 
238          and returns this word as string. THe cursor will be moved 
239          to the beginning of this word. 
240          With SelectSelectedWord can this be highlighted really
241          */ 
242         char * SelectNextWord(BufferView *, float & value);
243         ///
244         void SelectSelectedWord(BufferView *);
245         ///
246         void SetCursor(BufferView *, LyXParagraph * par,
247                        LyXParagraph::size_type pos,
248                        bool setfont = true,
249                        bool boundary = false) const;
250
251         void SetCursor(BufferView *, LyXCursor &, LyXParagraph * par,
252                        LyXParagraph::size_type pos,
253                        bool boundary = false) const;
254         ///
255         void SetCursorIntern(BufferView *, LyXParagraph * par,
256                              LyXParagraph::size_type pos,
257                              bool setfont = true,
258                              bool boundary = false) const;
259         ///
260         void SetCurrentFont(BufferView *) const;
261
262         ///
263         bool IsBoundary(Buffer const *, LyXParagraph * par,
264                         LyXParagraph::size_type pos) const;
265         ///
266         bool IsBoundary(Buffer const *, LyXParagraph * par,
267                          LyXParagraph::size_type pos,
268                          LyXFont const & font) const;
269
270         ///
271         void SetCursorFromCoordinates(BufferView *, int x, long y) const;
272         void SetCursorFromCoordinates(BufferView *, LyXCursor &,
273                                       int x, long y) const;
274         ///
275         void CursorUp(BufferView *) const;
276         ///
277         void CursorDown(BufferView *) const;
278         ///
279         void CursorLeft(BufferView *, bool internal = true) const;
280         ///
281         void CursorRight(BufferView *, bool internal = true) const;
282         ///
283         void CursorLeftIntern(BufferView *, bool internal = true) const;
284         ///
285         void CursorRightIntern(BufferView *, bool internal = true) const;
286         ///
287         void CursorLeftOneWord(BufferView *) const;
288         ///
289         void CursorRightOneWord(BufferView *) const;
290         ///
291         void CursorUpParagraph(BufferView *) const;
292         ///
293         void CursorDownParagraph(BufferView *) const;
294         ///
295         void CursorHome(BufferView *) const;
296         ///
297         void CursorEnd(BufferView *) const;
298         ///
299         void CursorTab(BufferView *) const;
300         ///
301         void CursorTop(BufferView *) const;
302         ///
303         void CursorBottom(BufferView *) const;
304         ///
305         void Delete(BufferView *);
306         ///
307         void Backspace(BufferView *);
308         ///
309         void DeleteWordForward(BufferView *);
310         ///
311         void DeleteWordBackward(BufferView *);
312         ///
313         void DeleteLineForward(BufferView *);
314         ///
315         bool SelectWordWhenUnderCursor(BufferView *);
316
317         enum TextCase {
318                 text_lowercase = 0,
319                 text_capitalization = 1,
320                 text_uppercase = 2
321         };
322         /// Change the case of the word at cursor position.
323         void ChangeWordCase(BufferView *, TextCase action);
324
325         /** returns a printed row in a pixmap. The y value is needed to
326           decide, wether it is selected text or not. This is a strange
327           solution but faster.
328          */
329         void GetVisibleRow(BufferView *, int y_offset, int x_offset,
330                            Row * row_ptr, long y, bool cleared=false);
331
332 #ifndef NEW_INSETS
333         /* footnotes: */
334         ///
335         void ToggleFootnote(BufferView *);
336         ///
337         void OpenStuff(BufferView *);
338         ///
339         void OpenFootnotes();
340         ///
341         void OpenFootnote(BufferView *);
342         ///
343         void CloseFootnotes();
344         ///
345         void CloseFootnote(BufferView *);
346
347         /** turn the selection into a new environment. If there is no
348           selection, create an empty environment
349          */ 
350         void InsertFootnoteEnvironment(BufferView *,
351                                        LyXParagraph::footnote_kind kind);
352         ///
353         void MeltFootnoteEnvironment(BufferView *);
354 #endif
355         ///
356         void CutSelection(BufferView *, bool = true);
357         ///
358         void CopySelection(BufferView *);
359         ///
360         void PasteSelection(BufferView *);
361         ///
362         void copyEnvironmentType();
363         ///
364         void pasteEnvironmentType(BufferView *);
365         ///
366         void InsertFootnote();
367         ///
368         void InsertMarginpar();
369         ///
370         void InsertFigure();
371         ///
372         void InsertTabular();
373
374         /** the DTP switches for paragraphs. LyX will store the top settings
375          always in the first physical paragraph, the bottom settings in the
376          last. When a paragraph is broken, the top settings rest, the bottom 
377          settings are given to the new one. So I can make shure, they do not
378          duplicate themself (and you cannnot make dirty things with them! )
379          */ 
380         void SetParagraph(BufferView *,
381                           bool line_top, bool line_bottom,
382                           bool pagebreak_top, bool pagebreak_bottom,
383                           VSpace const & space_top,
384                           VSpace const & space_bottom,
385                           LyXAlignment align, 
386                           string labelwidthstring,
387                           bool noindent);
388         void SetParagraphExtraOpt(BufferView *, int type,
389                                   char const * width,
390                                   char const * widthp,
391                                   int alignment, bool hfill,
392                                   bool start_minipage);
393
394         /* these things are for search and replace */
395
396         /** returns true if the specified string is at the specified
397           position
398           */
399         bool IsStringInText(LyXParagraph * par,
400                             LyXParagraph::size_type pos,
401                             char const * str) const;
402         /** sets the selection over the number of characters of string,
403           no check!!
404           */
405         void SetSelectionOverString(BufferView *, char const * str);
406
407         /** simple replacing. The font of the first selected character
408           is used
409           */
410         void ReplaceSelectionWithString(BufferView *, char const * str);
411
412         /** if the string can be found: return true and set the cursor to
413           the new position */
414         bool SearchForward(BufferView *, char const * str) const;
415         bool SearchBackward(BufferView *, char const * str) const;
416
417         /// needed to insert the selection
418         void InsertStringA(BufferView *, string const & str);
419         /// needed to insert the selection
420         void InsertStringB(BufferView *, string const & str);
421
422         /// usefull when texing from within LyX
423         bool GotoNextError(BufferView *) const;
424
425         /// just another feature :)
426         bool GotoNextNote(BufferView *) const;
427
428         /* for the greater insets */
429   
430         /// returns false if inset wasn't found
431         bool UpdateInset(BufferView *, Inset *);
432         ///
433         void CheckParagraph(BufferView *, LyXParagraph * par,
434                             LyXParagraph::size_type pos);
435         ///
436         int NumberOfCell(LyXParagraph * par,
437                          LyXParagraph::size_type pos) const;
438         /* table stuff -- begin*/
439
440         /** all table features of the text-class are put together in
441           this function. Possible values of feature are defined in table.h
442           */
443         void TableFeatures(BufferView *, int feature, string const & val) const;
444         ///
445         void TableFeatures(BufferView *, int feature) const;
446
447         /** pos points at the beginning of the next cell (if there is one)
448          */
449         int WidthOfCell(BufferView *, LyXParagraph * par,
450                         LyXParagraph::size_type & pos) const;
451         ///
452         void CheckParagraphInTable(BufferView *, LyXParagraph * par,
453                                    LyXParagraph::size_type pos);
454         ///
455         void InsertCharInTable(BufferView *, char c);
456         ///
457         void BackspaceInTable(BufferView *);
458         ///
459         bool HitInTable(BufferView *, Row * row, int x) const;
460         ///
461         bool MouseHitInTable(BufferView *, int x, long y) const;
462         /* table stuff -- end*/
463         ///
464         LyXParagraph * GetParFromID(int id);
465
466         // undo functions
467         /// returns false if no undo possible
468         bool TextUndo(BufferView *);
469         /// returns false if no redo possible
470         bool TextRedo(BufferView *);
471         /// used by TextUndo/TextRedo
472         bool TextHandleUndo(BufferView *, Undo * undo);
473         /// makes sure the next operation will be stored
474         void FinishUndo();
475         /// this is dangerous and for internal use only
476         void FreezeUndo();
477         /// this is dangerous and for internal use only
478         void UnFreezeUndo();
479         /// the flag used by FinishUndo();
480         mutable bool undo_finished;
481         /// a flag
482         bool undo_frozen;
483         ///
484         void SetUndo(Buffer *, Undo::undo_kind kind,
485                      LyXParagraph const * before,
486                      LyXParagraph const * end) const;
487         ///
488         void SetRedo(Buffer *, Undo::undo_kind kind,
489                      LyXParagraph const * before,
490                      LyXParagraph const * end);
491         ///
492         Undo * CreateUndo(Buffer *, Undo::undo_kind kind,
493                           LyXParagraph const * before,
494                           LyXParagraph const * end) const;
495         /// for external use in lyx_cb.C
496         void SetCursorParUndo(Buffer *);
497         ///
498         void RemoveTableRow(LyXCursor & cursor) const;
499         ///
500         bool IsEmptyTableCell() const;
501         ///
502         void toggleAppendix(BufferView *);
503         ///
504         int workWidth(BufferView *) const;
505         ///
506         void ComputeBidiTables(Buffer const *, Row * row) const;
507
508         /// Maps positions in the visual string to positions in logical string.
509         inline
510         LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
511                 if (bidi_start == -1)
512                         return pos;
513                 else
514                         return log2vis_list[pos-bidi_start];
515         }
516
517         /// Maps positions in the logical string to positions in visual string.
518         inline
519         LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
520                 if (bidi_start == -1)
521                         return pos;
522                 else
523                         return vis2log_list[pos-bidi_start];
524         }
525
526         inline
527         int bidi_level(LyXParagraph::size_type pos) const {
528                 if (bidi_start == -1)
529                         return 0;
530                 else
531                         return bidi_levels[pos-bidi_start];
532         }       
533
534         inline
535         bool bidi_InRange(LyXParagraph::size_type pos) const {
536                 return bidi_start == -1 ||
537                         (bidi_start <= pos && pos <= bidi_end);
538         }
539 private:
540         ///
541         void init();
542         ///
543         mutable Row * firstrow;
544         ///
545         mutable Row * lastrow;
546
547         /** Copybuffer for copy environment type
548           Asger has learned that this should be a buffer-property instead
549           Lgb has learned that 'char' is a lousy type for non-characters
550           */
551         LyXTextClass::size_type copylayouttype;
552
553         /** inserts a new row behind the specified row, increments
554          * the touched counters */
555         void InsertRow(Row * row, LyXParagraph * par,
556                        LyXParagraph::size_type pos) const;
557         /** removes the row and reset the touched counters */
558         void RemoveRow(Row * row) const;
559
560         /** remove all following rows of the paragraph of the specified row. */
561         void RemoveParagraph(Row * row) const;
562
563         /** insert the specified paragraph behind the specified row */
564         void InsertParagraph(BufferView *, LyXParagraph * par, Row * row) const;
565
566         /** appends  the implizit specified paragraph behind the specified row,
567          * start at the implizit given position */
568         void AppendParagraph(BufferView *, Row * row) const;
569    
570         ///
571         void BreakAgain(BufferView *, Row * row) const;
572         ///
573         void BreakAgainOneRow(BufferView *, Row * row);
574         /// Calculate and set the height of the row
575         void SetHeightOfRow(BufferView *, Row * row_ptr) const;
576
577         /** this calculates the specified parameters. needed when setting
578          * the cursor and when creating a visible row */ 
579         void PrepareToPrint(BufferView *, Row * row, float & x,
580                             float & fill_separator, 
581                             float & fill_hfill,
582                             float & fill_label_hfill,
583                             bool bidi = true) const;
584
585         ///
586         void DeleteEmptyParagraphMechanism(BufferView *,
587                                            LyXCursor const & old_cursor) const;
588
589         /** Updates all counters starting BEHIND the row. Changed paragraphs
590          * with a dynamic left margin will be rebroken. */ 
591         void UpdateCounters(BufferView *, Row * row) const;
592         ///
593         void SetCounter(Buffer const *, LyXParagraph * par) const;
594    
595         /*
596          * some low level functions
597          */
598         
599         ///
600         int SingleWidth(BufferView *, LyXParagraph * par,
601                         LyXParagraph::size_type pos) const;
602         ///
603         int SingleWidth(BufferView *, LyXParagraph * par,
604                         LyXParagraph::size_type pos, char c) const;
605         ///
606         void draw(BufferView *, Row const * row,
607                   LyXParagraph::size_type & pos,
608                   int offset, float & x, bool cleared);
609
610         /// get the next breakpoint in a given paragraph
611         LyXParagraph::size_type NextBreakPoint(BufferView *, Row const * row,
612                                                int width) const;
613         /// returns the minimum space a row needs on the screen in pixel
614         int Fill(BufferView *, Row * row, int workwidth) const;
615         
616         /** returns the minimum space a manual label needs on the
617           screen in pixel */ 
618         int LabelFill(BufferView *, Row const * row) const;
619
620         ///
621         LyXParagraph::size_type
622         BeginningOfMainBody(Buffer const *, LyXParagraph const * par) const;
623         
624         /** Returns the left beginning of the text.
625           This information cannot be taken from the layouts-objekt, because
626           in LaTeX the beginning of the text fits in some cases
627           (for example sections) exactly the label-width.
628           */
629         int LeftMargin(BufferView *, Row const * row) const;
630         ///
631         int RightMargin(Buffer const *, Row const * row) const;
632         ///
633         int LabelEnd (BufferView *, Row const * row) const;
634
635         /** returns the number of separators in the specified row.
636           The separator on the very last column doesnt count
637           */ 
638         int NumberOfSeparators(Buffer const *, Row const * row) const;
639
640         /** returns the number of hfills in the specified row. The
641           LyX-Hfill is a LaTeX \hfill so that the hfills at the
642           beginning and at the end were ignored. This is {\em MUCH}
643           more usefull than not to ignore!
644           */
645         int NumberOfHfills(Buffer const *, Row const * row) const;
646    
647         /// like NumberOfHfills, but only those in the manual label!
648         int NumberOfLabelHfills(Buffer const *, Row const * row) const;
649         /** returns true, if a expansion is needed. Rules are given by 
650           LaTeX
651           */
652         bool HfillExpansion(Buffer const *, Row const * row_ptr,
653                             LyXParagraph::size_type pos) const;
654
655
656         ///
657         mutable std::vector<LyXParagraph::size_type> log2vis_list;
658
659         ///
660         mutable std::vector<LyXParagraph::size_type> vis2log_list;
661
662         ///
663         mutable std::vector<LyXParagraph::size_type> bidi_levels;
664
665         ///
666         mutable LyXParagraph::size_type bidi_start;
667
668         ///
669         mutable LyXParagraph::size_type bidi_end;
670
671         ///
672         mutable bool bidi_same_direction;
673
674         ///
675         unsigned char TransformChar(unsigned char c, LyXParagraph * par,
676                                 LyXParagraph::size_type pos) const;
677
678         /** returns the paragraph position of the last character in the 
679           specified row
680           */
681         LyXParagraph::size_type RowLast(Row const * row) const;
682         ///
683         LyXParagraph::size_type RowLastPrintable(Row const * row) const;
684
685         ///
686         void charInserted();
687         ///
688         /// special owner functions
689         ///
690         LyXParagraph * OwnerParagraph() const;
691         ///
692         LyXParagraph * OwnerParagraph(LyXParagraph *) const;
693         ///
694 };
695
696 #endif