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