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