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