]> git.lyx.org Git - lyx.git/blob - src/cursor.h
e4d1ebc2a1d27df87eb17d19d1740efaa483a424
[lyx.git] / src / cursor.h
1 // -*- C++ -*-
2 /**
3  * \file cursor.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef CURSOR_H
13 #define CURSOR_H
14
15 #include "cursor_slice.h"
16
17 #include <iosfwd>
18 #include <vector>
19
20 class BufferView;
21 class UpdatableInset;
22 class MathAtom;
23 class DispatchResult;
24 class FuncRequest;
25 class InsetTabular;
26 class LyXText;
27 class Paragraph;
28
29
30 // these should go
31 class MathHullInset;
32 class PainterInfo;
33 class MathUnknownInset;
34 class MathGridInset;
35
36 // this is used for traversing math insets
37 typedef std::vector<CursorSlice> CursorBase;
38 /// move on one step
39 void increment(CursorBase &);
40 ///
41 CursorBase ibegin(InsetBase * p);
42 ///
43 CursorBase iend(InsetBase * p);
44
45
46 /**
47  * The cursor class describes the position of a cursor within a document.
48  */
49
50 class LCursor {
51 public:
52         /// type for cell number in inset
53         typedef CursorSlice::idx_type idx_type;
54         /// type for paragraph numbers positions within a cell
55         typedef CursorSlice::par_type par_type;
56         /// type for cursor positions within a cell
57         typedef CursorSlice::pos_type pos_type;
58         /// type for row indices
59         typedef CursorSlice::row_type row_type;
60         /// type for col indices
61         typedef CursorSlice::col_type col_type;
62
63         /// create the cursor of a BufferView
64         explicit LCursor(BufferView & bv);
65         /// dispatch from innermost inset upwards
66         DispatchResult dispatch(FuncRequest const & cmd);
67         /// add a new cursor slice
68         void push(InsetBase * inset);
69         /// add a new cursor slice, place cursor on left end
70         void pushLeft(InsetBase * inset);
71         /// pop one level off the cursor
72         void pop();
73         /// pop one slice off the cursor stack and go left
74         bool popLeft();
75         /// pop one slice off the cursor stack and go right
76         bool popRight();
77         /// restrict cursor nesting to given size
78         void pop(int depth);
79         /// access to current cursor slice
80         CursorSlice & current();
81         /// access to current cursor slice
82         CursorSlice const & current() const;
83         /// how many nested insets do we have?
84         size_t depth() const { return cursor_.size(); }
85
86         //
87         // selection
88         //
89         /// selection active?
90         bool selection() const { return selection_; }
91         /// selection active?
92         bool & selection() { return selection_; }
93         /// did we place the anchor?
94         bool mark() const { return mark_; }
95         /// did we place the anchor?
96         bool & mark() { return mark_; }
97         ///
98         void setSelection();
99         /// set selection at given position
100         void setSelection(CursorBase const & where, size_t n);
101         ///
102         void clearSelection();
103         /// access start of selection
104         CursorSlice & selBegin();
105         /// access start of selection
106         CursorSlice const & selBegin() const;
107         /// access end of selection
108         CursorSlice & selEnd();
109         /// access end of selection
110         CursorSlice const & selEnd() const;
111         ///
112         std::string grabSelection();
113         ///
114         void eraseSelection();
115         ///
116         std::string grabAndEraseSelection();
117         // other selection methods
118         ///
119         void selCopy();
120         ///
121         void selCut();
122         ///
123         void selDel();
124         /// pastes n-th element of cut buffer
125         void selPaste(size_t n);
126         ///
127         void selHandle(bool selecting);
128         /// start selection
129         void selStart();
130         /// clear selection
131         void selClear();
132         /// clears or deletes selection depending on lyxrc setting
133         void selClearOrDel();
134         ///
135         void paste(std::string const & data);
136
137         //
138         // access to the 'current' cursor slice
139         //
140         /// the current inset
141         InsetBase * inset() const { return current().inset(); }
142         /// return the cell of the inset this cursor is in
143         idx_type idx() const { return current().idx(); }
144         /// return the cell of the inset this cursor is in
145         idx_type & idx() { return current().idx(); }
146         /// return the last possible cell in this inset
147         idx_type lastidx() const { return current().lastidx(); }
148         /// return the paragraph this cursor is in
149         par_type par() const { return current().par(); }
150         /// return the paragraph this cursor is in
151         par_type & par() { return current().par(); }
152         /// return the position within the paragraph
153         pos_type pos() const { return current().pos(); }
154         /// return the position within the paragraph
155         pos_type & pos() { return current().pos(); }
156         /// return the last position within the paragraph
157         pos_type lastpos() const;
158         /// return the number of embedded cells
159         size_t nargs() const;
160         /// return the number of embedded cells
161         size_t ncols() const;
162         /// return the number of embedded cells
163         size_t nrows() const;
164         /// return the grid row of the current cell
165         row_type row() const;
166         /// return the grid row of the current cell
167         col_type col() const;
168
169         //
170         // math-specific part
171         //
172         /// return the mathed cell this cursor is in
173         MathArray const & cell() const;
174         /// return the mathed cell this cursor is in
175         MathArray & cell();
176         /// the mathatom left of the cursor
177         MathAtom const & prevAtom() const;
178         /// the mathatom left of the cursor
179         MathAtom & prevAtom();
180         /// the mathatom right of the cursor
181         MathAtom const & nextAtom() const;
182         /// the mathatom right of the cursor
183         MathAtom & nextAtom();
184         /// auto-correct mode
185         bool autocorrect() const { return autocorrect_; }
186         /// auto-correct mode
187         bool & autocorrect() { return autocorrect_; }
188         /// are we entering a macro name?
189         bool macromode() const { return macromode_; }
190         /// are we entering a macro name?
191         bool & macromode() { return macromode_; }
192
193         //
194         // text-specific part
195         ///
196         bool boundary() const { return current().boundary(); }
197         ///
198         bool & boundary() { return current().boundary(); }
199         ///
200         Paragraph & paragraph();
201         ///
202         Paragraph const & paragraph() const;
203         ///
204         LyXText * text() const;
205         ///
206         InsetBase * innerInsetOfType(int code) const;
207         ///
208         InsetTabular * innerInsetTabular() const;
209         ///
210         LyXText * innerText() const;
211         ///
212         CursorSlice const & innerTextSlice() const;
213         /// returns x,y position
214         void getPos(int & x, int & y) const;
215         /// returns cursor dimension
216         void getDim(int & asc, int & desc) const;
217
218         //
219         // common part
220         //
221         /// move one step to the left
222         bool posLeft();
223         /// move one step to the right
224         bool posRight();
225
226         /// write acess to target x position of cursor
227         int & x_target();
228         /// return target x position of cursor
229         int x_target() const;
230         /// clear target x position of cursor
231         void clearTargetX();
232
233         /// access to selection anchor
234         CursorSlice & anchor();
235         /// access to selection anchor
236         CursorSlice const & anchor() const;
237         /// cache the absolute coordinate from the top inset
238         void updatePos();
239         /// sets anchor to cursor position
240         void resetAnchor(); 
241         /// access to owning BufferView
242         BufferView & bv() const; 
243         /// get some interesting description of current position
244         void info(std::ostream & os);
245         /// are we in math mode (2), text mode (1) or unsure (0)?
246         int currentMode();
247         /// reset cursor
248         void reset();
249
250         /// output
251         friend std::ostream & operator<<(std::ostream & os, LCursor const & cur);
252 public:
253 //private:
254         /// mainly used as stack, but wee need random access
255         std::vector<CursorSlice> cursor_;
256         /// the anchor position
257         std::vector<CursorSlice> anchor_;
258
259 private:
260         ///
261         BufferView * bv_;
262         /// current slice
263         int current_;
264         ///
265         int cached_y_;
266         /**
267          * The target x position of the cursor. This is used for when
268          * we have text like :
269          *
270          * blah blah blah blah| blah blah blah
271          * blah blah blah
272          * blah blah blah blah blah blah
273          *
274          * When we move onto row 3, we would like to be vertically aligned
275          * with where we were in row 1, despite the fact that row 2 is
276          * shorter than x()
277          */
278         int x_target_;
279         // do we have a selection?
280         bool selection_;
281         // are we on the way to get one?
282         bool mark_;
283
284         //
285         // math specific stuff that could be promoted to "global" later
286         //
287         /// do we allow autocorrection
288         bool autocorrect_;
289         /// are we entering a macro name?
290         bool macromode_;
291
292
293 ///////////////////////////////////////////////////////////////////
294 //
295 // The part below is the non-integrated rest of the original math
296 // cursor. This should be either generalized for texted or moved
297 // back to the math insets.
298 //
299 ///////////////////////////////////////////////////////////////////
300
301 public:
302         ///
303         void insert(MathAtom const &);
304         ///
305         void insert(MathArray const &);
306         ///
307         void insert2(std::string const &);
308         /// return false for empty math insets
309         bool erase();
310         /// return false for empty math insets
311         bool backspace();
312         /// called for LFUN_HOME etc
313         bool home();
314         /// called for LFUN_END etc
315         bool end();
316         /// called for LFUN_RIGHT and LFUN_RIGHTSEL
317         bool right();
318         /// called for LFUN_LEFT etc
319         bool left();
320         /// called for LFUN_UP etc
321         bool up();
322         /// called for LFUN_DOWN etc
323         bool down();
324         ///
325         void plainErase();
326         ///
327         void plainInsert(MathAtom const & at);
328         ///
329         void niceInsert(MathAtom const & at);
330         ///
331         void niceInsert(std::string const & str);
332
333         /// in pixels from top of screen
334         void setScreenPos(int x, int y);
335         /// in pixels from left of screen
336         int targetX() const;
337         /// return the next enclosing grid inset and the cursor's index in it
338         MathGridInset * enclosingGrid(idx_type & idx) const;
339         /// adjust anchor position after deletions/insertions
340         void adjust(pos_type from, int diff);
341         ///
342         MathHullInset * formula() const;
343         /// current offset in the current cell
344         ///
345         bool script(bool);
346         ///
347         bool interpret(char);
348         /// interpret name a name of a macro
349         void macroModeClose();
350         /// are we currently typing the name of a macro?
351         bool inMacroMode() const;
352         /// get access to the macro we are currently typing
353         MathUnknownInset * activeMacro();
354         /// are we currently typing '#1' or '#2' or...?
355         bool inMacroArgMode() const;
356
357         /// replace selected stuff with at, placing the former
358         // selection in given cell of atom
359         void handleNest(MathAtom const & at, int cell = 0);
360         /// remove this as soon as LyXFunc::getStatus is "localized"
361         //inline std::string getLastCode() { return "mathnormal"; }
362         ///
363         bool isInside(InsetBase const *);
364         ///
365         char valign();
366         ///
367         char halign();
368
369         /// make sure cursor position is valid
370         void normalize();
371         /// mark current cursor trace for redraw
372         void touch();
373
374         /// returns the normalized anchor of the selection
375         CursorSlice normalAnchor();
376
377         ///
378         void insert(char c);
379         ///
380         void insert(std::string const & str);
381         /// lock/unlock inset
382         void lockToggle();
383
384         /// hack for reveal codes
385         void markInsert();
386         void markErase();
387         /// injects content of a cell into parent
388         void pullArg();
389         /// split font inset etc
390         void handleFont(std::string const & font);
391
392         void releaseMathCursor();
393
394         bool inMathed() const;
395
396 private:
397         /// moves cursor index one cell to the left
398         bool idxLeft();
399         /// moves cursor index one cell to the right
400         bool idxRight();
401         /// moves cursor to end of last cell of current line
402         bool idxLineLast();
403         /// moves position somehow up or down
404         bool goUpDown(bool up);
405         /// moves position closest to (x, y) in given box
406         bool bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh);
407         /// moves position closest to (x, y) in current cell
408         void bruteFind2(int x, int y);
409         /// are we in a nucleus of a script inset?
410         bool inNucleus();
411
412         /// the name of the macro we are currently inputting
413         std::string macroName();
414         /// where in the curent cell does the macro name start?
415         int macroNamePos();
416         /// can we enter the inset?
417         bool openable(MathAtom const &);
418 };
419
420 #endif // LYXCURSOR_H