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