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