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