]> git.lyx.org Git - lyx.git/blob - src/lyxtext.h
remove reinit argument from LyXText::init (act as if always true)
[lyx.git] / src / lyxtext.h
1 // -*- C++ -*-
2 /**
3  * \file lyxtext.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author unknown
8  * \author Lars Gullik Bjønnes
9  * \author John Levon
10  *
11  * Full author contact details are available in file CREDITS
12  */
13
14 #ifndef LYXTEXT_H
15 #define LYXTEXT_H
16
17 #include "lyxfont.h"
18 #include "lyxcursor.h"
19 #include "layout.h"
20 #include "LColor.h"
21 #include "insets/inset.h"
22 #include "RowList.h"
23 #include "bufferview_funcs.h"
24 #include "textcursor.h"
25
26 class Buffer;
27 class BufferParams;
28 class BufferView;
29 class InsetText;
30 class Paragraph;
31 class Row;
32 class Spacing;
33 class UpdatableInset;
34 class VSpace;
35 class WordLangTuple;
36 class ParagraphList;
37
38
39 /**
40   This class holds the mapping between buffer paragraphs and screen rows.
41   */
42
43 // The inheritance from TextCursor should go. It's just there to ease
44 // transition...
45 class LyXText : public TextCursor {
46 public:
47         /// what repainting is needed
48         enum refresh_status {
49                 /// no repaint is needed
50                 REFRESH_NONE = 0,
51                 /// the refresh_row needs repainting
52                 REFRESH_ROW = 1,
53                 /// everything from refresh_y downwards needs repainting
54                 REFRESH_AREA = 2
55         };
56
57         /// Constructor
58         LyXText(BufferView *);
59         /// sets inset as owner
60         LyXText(BufferView *, InsetText *);
61
62         void init(BufferView *);
63         ///
64         int height;
65         ///
66         unsigned int width;
67         /// the current font settings
68         LyXFont current_font;
69         /// the current font
70         LyXFont real_current_font;
71 private:
72         /** the 'anchor' row: the position of this row remains constant
73          *  with respect to the top of the screen
74          */
75         RowList::iterator anchor_row_;
76         /** the pixel offset with respect to this row of top_y
77          */
78         int anchor_row_offset_;
79 public:
80         /// update all cached row positions
81         void updateRowPositions();
82         /// get the y coord. of the top of the screen (relative to doc start)
83         int top_y() const;
84         /// set the y coord. of the top of the screen (relative to doc start)
85         void top_y(int newy);
86         /// set the anchoring row. top_y will be computed relative to this
87         void anchor_row(RowList::iterator rit);
88         ///
89         InsetText * inset_owner;
90         ///
91         UpdatableInset * the_locking_inset;
92
93         ///
94         int getRealCursorX() const;
95         ///
96         LyXFont const getFont(Buffer const *, ParagraphList::iterator pit,
97                 lyx::pos_type pos) const;
98         ///
99         LyXFont const getLayoutFont(Buffer const *,
100                                     ParagraphList::iterator pit) const;
101         ///
102         LyXFont const getLabelFont(Buffer const *,
103                                    ParagraphList::iterator pit) const;
104         ///
105         void setCharFont(Buffer const *, ParagraphList::iterator pit,
106                          lyx::pos_type pos, LyXFont const & font);
107         void setCharFont(ParagraphList::iterator pit,
108                          lyx::pos_type pos,
109                          LyXFont const & font, bool toggleall);
110
111         ///
112         void breakAgainOneRow(RowList::iterator rit);
113         /// what you expect when pressing <enter> at cursor position
114         void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
115
116         /** set layout over selection and make a total rebreak of
117           those paragraphs
118           */
119         ParagraphList::iterator
120         setLayout(LyXCursor & actual_cursor,
121                   LyXCursor & selection_start,
122                   LyXCursor & selection_end,
123                   string const & layout);
124         ///
125         void setLayout(string const & layout);
126
127         /**
128          * Increase or decrease the nesting depth of the selected paragraph(s)
129          * if test_only, don't change any depths. Returns whether something
130          * (would have) changed
131          */
132         bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
133
134         /// get the depth at current cursor position
135         int getDepth() const;
136
137         /** set font over selection and make a total rebreak of those
138           paragraphs.
139           toggleall defaults to false.
140           */
141         void setFont(LyXFont const &, bool toggleall = false);
142
143         /** deletes and inserts again all paragaphs between the cursor
144           and the specified par. The Cursor is needed to set the refreshing
145           parameters.
146           This function is needed after SetLayout and SetFont etc.
147           */
148         void redoParagraphs(LyXCursor const & cursor,
149                             ParagraphList::iterator endpit);
150         ///
151         void redoParagraph();
152
153         ///
154         void toggleFree(LyXFont const &, bool toggleall = false);
155
156         ///
157         string getStringToIndex();
158
159         /** recalculates the heights of all previous rows of the
160             specified paragraph.  needed, if the last characters font
161             has changed.
162             */
163         void redoHeightOfParagraph();
164
165         /** insert a character, moves all the following breaks in the
166           same Paragraph one to the right and make a little rebreak
167           */
168         void insertChar(char c);
169         ///
170         void insertInset(Inset * inset);
171
172         /// Completes the insertion with a rebreak from 'need_break_row' on
173         void partialRebreak();
174         /// a full rebreak of the whole text
175         void fullRebreak();
176
177         ///
178         RowList::iterator need_break_row;
179
180         /// clear any pending paints
181         void clearPaint();
182
183         /**
184          * Mark position y as the starting point for a repaint
185          */
186         void postPaint(int start_y);
187
188         /**
189          * Mark the given row at position y as needing a repaint.
190          */
191         void postRowPaint(RowList::iterator rit, int start_y);
192
193         ///
194         Inset::RESULT dispatch(FuncRequest const & cmd);
195
196         BufferView * bv();
197
198         BufferView * bv() const;
199
200         friend class LyXScreen;
201
202         /**
203          * Return the status. This represents what repaints are
204          * pending after some operation (e.g. inserting a char).
205          */
206         refresh_status refreshStatus() const;
207
208 private:
209         /**
210          * The pixel y position from which to repaint the screen.
211          * The position is absolute along the height of outermost
212          * lyxtext (I think). REFRESH_AREA and REFRESH_ROW
213          * repaints both use this as a starting point (if it's within
214          * the viewable portion of the lyxtext).
215          */
216         int refresh_y;
217         /**
218          * The row from which to repaint the screen, used by screen.c.
219          * This must be set if the pending update is REFRESH_ROW.
220          * It doesn't make any difference for REFRESH_AREA.
221          */
222         RowList::iterator refresh_row;
223
224         refresh_status refresh_status_;
225
226 public:
227         /// only the top-level LyXText has this non-zero
228         BufferView * bv_owner;
229
230 private:
231         /// returns a pointer to a specified row.
232         RowList::iterator
233         getRow(ParagraphList::iterator pit, lyx::pos_type pos) const;
234 public:
235         /// returns a pointer cursor row
236         RowList::iterator getRow(LyXCursor const & cursor) const;
237         /// convenience
238         RowList::iterator cursorRow() const;
239
240         /** returns a pointer to the row near the specified y-coordinate
241           (relative to the whole text). y is set to the real beginning
242           of this row
243           */
244         RowList::iterator getRowNearY(int & y) const;
245
246         /** returns the column near the specified x-coordinate of the row
247          x is set to the real beginning of this column
248          */
249         lyx::pos_type getColumnNearX(RowList::iterator rit,
250                                      int & x, bool & boundary) const;
251
252         /** returns a pointer to a specified row. y is set to the beginning
253          of the row
254          */
255         RowList::iterator
256         getRow(ParagraphList::iterator pit, lyx::pos_type pos, int & y) const;
257
258         RowList & rows() const {
259                 return rowlist_;
260         }
261
262
263         /// need the selection cursor:
264         void setSelection();
265         ///
266         void clearSelection();
267
268         /// select the word we need depending on word_location
269         void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
270         /// just selects the word the cursor is in
271         void selectWord(lyx::word_location loc);
272         /// returns the inset at cursor (if it exists), 0 otherwise
273         Inset * getInset() const;
274
275         /// accept selected change
276         void acceptChange();
277
278         /// reject selected change
279         void rejectChange();
280
281         /** 'selects" the next word, where the cursor is not in
282          and returns this word as string. THe cursor will be moved
283          to the beginning of this word.
284          With SelectSelectedWord can this be highlighted really
285          */
286         WordLangTuple const selectNextWordToSpellcheck(float & value);
287         ///
288         void selectSelectedWord();
289         /// returns true if par was empty and was removed
290         bool setCursor(ParagraphList::iterator pit,
291                        lyx::pos_type pos,
292                        bool setfont = true,
293                        bool boundary = false);
294         ///
295         void setCursor(LyXCursor &, ParagraphList::iterator pit,
296                        lyx::pos_type pos,
297                        bool boundary = false);
298         ///
299         void setCursorIntern(ParagraphList::iterator pit,
300                              lyx::pos_type pos,
301                              bool setfont = true,
302                              bool boundary = false);
303         ///
304         void setCurrentFont();
305
306         ///
307         bool isBoundary(Buffer const *, Paragraph const & par,
308                         lyx::pos_type pos) const;
309         ///
310         bool isBoundary(Buffer const *, Paragraph const & par,
311                          lyx::pos_type pos,
312                          LyXFont const & font) const;
313
314         ///
315         void setCursorFromCoordinates(int x, int y);
316         ///
317         void setCursorFromCoordinates(LyXCursor &,
318                                       int x, int y);
319         ///
320         void cursorUp(bool selecting = false);
321         ///
322         void cursorDown(bool selecting = false);
323         ///
324         void cursorLeft(bool internal = true);
325         ///
326         void cursorRight(bool internal = true);
327         ///
328         void cursorLeftOneWord();
329         ///
330         void cursorRightOneWord();
331         ///
332         void cursorUpParagraph();
333         ///
334         void cursorDownParagraph();
335         ///
336         void cursorHome();
337         ///
338         void cursorEnd();
339         ///
340         void cursorPrevious();
341         ///
342         void cursorNext();
343         ///
344         void cursorTop();
345         ///
346         void cursorBottom();
347         ///
348         void Delete();
349         ///
350         void backspace();
351         ///
352         bool selectWordWhenUnderCursor(lyx::word_location);
353         ///
354         enum TextCase {
355                 ///
356                 text_lowercase = 0,
357                 ///
358                 text_capitalization = 1,
359                 ///
360                 text_uppercase = 2
361         };
362         /// Change the case of the word at cursor position.
363         void changeCase(TextCase action);
364
365         ///
366         void toggleInset();
367         ///
368         void cutSelection(bool doclear = true, bool realcut = true);
369         ///
370         void copySelection();
371         ///
372         void pasteSelection(size_t sel_index = 0);
373
374         /** the DTP switches for paragraphs. LyX will store the top settings
375          always in the first physical paragraph, the bottom settings in the
376          last. When a paragraph is broken, the top settings rest, the bottom
377          settings are given to the new one. So I can make shure, they do not
378          duplicate themself (and you cannnot make dirty things with them! )
379          */
380         void setParagraph(bool line_top, bool line_bottom,
381                           bool pagebreak_top, bool pagebreak_bottom,
382                           VSpace const & space_top,
383                           VSpace const & space_bottom,
384                           Spacing const & spacing,
385                           LyXAlignment align,
386                           string const & labelwidthstring,
387                           bool noindent);
388
389         /* these things are for search and replace */
390
391         /**
392          * Sets the selection from the current cursor position to length
393          * characters to the right. No safety checks.
394          */
395         void setSelectionRange(lyx::pos_type length);
396
397         /** simple replacing. The font of the first selected character
398           is used
399           */
400         void replaceSelectionWithString(string const & str);
401
402         /// needed to insert the selection
403         void insertStringAsLines(string const & str);
404         /// needed to insert the selection
405         void insertStringAsParagraphs(string const & str);
406
407         /// Find next inset of some specified type.
408         bool gotoNextInset(std::vector<Inset::Code> const & codes,
409                            string const & contents = string());
410         ///
411         void gotoInset(std::vector<Inset::Code> const & codes,
412                        bool same_content);
413         ///
414         void gotoInset(Inset::Code code, bool same_content);
415         ///
416
417         /* for the greater insets */
418
419         /// returns false if inset wasn't found
420         bool updateInset(Inset *);
421         ///
422         void checkParagraph(ParagraphList::iterator pit, lyx::pos_type pos);
423         ///
424         int workWidth() const;
425         /// returns width of row containing inset
426         int workWidth(Inset const * inset) const;
427
428         ///
429         void computeBidiTables(Buffer const *, RowList::iterator row) const;
430         /// Maps positions in the visual string to positions in logical string.
431         lyx::pos_type log2vis(lyx::pos_type pos) const;
432         /// Maps positions in the logical string to positions in visual string.
433         lyx::pos_type vis2log(lyx::pos_type pos) const;
434         ///
435         lyx::pos_type bidi_level(lyx::pos_type pos) const;
436         ///
437         bool bidi_InRange(lyx::pos_type pos) const;
438 private:
439         ///
440         mutable RowList rowlist_;
441
442         ///
443         float getCursorX(RowList::iterator rit, lyx::pos_type pos,
444                          lyx::pos_type last, bool boundary) const;
445         /// used in setlayout
446         void makeFontEntriesLayoutSpecific(Buffer const &, Paragraph & par);
447
448         /** forces the redrawing of a paragraph. Needed when manipulating a
449             right address box
450             */
451         void redoDrawingOfParagraph(LyXCursor const & cursor);
452
453         /// removes the row and reset the touched counters
454         void removeRow(RowList::iterator rit);
455
456         /// remove all following rows of the paragraph of the specified row.
457         void removeParagraph(RowList::iterator rit);
458
459         /// insert the specified paragraph behind the specified row
460         void insertParagraph(ParagraphList::iterator pit,
461                              RowList::iterator rowit);
462
463         /** appends  the implizit specified paragraph behind the specified row,
464          * start at the implizit given position */
465         void appendParagraph(RowList::iterator rowit);
466
467         ///
468         void breakAgain(RowList::iterator rit);
469         /// Calculate and set the height of the row
470         void setHeightOfRow(RowList::iterator rit);
471
472         // fix the cursor `cur' after a characters has been deleted at `where'
473         // position. Called by deleteEmptyParagraphMechanism
474         void fixCursorAfterDelete(LyXCursor & cur,
475                                   LyXCursor const & where);
476
477         /// delete double space (false) or empty paragraphs (true) around old_cursor
478         bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
479
480 public:
481         /** Updates all counters starting BEHIND the row. Changed paragraphs
482          * with a dynamic left margin will be rebroken. */
483         void updateCounters();
484         ///
485         void update();
486         /**
487          * Returns an inset if inset was hit, or 0 if not.
488          * If hit, the coordinates are changed relative to the inset.
489          */
490         Inset * checkInsetHit(int & x, int & y);
491
492         ///
493         int singleWidth(ParagraphList::iterator pit,
494                 lyx::pos_type pos) const;
495         ///
496         int singleWidth(ParagraphList::iterator pit,
497                 lyx::pos_type pos, char c) const;
498
499         /// return the color of the canvas
500         LColor::color backgroundColor() const;
501
502         ///
503         mutable bool bidi_same_direction;
504
505         unsigned char transformChar(unsigned char c, Paragraph const & par,
506                                     lyx::pos_type pos) const;
507
508         /**
509          * Returns the left beginning of the text.
510          * This information cannot be taken from the layout object, because
511          * in LaTeX the beginning of the text fits in some cases
512          * (for example sections) exactly the label-width.
513          */
514         int leftMargin(Row const & row) const;
515         ///
516         int rightMargin(Buffer const &, Row const & row) const;
517
518         /** this calculates the specified parameters. needed when setting
519          * the cursor and when creating a visible row */
520         void prepareToPrint(RowList::iterator row, float & x,
521                             float & fill_separator,
522                             float & fill_hfill,
523                             float & fill_label_hfill,
524                             bool bidi = true) const;
525
526 private:
527         ///
528         void setCounter(Buffer const *, ParagraphList::iterator pit);
529         ///
530         void deleteWordForward();
531         ///
532         void deleteWordBackward();
533         ///
534         void deleteLineForward();
535
536         /*
537          * some low level functions
538          */
539
540
541         /// return the pos value *before* which a row should break.
542         /// for example, the pos at which IsNewLine(pos) == true
543         lyx::pos_type rowBreakPoint(Row const & row) const;
544
545         /// returns the minimum space a row needs on the screen in pixel
546         int fill(RowList::iterator row, int workwidth) const;
547
548         /**
549          * returns the minimum space a manual label needs on the
550          * screen in pixels
551          */
552         int labelFill(Row const & row) const;
553
554         /// FIXME
555         int labelEnd(Row const & row) const;
556
557         ///
558         mutable std::vector<lyx::pos_type> log2vis_list;
559         ///
560         mutable std::vector<lyx::pos_type> vis2log_list;
561         ///
562         mutable std::vector<lyx::pos_type> bidi_levels;
563         ///
564         mutable lyx::pos_type bidi_start;
565         ///
566         mutable lyx::pos_type bidi_end;
567
568         ///
569         void charInserted();
570 public:
571         //
572         // special owner functions
573         ///
574         ParagraphList & ownerParagraphs() const;
575
576         /// return true if this is owned by an inset.
577         bool isInInset() const;
578
579 private:
580         /** Cursor related data.
581           Later this variable has to be removed. There should be now internal
582           cursor in a text */
583         ///
584         ///TextCursor cursor_;
585 };
586
587 /// return the default height of a row in pixels, considering font zoom
588 extern int defaultRowHeight();
589
590 #endif // LYXTEXT_H