X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCursor.h;h=1abc177ca469e9708b20100d2dd63c8e14e64bad;hb=28be7d552f62cc02fa86d7f79201d089bfb2d7b5;hp=318c5d9a6d45e34e5f7a9343abf7ac496973ca9a;hpb=f6b1c24b990751598bad532d4595090a2dec9061;p=lyx.git diff --git a/src/Cursor.h b/src/Cursor.h index 318c5d9a6d..1abc177ca4 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -9,6 +9,48 @@ * Full author contact details are available in file CREDITS. */ +/* +First some explanation about what a Cursor really is, from local to +global. + +* a CursorSlice indicates the position of the cursor at local level. + It contains in particular: + * idx(): the cell that contains the cursor (for Tabular or math + arrays). Always 0 for 'plain' insets + * pit(): the index of the current paragraph (only for text) + * pos(): the position in the current paragraph (or in the math + equation in mathed). + * inset(): the inset in which the cursor is. For a InsetTabular, + this is the tabular itself, not the cell inset (which is an + InsetTableCell). + +* a DocIterator indicated the position of the cursor in the document. + It knows about the current buffer (buffer() method) and contains a + vector of CursorSlices that describes the nesting of insets up to the + point of interest. Note that operator<< has been implemented, so that + one can send a DocIterator to a stream to see its value. Try it, it is + very helpful to understand the cursor layout. + * when using idx/pit/pos on a DocIterator, one gets the information + from the inner slice (this slice can be accessed as top()) + * inMathed() returns true when the cursor is in a math formula + * inTexted() returns true when the cursor is in text + * innerTextSlice() returns the deepest slice that is text (useful + when one is in a math equation and looks for the enclosing text) + +* A CursorData is a descendant of Dociterator that contains + * a second DocIterator object, the anchor, that is useful when + selecting. + * some other data that describes current selection, cursor font, etc. + + This class is mostly used only for undo and contains the Cursor + elements that are not GUI-related. In LyX 2.0, Cursor was directly + deriving from DocIterator + +* A Cursor is a descendant of CursorData that contains interesting + display-related information, in particular targetX(), the horizontal + position of the cursor in pixels. +*/ + #ifndef LCURSOR_H #define LCURSOR_H @@ -19,8 +61,6 @@ #include "mathed/MathParser_flags.h" -#include - namespace lyx { @@ -49,24 +89,19 @@ public: explicit CursorData(Buffer * buffer); /// explicit CursorData(DocIterator const & dit); + /// output + friend std::ostream & operator<<(std::ostream & os, CursorData const & cur); + friend LyXErr & operator<<(LyXErr & os, CursorData const & cur); + protected: /// the anchor position DocIterator anchor_; - /// the start of the new born word - DocIterator new_word_; - /// - mutable DispatchResult disp_; /// do we have a selection? bool selection_; /// are we on the way to get one? bool mark_; /// are we in word-selection mode? This is set when double clicking. bool word_selection_; - /// If true, we are behind the previous char, otherwise we are in front - // of the next char. This only make a difference when we are in front - // of a big inset spanning a whole row and computing coordinates for - // displaying the cursor. - bool logicalpos_; // FIXME: make them protected. public: @@ -115,7 +150,10 @@ public: /// set the cursor data void setCursorData(CursorData const & data); /// sets cursor part + /// this (intentionally) does neither touch anchor nor selection status void setCursor(DocIterator const & it); + /// set the cursor to dit normalised against the anchor, and set selection. + void setCursorSelectionTo(DocIterator dit); /// sets the cursor to the normalized selection anchor void setCursorToAnchor(); @@ -127,8 +165,8 @@ public: // /// selection active? bool selection() const { return selection_; } - /// set selection; - void setSelection(bool sel) { selection_ = sel; } + /// set selection; this is lower level than (set|clear)Selection + void selection(bool sel) { selection_ = sel; } /// do we have a multicell selection? bool selIsMultiCell() const { return selection_ && selBegin().idx() != selEnd().idx(); } @@ -155,7 +193,7 @@ public: CursorSlice selEnd() const; /// access start of selection DocIterator selectionBegin() const; - /// access start of selection + /// access end of selection DocIterator selectionEnd() const; /** * Update the selection status and save permanent @@ -177,6 +215,9 @@ public: bool macromode() const { return macromode_; } /// are we entering a macro name? bool & macromode() { return macromode_; } + + /// returns true when all insets in cursor stack are in cache + bool inCoordCache() const; /// returns x,y position void getPos(int & x, int & y) const; /// return logical positions between which the cursor is situated @@ -184,17 +225,13 @@ public: * If the cursor is at the edge of a row, the position which is "over the * edge" will be returned as -1. */ - void getSurroundingPos(pos_type & left_pos, pos_type & right_pos); + void getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const; /// the row in the paragraph we're in Row const & textRow() const; // // common part // - /// move one step backwards - bool posBackward(); - /// move one step forward - bool posForward(); /// move visually one step to the right /** * @note: This method may move into an inset unless skip_inset == true. @@ -227,6 +264,8 @@ public: bool posVisToNewRow(bool movingLeft); /// move to right or left extremity of the current row void posVisToRowExtremity(bool left); + /// Should interpretation of the arrow keys be reversed? + bool reverseDirectionNeeded() const; /// insert an inset void insert(Inset *); @@ -253,10 +292,9 @@ public: /// access to normalized selection anchor CursorSlice normalAnchor() const; - // FIXME: this can't be a const & and a const function because - // LFUN_TAB_* wants to move the real anchor. /// access to real selection anchor - DocIterator & realAnchor(); + DocIterator const & realAnchor() const { return anchor_; } + DocIterator & realAnchor() { return anchor_; } /// sets anchor to cursor position void resetAnchor(); /// access to owning BufferView @@ -301,15 +339,12 @@ public: * Not using noScreenUpdate() should never be wrong. */ void noScreenUpdate() const; - /// - Update::flags screenUpdate() const { return disp_.screenUpdate(); } /// fix cursor in circumstances that should never happen. - /// \retval true if a fix occured. + /// \retval true if a fix occurred. bool fixIfBroken(); - - /// output - friend std::ostream & operator<<(std::ostream & os, Cursor const & cur); - friend LyXErr & operator<<(LyXErr & os, Cursor const & cur); + /// Repopulate the slices insets from bottom to top. Useful + /// for stable iterators or Undo data. + void sanitize(); /// bool textUndo(); @@ -326,21 +361,23 @@ public: void endUndoGroup() const; /// The general case: prepare undo for an arbitrary range. - void recordUndo(UndoKind kind, pit_type from, pit_type to) const; + void recordUndo(pit_type from, pit_type to) const; /// Convenience: prepare undo for the range between 'from' and cursor. - void recordUndo(UndoKind kind, pit_type from) const; + void recordUndo(pit_type from) const; /// Convenience: prepare undo for the single paragraph or cell /// containing the cursor void recordUndo(UndoKind kind = ATOMIC_UNDO) const; /// Convenience: prepare undo for the inset containing the cursor - void recordUndoInset(UndoKind kind = ATOMIC_UNDO, - Inset const * inset = 0) const; + void recordUndoInset(Inset const * inset = 0) const; /// Convenience: prepare undo for the whole buffer - void recordUndoFullDocument() const; + void recordUndoFullBuffer() const; + + /// Convenience: prepare undo for buffer parameters + void recordUndoBufferParams() const; /// Convenience: prepare undo for the selected paragraphs or cells void recordUndoSelection() const; @@ -357,6 +394,17 @@ public: /// and after leaving the word the result is empty. DocIterator newWord() const { return new_word_; } + /// Return true if the next or previous inset has confirmDeletion depending + /// on the boolean before. If there is a selection, return true if at least + /// one inset in the selection has confirmDeletion. + bool confirmDeletion(bool before = false) const; + + /// Determine if x falls to the left or to the side of the middle of the + /// inset, and advance the cursor to match this position. If edit is true, + /// keep the cursor in front of the inset if it matter for dialogs. + /// Note: it does not handle RTL text yet, and is only used in math for now. + void moveToClosestEdge(int x, bool edit = false); + public: //private: @@ -391,6 +439,8 @@ private: int x_target_; /// if a x_target cannot be hit exactly in a text, put the difference here int textTargetOffset_; + /// the start of the new born word + DocIterator new_word_; /// position before dispatch started DocIterator beforeDispatchCursor_; /// cursor screen coordinates before dispatch started @@ -411,9 +461,10 @@ public: /// void insert(MathData const &); /// return false for empty math insets - bool erase(); - /// return false for empty math insets - bool backspace(); + /// Use force to skip the confirmDeletion check. + bool erase(bool force = false); + bool backspace(bool force = false); + /// move the cursor up by sending an internal LFUN_UP /// return true if fullscreen update is needed bool up(); @@ -430,6 +481,15 @@ public: /// return true if successful bool upDownInMath(bool up); /// + InsetMath & nextMath(); + /// + InsetMath & prevMath(); + /// move forward in math. word: whether to skip a whole "word" (insets with + /// the same mathclass) + bool mathForward(bool word); + /// + bool mathBackward(bool word); + /// void plainErase(); /// void plainInsert(MathAtom const & at); @@ -494,10 +554,11 @@ public: /** - * Notifies all insets which appear in old, but not in cur. And then - * notify all insets which appear in cur, but not in old. - * Make sure that the cursor old is valid, i.e. all inset pointers - * point to valid insets! Use Cursor::fixIfBroken if necessary. + * Notifies all insets which appear in \c old, but not in \c cur. And then + * notify all insets which appear in \c cur, but not in \c old. + * \returns true if cursor is now invalid, e.g. if some insets in + * higher cursor slices of \c old do not exist anymore. In this case + * it may be necessary to use Use Cursor::fixIfBroken. */ bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur);