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