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