visual mode for bidi cursor movement --- at the word-at-a-time level

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24602 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Dov Feldstern 2008-05-04 20:22:19 +00:00
parent ffda0d89b4
commit 553d896bb6
3 changed files with 118 additions and 16 deletions

View 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(), /**/);

View 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.

View 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: