]> git.lyx.org Git - lyx.git/blob - src/lyxtext.h
25c63df039b867f4e1f9d0c399c4effe4d69b2e8
[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 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 private:
170         /// returns a pointer to a specified row.
171         RowList::iterator getRow(Paragraph & par, lyx::pos_type pos) const;
172 public:
173         /// returns an iterator pointing to a cursor row
174         RowList::iterator getRow(LyXCursor const & cursor) const;
175         /// convenience
176         RowList::iterator cursorRow() const;
177         /// returns an iterator pointing to a cursor paragraph
178         ParagraphList::iterator getPar(LyXCursor const & cursor) const;
179         ///
180         ParagraphList::iterator getPar(lyx::paroffset_type par) const;
181         ///
182         int parOffset(ParagraphList::iterator pit) const;
183         /// convenience
184         ParagraphList::iterator cursorPar() const;
185
186         /** returns a pointer to the row near the specified y-coordinate
187           (relative to the whole text). y is set to the real beginning
188           of this row
189           */
190         RowList::iterator getRowNearY(int y,
191                 ParagraphList::iterator & pit) const;
192
193         /** returns the column near the specified x-coordinate of the row
194          x is set to the real beginning of this column
195          */
196         lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
197                 Row const & row, int & x, bool & boundary) const;
198
199         /// need the selection cursor:
200         void setSelection();
201         ///
202         void clearSelection();
203
204         /// select the word we need depending on word_location
205         void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
206         /// just selects the word the cursor is in
207         void selectWord(lyx::word_location loc);
208         /// returns the inset at cursor (if it exists), 0 otherwise
209         InsetOld * getInset() const;
210
211         /// accept selected change
212         void acceptChange();
213
214         /// reject selected change
215         void rejectChange();
216
217         /** 'selects" the next word, where the cursor is not in
218          and returns this word as string. THe cursor will be moved
219          to the beginning of this word.
220          With SelectSelectedWord can this be highlighted really
221          */
222         WordLangTuple const selectNextWordToSpellcheck(float & value);
223         ///
224         void selectSelectedWord();
225         /// re-computes the cached coordinates in the cursor
226         void redoCursor();
227         ///
228         void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
229         /// returns true if par was empty and was removed
230         bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
231                        bool setfont = true, bool boundary = false);
232         ///
233         void setCursor(LyXCursor &, lyx::paroffset_type par,
234                        lyx::pos_type pos, bool boundary = false);
235         ///
236         void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
237                              bool setfont = true, bool boundary = false);
238         ///
239         void setCurrentFont();
240
241         ///
242         void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
243         ///
244         void recUndo(lyx::paroffset_type first) const;
245         ///
246         void setCursorFromCoordinates(int x, int y);
247         ///
248         void setCursorFromCoordinates(LyXCursor &, int x, int y);
249         ///
250         void cursorUp(bool selecting = false);
251         ///
252         void cursorDown(bool selecting = false);
253         ///
254         void cursorLeft(bool internal = true);
255         ///
256         void cursorRight(bool internal = true);
257         ///
258         void cursorLeftOneWord();
259         ///
260         void cursorRightOneWord();
261         ///
262         void cursorUpParagraph();
263         ///
264         void cursorDownParagraph();
265         ///
266         void cursorHome();
267         ///
268         void cursorEnd();
269         ///
270         void cursorPrevious();
271         ///
272         void cursorNext();
273         ///
274         void cursorTop();
275         ///
276         void cursorBottom();
277         ///
278         void Delete();
279         ///
280         void backspace();
281         ///
282         bool selectWordWhenUnderCursor(lyx::word_location);
283         ///
284         enum TextCase {
285                 ///
286                 text_lowercase = 0,
287                 ///
288                 text_capitalization = 1,
289                 ///
290                 text_uppercase = 2
291         };
292         /// Change the case of the word at cursor position.
293         void changeCase(TextCase action);
294
295         ///
296         void toggleInset();
297         ///
298         void cutSelection(bool doclear = true, bool realcut = true);
299         ///
300         void copySelection();
301         ///
302         void pasteSelection(size_t sel_index = 0);
303
304         /** the DTP switches for paragraphs. LyX will store the top settings
305          always in the first physical paragraph, the bottom settings in the
306          last. When a paragraph is broken, the top settings rest, the bottom
307          settings are given to the new one. So I can make shure, they do not
308          duplicate themself (and you cannnot make dirty things with them! )
309          */
310         void setParagraph(bool line_top, bool line_bottom,
311                           bool pagebreak_top, bool pagebreak_bottom,
312                           VSpace const & space_top,
313                           VSpace const & space_bottom,
314                           Spacing const & spacing,
315                           LyXAlignment align,
316                           std::string const & labelwidthstring,
317                           bool noindent);
318
319         /* these things are for search and replace */
320
321         /**
322          * Sets the selection from the current cursor position to length
323          * characters to the right. No safety checks.
324          */
325         void setSelectionRange(lyx::pos_type length);
326
327         /** simple replacing. The font of the first selected character
328           is used
329           */
330         void replaceSelectionWithString(std::string const & str);
331
332         /// needed to insert the selection
333         void insertStringAsLines(std::string const & str);
334         /// needed to insert the selection
335         void insertStringAsParagraphs(std::string const & str);
336
337         /// Find next inset of some specified type.
338         bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
339                            std::string const & contents = std::string());
340         ///
341         void gotoInset(std::vector<InsetOld::Code> const & codes,
342                        bool same_content);
343         ///
344         void gotoInset(InsetOld::Code code, bool same_content);
345
346         ///
347         int workWidth() const;
348
349 private:
350         ///
351         float getCursorX(ParagraphList::iterator pit,
352              Row const & row, lyx::pos_type pos,
353                          lyx::pos_type last, bool boundary) const;
354         /// used in setlayout
355         void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
356
357         /// Calculate and set the height of the row
358         void setHeightOfRow(ParagraphList::iterator, Row & row);
359
360         // fix the cursor `cur' after a characters has been deleted at `where'
361         // position. Called by deleteEmptyParagraphMechanism
362         void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
363
364         /// delete double space (false) or empty paragraphs (true) around old_cursor
365         bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
366
367 public:
368         /** Updates all counters starting BEHIND the row. Changed paragraphs
369          * with a dynamic left margin will be rebroken. */
370         void updateCounters();
371         /**
372          * Returns an inset if inset was hit, or 0 if not.
373          * If hit, the coordinates are changed relative to the inset.
374          */
375         InsetOld * checkInsetHit(int & x, int & y);
376
377         ///
378         int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
379         ///
380         int singleWidth(ParagraphList::iterator pit,
381                 lyx::pos_type pos, char c, LyXFont const & Font) const;
382
383         /// return the color of the canvas
384         LColor_color backgroundColor() const;
385
386
387         unsigned char transformChar(unsigned char c, Paragraph const & par,
388                                     lyx::pos_type pos) const;
389
390         /**
391          * Returns the left beginning of the text.
392          * This information cannot be taken from the layout object, because
393          * in LaTeX the beginning of the text fits in some cases
394          * (for example sections) exactly the label-width.
395          */
396         int leftMargin(ParagraphList::iterator pit, Row const & row) const;
397         ///
398         int rightMargin(Paragraph const & par, Buffer const &, Row const & row) const;
399
400         /** this calculates the specified parameters. needed when setting
401          * the cursor and when creating a visible row */
402         void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
403
404 private:
405         ///
406         void setCounter(Buffer const &, ParagraphList::iterator pit);
407         ///
408         void deleteWordForward();
409         ///
410         void deleteWordBackward();
411         ///
412         void deleteLineForward();
413
414         /// sets row.end to the pos value *after* which a row should break.
415         /// for example, the pos after which isNewLine(pos) == true
416         void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
417
418         /// returns the minimum space a row needs on the screen in pixel
419         int fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
420
421         /**
422          * returns the minimum space a manual label needs on the
423          * screen in pixels
424          */
425         int labelFill(ParagraphList::iterator pit, Row const & row) const;
426
427         /// FIXME
428         int labelEnd(ParagraphList::iterator pit, Row const & row) const;
429         
430         ///
431         void charInserted();
432
433 public:
434         ///
435         mutable Bidi bidi;
436         ///
437         bool in_inset_;
438         ///
439         ParagraphList * paragraphs_;
440         //
441         // special owner functions
442         ///
443         ParagraphList & ownerParagraphs() const;
444
445         /// return true if this is owned by an inset.
446         bool isInInset() const;
447
448         /// return first row of text
449         RowList::iterator firstRow() const;
450         /// return last row of text
451         RowList::iterator lastRow() const;
452         /// return row "behind" last row of text
453         RowList::iterator endRow() const;
454         /// return next row crossing paragraph boundaries
455         void nextRow(ParagraphList::iterator & pit,
456                 RowList::iterator & rit) const;
457         /// return previous row crossing paragraph boundaries
458         void previousRow(ParagraphList::iterator & pit,
459                 RowList::iterator & rit) const;
460
461         /// is this row the last in the text?
462         bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
463         /// is this row the first in the text?
464         bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
465
466         ///
467         std::string selectionAsString(Buffer const & buffer, bool label) const;
468 private:
469         /** Cursor related data.
470           Later this variable has to be removed. There should be now internal
471           cursor in a text */
472         ///
473         ///TextCursor cursor_;
474         /// prohibit this as long as there are back pointers...
475         LyXText(LyXText 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