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