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