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