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