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