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