]> git.lyx.org Git - features.git/commitdiff
visual mode for bidi cursor movement --- in tables
authorDov Feldstern <dov@lyx.org>
Fri, 11 Apr 2008 12:02:10 +0000 (12:02 +0000)
committerDov Feldstern <dov@lyx.org>
Fri, 11 Apr 2008 12:02:10 +0000 (12:02 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24235 a592a061-630c-0410-9148-cb99ea01b6c8

src/Cursor.cpp
src/Text2.cpp
src/insets/Inset.h
src/insets/InsetTabular.cpp
src/insets/InsetTabular.h

index 81357ccc2161735fca39c5ce6a73652338a8ed15..e41ea638b64590a1d74cb797906486c7b8ac9788 100644 (file)
@@ -567,6 +567,14 @@ bool Cursor::posVisToNewRow(bool movingLeft)
        Buffer const & buf = buffer();
        Row const & row = textRow();
        bool par_is_LTR = !par.isRTL(buf.params());
+
+       // Inside a table, determining whether to move to the next or previous row
+       // should be done based on the table's direction. 
+       int s = depth() - 1;
+       if (s >= 1 && (*this)[s].inset().asInsetTabular()) {
+               par_is_LTR = !(*this)[s].inset().asInsetTabular()->isRightToLeft(*this);
+               LYXERR(Debug::RTL, "Inside table! par_is_LTR=" << (par_is_LTR ? 1 : 0));
+       }
        
        // if moving left in an LTR paragraph or moving right in an RTL one, 
        // move to previous row
index 862b3a2b59aeb24bd5533b7ef90819aaf884cba1..27fe087c109159ca389500175e9b16980c65c9ed 100644 (file)
@@ -678,7 +678,7 @@ bool Text::cursorVisLeft(Cursor & cur, bool skip_inset)
        }
 
        // Are we already at leftmost pos in row?
-       if (left_pos == -1) {
+       if (cur.text()->empty() || left_pos == -1) {
                
                Cursor new_cur = cur;
                if (!new_cur.posVisToNewRow(true)) {
@@ -768,7 +768,7 @@ bool Text::cursorVisRight(Cursor & cur, bool skip_inset)
        }
 
        // Are we already at rightmost pos in row?
-       if (right_pos == -1) {
+       if (cur.text()->empty() || right_pos == -1) {
                
                Cursor new_cur = cur;
                if (!new_cur.posVisToNewRow(false)) {
index a5fe6e6b6b2aaa964010414e6c1898b997fb00eb..b86f35c5426d6f41d0bf66ffbf72466f13452f49 100644 (file)
@@ -41,6 +41,7 @@ class InsetIterator;
 class InsetLayout;
 class InsetList;
 class InsetMath;
+class InsetTabular;
 class InsetText;
 class LaTeXFeatures;
 class Lexer;
@@ -129,6 +130,10 @@ public:
        virtual InsetCollapsable * asInsetCollapsable() { return 0; }
        /// is this inset based on the InsetCollapsable class?
        virtual InsetCollapsable const * asInsetCollapsable() const { return 0; }
+       /// is this inset based on the InsetTabular class?
+       virtual InsetTabular * asInsetTabular() { return 0; }
+       /// is this inset based on the InsetTabular class?
+       virtual InsetTabular const * asInsetTabular() const { return 0; }
 
        /// the real dispatcher
        void dispatch(Cursor & cur, FuncRequest & cmd);
index ab9062f2cc89ce942425b4de6e3e7ef3282a9109..bf37945766bb5d13fcc0f0929387eed0beea59ba 100644 (file)
@@ -3218,53 +3218,67 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                break;
        case LFUN_CHAR_FORWARD_SELECT:
        case LFUN_CHAR_FORWARD:
-               cell(cur.idx())->dispatch(cur, cmd);
-               if (!cur.result().dispatched()) {
-                       moveNextCell(cur);
-                       if (sl == cur.top())
-                               cmd = FuncRequest(LFUN_FINISHED_FORWARD);
+       case LFUN_CHAR_BACKWARD_SELECT:
+       case LFUN_CHAR_BACKWARD:
+       case LFUN_CHAR_RIGHT_SELECT:
+       case LFUN_CHAR_RIGHT:
+       case LFUN_CHAR_LEFT_SELECT:
+       case LFUN_CHAR_LEFT: {
+
+               // determine whether we move to next or previous cell, where to enter 
+               // the new cell from, and which command to "finish" (i.e., exit the
+               // inset) with:
+               bool next_cell;
+               EntryDirection entry_from = ENTRY_DIRECTION_IGNORE;
+               FuncCode finish_lfun;
+
+               if (cmd.action == LFUN_CHAR_FORWARD 
+                               || cmd.action == LFUN_CHAR_FORWARD_SELECT) {
+                       next_cell = true;
+                       finish_lfun = LFUN_FINISHED_FORWARD;
+               }
+               else if (cmd.action == LFUN_CHAR_BACKWARD
+                               || cmd.action == LFUN_CHAR_BACKWARD_SELECT) {
+                       next_cell = false;
+                       finish_lfun = LFUN_FINISHED_BACKWARD;
+               }
+               // LEFT or RIGHT commands --- the interpretation will depend on the 
+               // table's direction.
+               else {
+                       bool right = (cmd.action == LFUN_CHAR_RIGHT
+                                                       || cmd.action == LFUN_CHAR_RIGHT_SELECT);
+                       next_cell = (isRightToLeft(cur) != right);
+                       
+                       if (lyxrc.visual_cursor) {
+                               entry_from = right ? ENTRY_DIRECTION_LEFT:ENTRY_DIRECTION_RIGHT;
+                       }
+
+                       if (right)
+                               finish_lfun = LFUN_FINISHED_RIGHT;
                        else
-                               cur.dispatched();
+                               finish_lfun = LFUN_FINISHED_LEFT;
                }
-               break;
+               
 
-       case LFUN_CHAR_BACKWARD_SELECT:
-       case LFUN_CHAR_BACKWARD:
+               // finally, now that we know what we want to do, do it!
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
-                       movePrevCell(cur);
+                       // move to next/prev cell, as appropriate
+                       LYXERR(Debug::RTL, "entering " << (next_cell ? "next" : "previous")
+                               << " cell from: " << int(entry_from));
+                       if (next_cell)
+                               moveNextCell(cur, entry_from);
+                       else
+                               movePrevCell(cur, entry_from);
+                       // if we're exiting the table, call the appropriate FINISHED lfun
                        if (sl == cur.top())
-                               cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
+                               cmd = FuncRequest(finish_lfun);
                        else
                                cur.dispatched();
                }
                break;
 
-       case LFUN_CHAR_RIGHT_SELECT:
-       case LFUN_CHAR_RIGHT:
-               //FIXME: for visual cursor, really move right
-               if (isRightToLeft(cur))
-                       lyx::dispatch(FuncRequest(
-                               cmd.action == LFUN_CHAR_RIGHT_SELECT ?
-                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD));
-               else
-                       lyx::dispatch(FuncRequest(
-                               cmd.action == LFUN_CHAR_RIGHT_SELECT ?
-                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD));
-               break;
-
-       case LFUN_CHAR_LEFT_SELECT:
-       case LFUN_CHAR_LEFT:
-               //FIXME: for visual cursor, really move left
-               if (isRightToLeft(cur))
-                       lyx::dispatch(FuncRequest(
-                               cmd.action == LFUN_CHAR_LEFT_SELECT ?
-                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD));
-               else
-                       lyx::dispatch(FuncRequest(
-                               cmd.action == LFUN_CHAR_LEFT_SELECT ?
-                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD));
-               break;
+       }
 
        case LFUN_DOWN_SELECT:
        case LFUN_DOWN:
@@ -3958,7 +3972,7 @@ void InsetTabular::resetPos(Cursor & cur) const
 }
 
 
-void InsetTabular::moveNextCell(Cursor & cur)
+void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from)
 {
        if (isRightToLeft(cur)) {
                if (tabular.isFirstCellInRow(cur.idx())) {
@@ -3978,11 +3992,29 @@ void InsetTabular::moveNextCell(Cursor & cur)
        }
        cur.pit() = 0;
        cur.pos() = 0;
+       cur.boundary(false);
+
+       // in visual mode, place cursor at extreme left or right
+       
+       switch(entry_from) {
+
+       case ENTRY_DIRECTION_RIGHT:
+               cur.posVisToRowExtremity(false /* !left */);
+               break;
+       case ENTRY_DIRECTION_LEFT:
+               cur.posVisToRowExtremity(true /* left */);
+               break;
+       case ENTRY_DIRECTION_IGNORE:
+               // nothing to do in this case
+               break;
+
+       }
+
        resetPos(cur);
 }
 
 
-void InsetTabular::movePrevCell(Cursor & cur)
+void InsetTabular::movePrevCell(Cursor & cur, EntryDirection entry_from)
 {
        if (isRightToLeft(cur)) {
                if (tabular.isLastCellInRow(cur.idx())) {
@@ -4004,6 +4036,22 @@ void InsetTabular::movePrevCell(Cursor & cur)
        cur.pit() = cur.lastpit();
        cur.pos() = cur.lastpos();
 
+       // in visual mode, place cursor at extreme left or right
+       
+       switch(entry_from) {
+
+       case ENTRY_DIRECTION_RIGHT:
+               cur.posVisToRowExtremity(false /* !left */);
+               break;
+       case ENTRY_DIRECTION_LEFT:
+               cur.posVisToRowExtremity(true /* left */);
+               break;
+       case ENTRY_DIRECTION_IGNORE:
+               // nothing to do in this case
+               break;
+
+       }
+
        // FIXME: this accesses the position cache before it is initialized
        //resetPos(cur);
 }
index d05c20065a8e42eed821505be4cd2c8cf72f5a14..9d7a237fed3ffabcffd38029aae1ed34acccfb20 100644 (file)
@@ -810,6 +810,13 @@ public:
        ///
        void completionPosAndDim(Cursor const &, int & x, int & y, Dimension & dim) const;
 
+       ///
+       virtual InsetTabular * asInsetTabular() { return this; }
+       ///
+       virtual InsetTabular const * asInsetTabular() const { return this; }
+       ///
+       bool isRightToLeft(Cursor & cur) const;
+
        //
        // Public structures and variables
        ///
@@ -834,9 +841,11 @@ private:
        void setCursorFromCoordinates(Cursor & cur, int x, int y) const;
 
        ///
-       void moveNextCell(Cursor & cur);
+       void moveNextCell(Cursor & cur, 
+                               EntryDirection entry_from = ENTRY_DIRECTION_IGNORE);
        ///
-       void movePrevCell(Cursor & cur);
+       void movePrevCell(Cursor & cur,
+                               EntryDirection entry_from = ENTRY_DIRECTION_IGNORE);
        ///
        int cellXPos(idx_type cell) const;
        ///
@@ -850,8 +859,6 @@ private:
        ///
        void cutSelection(Cursor & cur);
        ///
-       bool isRightToLeft(Cursor & cur) const;
-       ///
        void getSelection(Cursor & cur, row_type & rs, row_type & re,
                          col_type & cs, col_type & ce) const;
        ///