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