]> git.lyx.org Git - lyx.git/blob - src/lyxtext.h
748fb3465f6e590905f24cd34c57d9f64f2a36b6
[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 "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         void GetVisibleRow(int offset, 
294                            Row * row_ptr, long y);
295                                            
296         /* footnotes: */
297         ///
298         void ToggleFootnote();
299         ///
300         void OpenStuff();
301         ///
302         void OpenFootnotes();
303         ///
304         void OpenFootnote();
305         ///
306         void CloseFootnotes();
307         ///
308         void CloseFootnote();
309
310         /** turn the selection into a new environment. If there is no
311           selection, create an empty environment
312          */ 
313         void InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind);
314         ///
315         void MeltFootnoteEnvironment();
316         ///
317         void CutSelection(bool = true);
318         ///
319         void CopySelection();
320         ///
321         void PasteSelection();
322         ///
323         void copyEnvironmentType();
324         ///
325         void pasteEnvironmentType();
326         ///
327         void InsertFootnote();
328         ///
329         void InsertMarginpar();
330         ///
331         void InsertFigure();
332         ///
333         void InsertTabular();
334
335         /** the DTP switches for paragraphs. LyX will store the top settings
336          always in the first physical paragraph, the bottom settings in the
337          last. When a paragraph is broken, the top settings rest, the bottom 
338          settings are given to the new one. So I can make shure, they do not
339          duplicate themself (and you cannnot make dirty things with them! )
340          */ 
341         void SetParagraph(bool line_top, bool line_bottom,
342                           bool pagebreak_top, bool pagebreak_bottom,
343                           VSpace const & space_top,
344                           VSpace const & space_bottom,
345                           LyXAlignment align, 
346                           string labelwidthstring,
347                           bool noindent);
348         void SetParagraphExtraOpt(int type,
349                                   char const * width,
350                                   char const * widthp,
351                                   int alignment, bool hfill,
352                                   bool start_minipage);
353
354         /* these things are for search and replace */
355
356         /** returns true if the specified string is at the specified
357           position
358           */
359         bool IsStringInText(LyXParagraph * par,
360                             LyXParagraph::size_type pos,
361                             char const * str) const;
362         /** sets the selection over the number of characters of string,
363           no check!!
364           */
365         void SetSelectionOverString(char const * str);
366
367         /** simple replacing. The font of the first selected character
368           is used
369           */
370         void ReplaceSelectionWithString(char const * str);
371
372         /** if the string can be found: return true and set the cursor to
373           the new position */
374         bool SearchForward(char const * str) const;
375         bool SearchBackward(char const * str) const;
376
377         /// needed to insert the selection
378         void InsertStringA(LyXParagraph::TextContainer const & text);
379         /// needed to insert the selection
380         void InsertStringB(LyXParagraph::TextContainer const & text);
381         /// needed to insert the selection
382         void InsertStringA(char const * str);
383         /// needed to insert the selection
384         void InsertStringB(char const * str);
385
386         /// usefull when texing from within LyX
387         bool GotoNextError() const;
388
389         /// just another feature :)
390         bool GotoNextNote() const;
391
392         /** needed to switch between different classes this works
393           for a list of paragraphs beginning with the specified par 
394           return value is the number of wrong conversions
395           */ 
396         int SwitchLayoutsBetweenClasses(char class1, char class2,
397                                         LyXParagraph * par);
398
399         /* for the greater insets */
400   
401         /// returns 0 if inset wasn't found
402         int UpdateInset(Inset * inset);
403         ///
404         void CheckParagraph(LyXParagraph * par,
405                             LyXParagraph::size_type pos);
406         ///
407         int NumberOfCell(LyXParagraph * par,
408                          LyXParagraph::size_type pos) const;
409         /* table stuff -- begin*/
410
411         /** all table features of the text-class are put together in
412           this function. Possible values of feature are defined in table.h
413           */
414         void TableFeatures(int feature, string const & val) const;
415         ///
416         void TableFeatures(int feature) const;
417
418         /** pos points at the beginning of the next cell (if there is one)
419          */
420         int WidthOfCell(LyXParagraph * par,
421                         LyXParagraph::size_type & pos) const;
422         ///
423         void CheckParagraphInTable(LyXParagraph * par,
424                                    LyXParagraph::size_type pos);
425         ///
426         void InsertCharInTable(char c);
427         ///
428         void BackspaceInTable();
429         ///
430         bool HitInTable(Row * row, int x) const;
431         ///
432         bool MouseHitInTable(int x, long y) const;
433         /* table stuff -- end*/
434         ///
435         LyXParagraph * GetParFromID(int id);
436
437         // undo functions
438         /// returns false if no undo possible
439         bool TextUndo();
440         /// returns false if no redo possible
441         bool TextRedo();
442         /// used by TextUndo/TextRedo
443         bool TextHandleUndo(Undo * undo);
444         /// makes sure the next operation will be stored
445         void FinishUndo();
446         /// this is dangerous and for internal use only
447         void FreezeUndo();
448         /// this is dangerous and for internal use only
449         void UnFreezeUndo();
450         /// the flag used by FinishUndo();
451         mutable bool undo_finished;
452         /// a flag
453         bool undo_frozen;
454         ///
455         void SetUndo(Undo::undo_kind kind,
456                      LyXParagraph const * before,
457                      LyXParagraph const * end) const;
458         ///
459         void SetRedo(Undo::undo_kind kind,
460                      LyXParagraph const * before,
461                      LyXParagraph const * end);
462         ///
463         Undo * CreateUndo(Undo::undo_kind kind,
464                           LyXParagraph const * before,
465                           LyXParagraph const * end) const;
466         /// for external use in lyx_cb.C
467         void SetCursorParUndo();
468         ///
469         void CursorLeftIntern() const;
470         ///
471         void CursorRightIntern() const;
472         ///
473         void RemoveTableRow(LyXCursor * cursor) const;
474         ///
475         bool IsEmptyTableCell() const;
476         ///
477         void toggleAppendix();
478         ///
479         unsigned short paperWidth() const { return paperwidth; }
480 private:
481         ///
482         BufferView * owner_;
483         
484         /// width of the paper
485         unsigned short  paperwidth;
486
487         ///
488         mutable Row * firstrow;
489         ///
490         mutable Row * lastrow;
491
492         /** Copybuffer for copy environment type
493           Asger has learned that this should be a buffer-property instead
494           Lgb has learned that 'char' is a lousy type for non-characters
495           */
496         char copylayouttype;
497
498         /// the currentrow is needed to access rows faster*/ 
499         mutable Row * currentrow; // pointer to the current row
500         /// position in the text 
501         mutable long currentrow_y;
502    
503         /** inserts a new row behind the specified row, increments
504          * the touched counters */
505         void InsertRow(Row * row, LyXParagraph * par,
506                        LyXParagraph::size_type pos) const;
507         /** removes the row and reset the touched counters */
508         void RemoveRow(Row * row) const;
509
510         /** remove all following rows of the paragraph of the specified row. */
511         void RemoveParagraph(Row * row) const;
512
513         /** insert the specified paragraph behind the specified row */
514         void InsertParagraph(LyXParagraph * par, Row * row) const;
515
516         /** appends  the implizit specified paragraph behind the specified row,
517          * start at the implizit given position */
518         void AppendParagraph(Row * row) const;
519    
520         ///
521         void BreakAgain(Row * row) const;
522         ///
523         void BreakAgainOneRow(Row * row);
524         /// Calculate and set the height of the row
525         void SetHeightOfRow(Row * row_ptr) const;
526
527         /** this calculates the specified parameters. needed when setting
528          * the cursor and when creating a visible row */ 
529         void PrepareToPrint(Row * row, float & x,
530                             float & fill_separator, 
531                             float & fill_hfill,
532                             float & fill_label_hfill,
533                             bool bidi = true) const;
534         ///
535         void DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const;
536
537         /** Updates all counters starting BEHIND the row. Changed paragraphs
538          * with a dynamic left margin will be rebroken. */ 
539         void UpdateCounters(Row * row) const;
540         ///
541         void SetCounter(LyXParagraph * par) const;
542    
543         /*
544          * some low level functions
545          */
546         
547         ///
548         int SingleWidth(LyXParagraph * par,
549                         LyXParagraph::size_type pos) const;
550         ///
551         int SingleWidth(LyXParagraph * par,
552                         LyXParagraph::size_type pos, char c) const;
553         ///
554         void draw(Row const * row,
555                   LyXParagraph::size_type & pos,
556                   int offset, float & x);
557
558         /// get the next breakpoint in a given paragraph
559         LyXParagraph::size_type NextBreakPoint(Row const * row,
560                                                int width) const;
561         /// returns the minimum space a row needs on the screen in pixel
562         int Fill(Row const * row, int paperwidth) const;
563         
564         /** returns the minimum space a manual label needs on the
565           screen in pixel */ 
566         int LabelFill(Row const * row) const;
567
568         ///
569         LyXParagraph::size_type BeginningOfMainBody(LyXParagraph * par) const;
570         /** Returns the left beginning of the text.
571           This information cannot be taken from the layouts-objekt, because
572           in LaTeX the beginning of the text fits in some cases
573           (for example sections) exactly the label-width.
574           */
575         int LeftMargin(Row const * row) const;
576         ///
577         int RightMargin(Row const * row) const;
578         ///
579         int LabelEnd (Row const * row) const;
580
581         /** returns the number of separators in the specified row.
582           The separator on the very last column doesnt count
583           */ 
584         int NumberOfSeparators(Row const * row) const;
585
586         /** returns the number of hfills in the specified row. The
587           LyX-Hfill is a LaTeX \hfill so that the hfills at the
588           beginning and at the end were ignored. This is {\em MUCH}
589           more usefull than not to ignore!
590           */
591         int NumberOfHfills(Row const * row) const;
592    
593         /// like NumberOfHfills, but only those in the manual label!
594         int NumberOfLabelHfills(Row const * row) const;
595
596         /** returns true, if a expansion is needed. Rules are given by 
597           LaTeX
598           */
599         bool HfillExpansion(Row const * row_ptr,
600                             LyXParagraph::size_type pos) const;
601
602         ///
603         mutable vector<LyXParagraph::size_type> log2vis_list;
604
605         ///
606         mutable vector<LyXParagraph::size_type> vis2log_list;
607
608         ///
609         mutable LyXParagraph::size_type bidi_start;
610
611         ///
612         void ComputeBidiTables(Row *row) const;
613
614         ///
615         void ComputeBidiTablesFromTo(Row *row,
616                                      LyXParagraph::size_type from,
617                                      LyXParagraph::size_type to,
618                                      LyXParagraph::size_type offset) const;
619
620         /// Maps positions in the visual string to positions in logical string.
621         inline
622         LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
623                 if (bidi_start == -1)
624                         return pos;
625                 else
626                         return log2vis_list[pos-bidi_start];
627         }
628
629         /// Maps positions in the logical string to positions in visual string.
630         inline
631         LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
632                 if (bidi_start == -1)
633                         return pos;
634                 else
635                         return vis2log_list[pos-bidi_start];
636         }
637
638         /** returns the paragraph position of the last character in the 
639           specified row
640           */
641         LyXParagraph::size_type RowLast(Row const * row) const;
642         ///
643         void charInserted();
644 };
645
646 #endif