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