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