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