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