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