]> git.lyx.org Git - features.git/blob - src/lyxtext.h
some new (not extensive) changes, some fixes, will probably reverto to .la libs later...
[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           [later]
186           Since the LyXText now has been moved from Buffer to BufferView
187           it should not be absolutely needed to move the cursor...
188           */
189         LyXCursor cursor;
190    
191         /* the selection cursor */
192         /// 
193         bool selection;
194         ///
195         bool mark_set;
196
197         ///
198         LyXCursor sel_cursor;
199         ///
200         LyXCursor sel_start_cursor;
201         ///
202         LyXCursor sel_end_cursor;
203         /// needed for the toggling
204         LyXCursor last_sel_cursor;
205         ///
206         LyXCursor toggle_cursor;
207         ///
208         LyXCursor toggle_end_cursor;
209    
210         /// need the selection cursor:
211         void SetSelection();
212         ///
213         void ClearSelection();
214
215         /// just selects the word the cursor is in
216         void SelectWord();
217
218         /** 'selects" the next word, where the cursor is not in 
219          and returns this word as string. THe cursor will be moved 
220          to the beginning of this word. 
221          With SelectSelectedWord can this be highlighted really
222          */ 
223         char * SelectNextWord(float & value);
224         ///
225         void SelectSelectedWord();
226         ///
227         void SetCursor(LyXParagraph * par,
228                        LyXParagraph::size_type pos);
229         ///
230         void SetCursorIntern(LyXParagraph * par,
231                              LyXParagraph::size_type pos);
232         ///
233         void SetCursorFromCoordinates(int x, long y);
234         ///
235         void CursorUp();
236         ///
237         void CursorDown();
238         ///
239         void CursorLeft();
240         ///
241         void CursorRight();
242         ///
243         void CursorLeftOneWord();
244         ///
245         void CursorRightOneWord();
246         ///
247         void CursorUpParagraph();
248         ///
249         void CursorDownParagraph();
250         ///
251         void CursorHome();
252         ///
253         void CursorEnd();
254         ///
255         void CursorTab();
256         ///
257         void CursorTop();
258         ///
259         void CursorBottom();
260         ///
261         void Delete();
262         ///
263         void Backspace();
264         ///
265         void DeleteWordForward();
266         ///
267         void DeleteWordBackward();
268         ///
269         void DeleteLineForward();
270         ///
271         int SelectWordWhenUnderCursor();
272
273         enum TextCase {
274                 text_lowercase = 0,
275                 text_capitalization = 1,
276                 text_uppercase = 2
277         };
278         /// Change the case of the word at cursor position.
279         void ChangeWordCase(TextCase action);
280
281         /** returns a printed row in a pixmap. The y value is needed to
282           decide, wether it is selected text or not. This is a strange
283           solution but faster.
284          */ 
285         void GetVisibleRow(LyXScreen & scr, int offset, 
286                            Row * row_ptr, long y);
287                                            
288         /* footnotes: */
289         ///
290         void ToggleFootnote();
291         ///
292         void OpenStuff();
293         ///
294         void OpenFootnotes();
295         ///
296         void OpenFootnote();
297         ///
298         void CloseFootnotes();
299         ///
300         void CloseFootnote();
301
302         /** turn the selection into a new environment. If there is no
303           selection, create an empty environment
304          */ 
305         void InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind);
306         ///
307         void MeltFootnoteEnvironment();
308         ///
309         void CutSelection(bool = true);
310         ///
311         void CopySelection();
312         ///
313         void PasteSelection();
314         ///
315         void copyEnvironmentType();
316         ///
317         void pasteEnvironmentType();
318         ///
319         void InsertFootnote();
320         ///
321         void InsertMarginpar();
322         ///
323         void InsertFigure();
324         ///
325         void InsertTabular();
326
327         /** the DTP switches for paragraphs. LyX will store the top settings
328          always in the first physical paragraph, the bottom settings in the
329          last. When a paragraph is broken, the top settings rest, the bottom 
330          settings are given to the new one. So I can make shure, they do not
331          duplicate themself (and you cannnot make dirty things with them! )
332          */ 
333         void SetParagraph(bool line_top, bool line_bottom,
334                           bool pagebreak_top, bool pagebreak_bottom,
335                           VSpace space_top, VSpace space_bottom,
336                           LyXAlignment align, 
337                           string labelwidthstring,
338                           bool noindent);
339         void SetParagraphExtraOpt(int type,
340                                   char const * width,
341                                   char const * widthp,
342                                   int alignment, bool hfill,
343                                   bool start_minipage);
344
345         /* these things are for search and replace */
346
347         /** returns true if the specified string is at the specified
348           position
349           */
350         bool IsStringInText(LyXParagraph * par,
351                             LyXParagraph::size_type pos,
352                             char const * str);
353         /** sets the selection over the number of characters of string,
354           no check!!
355           */
356         void SetSelectionOverString(char const * str);
357
358         /** simple replacing. The font of the first selected character
359           is used
360           */
361         void ReplaceSelectionWithString(char const * string);
362
363         /** if the string can be found: return true and set the cursor to
364           the new position */
365         bool SearchForward(char const * string);
366         bool SearchBackward(char const * string);
367
368         /// needed to insert the selection
369         void InsertStringA(LyXParagraph::TextContainer const & text);
370         /// needed to insert the selection
371         void InsertStringB(LyXParagraph::TextContainer const & text);
372         /// needed to insert the selection
373         void InsertStringA(char const * string);
374         /// needed to insert the selection
375         void InsertStringB(char const * string);
376
377         /// usefull when texing from within LyX
378         bool GotoNextError();
379
380         /// just another feature :)
381         bool GotoNextNote();
382
383         /** needed to switch between different classes this works
384           for a list of paragraphs beginning with the specified par 
385           return value is the number of wrong conversions
386           */ 
387         int SwitchLayoutsBetweenClasses(char class1, char class2,
388                                         LyXParagraph * par);
389
390         /* for the greater insets */
391   
392         /// returns 0 if inset wasn't found
393         int UpdateInset(Inset * inset);
394         ///
395         void CheckParagraph(LyXParagraph * par,
396                             LyXParagraph::size_type pos);
397         ///
398         int NumberOfCell(LyXParagraph * par,
399                          LyXParagraph::size_type pos);
400         /* table stuff -- begin*/
401
402         /** all table features of the text-class are put together in
403           this function. Possible values of feature are defined in table.h
404           */
405         void TableFeatures(int feature, string val);
406         ///
407         void TableFeatures(int feature);
408
409         /** pos points at the beginning of the next cell (if there is one)
410          */
411         int WidthOfCell(LyXParagraph * par, LyXParagraph::size_type & pos);
412         ///
413         void CheckParagraphInTable(LyXParagraph * par,
414                                    LyXParagraph::size_type pos);
415         ///
416         void InsertCharInTable(char c);
417         ///
418         void BackspaceInTable();
419         ///
420         bool HitInTable(Row * row, int x);
421         ///
422         bool MouseHitInTable(int x, long y);
423         /* table stuff -- end*/
424         ///
425         LyXParagraph * GetParFromID(int id);
426
427         // undo functions
428         /// returns false if no undo possible
429         bool  TextUndo();
430         /// returns false if no redo possible
431         bool  TextRedo();
432         /// used by TextUndo/TextRedo
433         bool TextHandleUndo(Undo * undo);
434         /// makes sure the next operation will be stored
435         void FinishUndo();
436         /// this is dangerous and for internal use only
437         void FreezeUndo();
438         /// this is dangerous and for internal use only
439         void UnFreezeUndo();
440         /// the flag used by FinishUndo();
441         bool undo_finished;
442         /// a flag
443         bool undo_frozen;
444         ///
445         void SetUndo(Undo::undo_kind kind, LyXParagraph * before,
446                      LyXParagraph * end);
447         ///
448         void SetRedo(Undo::undo_kind kind, LyXParagraph * before,
449                      LyXParagraph * end);
450         ///
451         Undo * CreateUndo(Undo::undo_kind kind, LyXParagraph * before,
452                           LyXParagraph * end);
453         /// for external use in lyx_cb.C
454         void SetCursorParUndo();
455         ///
456         void CursorLeftIntern();
457         ///
458         void CursorRightIntern();
459         ///
460         void RemoveTableRow(LyXCursor * cursor);
461         ///
462         bool IsEmptyTableRow(LyXCursor * cursor) const;
463         ///
464         bool IsEmptyTableCell() const;
465         ///
466         void toggleAppendix();
467         ///
468         unsigned short paperWidth() const { return paperwidth; }
469
470 private:
471         /// width of the paper
472         unsigned short  paperwidth;
473
474         ///
475         Row * firstrow;
476         ///
477         Row * lastrow;
478
479         /** Copybuffer for copy environment type
480           Asger has learned that this should be a buffer-property instead
481           Lgb has learned that 'char' is a lousy type for non-characters
482           */
483         char copylayouttype;
484
485         /// the currentrow is needed to access rows faster*/ 
486         Row * currentrow;               /* pointer to the current row  */
487         /// position in the text 
488         long  currentrow_y;
489    
490         /** inserts a new row behind the specified row, increments
491          * the touched counters */
492         void InsertRow(Row * row, LyXParagraph * par,
493                        LyXParagraph::size_type pos );
494         /** removes the row and reset the touched counters */
495         void RemoveRow(Row * row);
496
497         /** remove all following rows of the paragraph of the specified row. */
498         void RemoveParagraph(Row * row);
499
500         /** insert the specified paragraph behind the specified row */
501         void InsertParagraph(LyXParagraph * par, Row * row);
502
503         /** appends  the implizit specified paragraph behind the specified row,
504          * start at the implizit given position */
505         void AppendParagraph(Row * row);
506    
507         ///
508         void BreakAgain(Row * row);
509         ///
510         void BreakAgainOneRow(Row * row);
511         ///
512         void SetHeightOfRow(Row * row_ptr); /* calculate and set the height 
513                                             * of the row */
514
515         /** this calculates the specified parameters. needed when setting
516          * the cursor and when creating a visible row */ 
517         void PrepareToPrint(Row * row, float & x, float & fill_separator, 
518                             float & fill_hfill, float & fill_label_hfill);
519         ///
520         void DeleteEmptyParagraphMechanism(LyXCursor old_cursor);
521
522         /** Updates all counters starting BEHIND the row. Changed paragraphs
523          * with a dynamic left margin will be rebroken. */ 
524         void UpdateCounters(Row * row);
525         ///
526         void SetCounter(LyXParagraph * par);
527    
528         /*
529          * some low level functions
530          */
531         
532         ///
533         int SingleWidth(LyXParagraph * par,
534                         LyXParagraph::size_type pos);
535         ///
536         int SingleWidth(LyXParagraph * par,
537                         LyXParagraph::size_type pos, char c);
538         ///
539         void Draw(Row * row, LyXParagraph::size_type & pos,
540                   LyXScreen & scr,
541                   int offset, float & x);
542         /// get the next breakpoint in a given paragraph
543         LyXParagraph::size_type NextBreakPoint(Row * row,
544                                                int width);
545         /// returns the minimum space a row needs on the screen in pixel
546         int Fill(Row * row, int paperwidth);
547         
548         /** returns the minimum space a manual label needs on the
549           screen in pixel */ 
550         int LabelFill(Row * row);
551
552         ///
553         LyXParagraph::size_type BeginningOfMainBody(LyXParagraph * par) const;
554         /** Returns the left beginning of the text.
555           This information cannot be taken from the layouts-objekt, because
556           in LaTeX the beginning of the text fits in some cases
557           (for example sections) exactly the label-width.
558           */
559         int LeftMargin(Row * row);
560         ///
561         int RightMargin(Row * row);
562         ///
563         int LabelEnd (Row * row);
564
565         /** returns the number of separators in the specified row.
566           The separator on the very last column doesnt count
567           */ 
568         int NumberOfSeparators(Row * row);
569
570         /** returns the number of hfills in the specified row. The
571           LyX-Hfill is a LaTeX \hfill so that the hfills at the
572           beginning and at the end were ignored. This is {\em MUCH}
573           more usefull than not to ignore!
574           */
575         int NumberOfHfills(Row * row);
576    
577         /// like NumberOfHfills, but only those in the manual label!
578         int NumberOfLabelHfills(Row * row);
579
580         /** returns true, if a expansion is needed. Rules are given by 
581           LaTeX
582           */
583         bool HfillExpansion(Row * row_ptr,
584                             LyXParagraph::size_type pos);
585         /** returns the paragraph position of the last character in the 
586           specified row
587           */
588         LyXParagraph::size_type RowLast(Row * row);
589         ///
590         void charInserted();
591 };
592
593 #endif