]> git.lyx.org Git - features.git/commitdiff
visual mode for bidi cursor movement --- at the word-at-a-time level
authorDov Feldstern <dov@lyx.org>
Sun, 4 May 2008 20:22:19 +0000 (20:22 +0000)
committerDov Feldstern <dov@lyx.org>
Sun, 4 May 2008 20:22:19 +0000 (20:22 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24602 a592a061-630c-0410-9148-cb99ea01b6c8

src/Text.cpp
src/Text.h
src/Text3.cpp

index e2bec2e19c8be1f4834df0c135077c02dc5a2e1c..c324b572f53b3ae9b749b99a0acb050aad909a51 100644 (file)
@@ -622,6 +622,84 @@ bool Text::cursorBackwardOneWord(Cursor & cur)
 }
 
 
+bool Text::cursorVisLeftOneWord(Cursor & cur)
+{
+       LASSERT(this == cur.text(), /**/);
+
+       pos_type left_pos, right_pos;
+       bool left_is_letter, right_is_letter;
+
+       Cursor temp_cur = cur;
+
+       // always try to move at least once...
+       while (temp_cur.posVisLeft(true /* skip_inset */)) {
+
+               // collect some information about current cursor position
+               temp_cur.getSurroundingPos(left_pos, right_pos);
+               left_is_letter = 
+                       (left_pos > -1 ? temp_cur.paragraph().isLetter(left_pos) : false);
+               right_is_letter = 
+                       (right_pos > -1 ? temp_cur.paragraph().isLetter(right_pos) : false);
+
+               // if we're not at a letter/non-letter boundary, continue moving
+               if (left_is_letter == right_is_letter)
+                       continue;
+
+               // we should stop when we have an LTR word on our right or an RTL word
+               // on our left
+               if ((left_is_letter && temp_cur.paragraph().getFontSettings(
+                               temp_cur.bv().buffer().params(), 
+                               left_pos).isRightToLeft())
+                       || (right_is_letter && !temp_cur.paragraph().getFontSettings(
+                               temp_cur.bv().buffer().params(), 
+                               right_pos).isRightToLeft()))
+                       break;
+       }
+
+       return setCursor(cur, temp_cur.pit(), temp_cur.pos(), 
+                                        true, temp_cur.boundary());
+}
+
+
+bool Text::cursorVisRightOneWord(Cursor & cur)
+{
+       LASSERT(this == cur.text(), /**/);
+
+       pos_type left_pos, right_pos;
+       bool left_is_letter, right_is_letter;
+
+       Cursor temp_cur = cur;
+
+       // always try to move at least once...
+       while (temp_cur.posVisRight(true /* skip_inset */)) {
+
+               // collect some information about current cursor position
+               temp_cur.getSurroundingPos(left_pos, right_pos);
+               left_is_letter = 
+                       (left_pos > -1 ? temp_cur.paragraph().isLetter(left_pos) : false);
+               right_is_letter = 
+                       (right_pos > -1 ? temp_cur.paragraph().isLetter(right_pos) : false);
+
+               // if we're not at a letter/non-letter boundary, continue moving
+               if (left_is_letter == right_is_letter)
+                       continue;
+
+               // we should stop when we have an LTR word on our right or an RTL word
+               // on our left
+               if ((left_is_letter && temp_cur.paragraph().getFontSettings(
+                               temp_cur.bv().buffer().params(), 
+                               left_pos).isRightToLeft())
+                       || (right_is_letter && !temp_cur.paragraph().getFontSettings(
+                               temp_cur.bv().buffer().params(), 
+                               right_pos).isRightToLeft()))
+                       break;
+       }
+
+       return setCursor(cur, temp_cur.pit(), temp_cur.pos(), 
+                                        true, temp_cur.boundary());
+}
+
+
 void Text::selectWord(Cursor & cur, word_location loc)
 {
        LASSERT(this == cur.text(), /**/);
index 526fa2ee85a87b072190a17ab30ee9ac974a916b..34977dab015b563e6ce725cfad17c8e7d172a57b 100644 (file)
@@ -193,6 +193,10 @@ public:
        bool cursorBackwardOneWord(Cursor & cur);
        ///
        bool cursorForwardOneWord(Cursor & cur);
+       ///
+       bool cursorVisLeftOneWord(Cursor & cur);
+       ///
+       bool cursorVisRightOneWord(Cursor & cur);
        /// Delete from cursor up to the end of the current or next word.
        void deleteWordForward(Cursor & cur);
        /// Delete from cursor to start of current or prior word.
index b63f7aa7c8fed00f44b8e516e5fe198b55a76556..a38b5ab579b9da6d0118e67c1c1572666218f535 100644 (file)
@@ -633,16 +633,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_WORD_RIGHT:
        case LFUN_WORD_RIGHT_SELECT:
-               //FIXME: for visual cursor mode, really move right
-               if (reverseDirectionNeeded(cur)) {
-                       cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ?
-                                       LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD;
+               if (lyxrc.visual_cursor) {
+                       needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_RIGHT_SELECT);
+                       needsUpdate |= cursorVisRightOneWord(cur);
+                       if (!needsUpdate && oldTopSlice == cur.top()
+                                       && cur.boundary() == oldBoundary) {
+                               cur.undispatched();
+                               cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       }
                } else {
-                       cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ?
-                                       LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD;
+                       if (reverseDirectionNeeded(cur)) {
+                               cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ?
+                                               LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD;
+                       } else {
+                               cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ?
+                                               LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD;
+                       }
+                       dispatch(cur, cmd);
+                       return;
                }
-               dispatch(cur, cmd);
-               return;
+               break;
 
        case LFUN_WORD_FORWARD:
        case LFUN_WORD_FORWARD_SELECT:
@@ -652,16 +662,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_WORD_LEFT:
        case LFUN_WORD_LEFT_SELECT:
-               //FIXME: for visual cursor mode, really move left
-               if (reverseDirectionNeeded(cur)) {
-                       cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ?
-                                       LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD;
+               if (lyxrc.visual_cursor) {
+                       needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_LEFT_SELECT);
+                       needsUpdate |= cursorVisLeftOneWord(cur);
+                       if (!needsUpdate && oldTopSlice == cur.top()
+                                       && cur.boundary() == oldBoundary) {
+                               cur.undispatched();
+                               cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                       }
                } else {
-                       cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ?
-                                       LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD;
+                       if (reverseDirectionNeeded(cur)) {
+                               cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ?
+                                               LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD;
+                       } else {
+                               cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ?
+                                               LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD;
+                       }
+                       dispatch(cur, cmd);
+                       return;
                }
-               dispatch(cur, cmd);
-               return;
+               break;
 
        case LFUN_WORD_BACKWARD:
        case LFUN_WORD_BACKWARD_SELECT: