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