From: José Matox Date: Thu, 17 May 2007 21:53:11 +0000 (+0000) Subject: Fix a crash which occurs when RTL flag is turned on. X-Git-Tag: 1.6.10~9719 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=4729f795bc2e43f5123e589c94613fcf82a10d29;p=features.git Fix a crash which occurs when RTL flag is turned on. The crash was being caused by the fact that when moving back from the beginning of the line to the previous line (by pressing RIGHT in an RTL paragraph, or LEFT in an LTR one), Bidi metrics for the new line do not yet exist, but an attempt is made to access them. Basically, this patch was created by trying to "symmetrically" copy cursorRight (which seems to work well) to cursorLeft (which was problematic). git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18389 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/Text2.cpp b/src/Text2.cpp index e893889a29..88339ffad2 100644 --- a/src/Text2.cpp +++ b/src/Text2.cpp @@ -717,8 +717,12 @@ void Text::setCurrentFont(Cursor & cur) pos_type pos = cur.pos(); Paragraph & par = cur.paragraph(); - if (cur.boundary() && pos > 0) + if (cur.boundary() && pos > 0 && pos < cur.lastpos()) { --pos; + // We may have just moved to the previous row --- + // we're going to be needing its bidi tables! + bidi.computeTables(par, cur.buffer(), cur.textRow()); + } if (pos > 0) { if (pos == cur.lastpos()) @@ -904,9 +908,18 @@ bool Text::checkAndActivateInset(Cursor & cur, bool front) return false; if (cur.pos() == cur.lastpos()) return false; - Inset * inset = cur.nextInset(); + Inset * inset = front ? cur.nextInset() : cur.prevInset(); if (!isHighlyEditableInset(inset)) return false; + /* + * Apparently, when entering an inset we are expected to be positioned + * *before* it in the containing paragraph, regardless of the direction + * from which we are entering. Otherwise, cursor placement goes awry, + * and when we exit from the beginning, we'll be placed *after* the + * inset. + */ + if (!front) + --cur.pos(); inset->edit(cur, front); return true; } @@ -917,27 +930,35 @@ bool Text::cursorLeft(Cursor & cur) // Tell BufferView to test for FitCursor in any case! cur.updateFlags(Update::FitCursor); - if (!cur.boundary() && cur.pos() > 0 && - cur.textRow().pos() == cur.pos() && - !cur.paragraph().isLineSeparator(cur.pos()-1) && - !cur.paragraph().isNewline(cur.pos()-1)) { - return setCursor(cur, cur.pit(), cur.pos(), true, true); - } - if (cur.pos() != 0) { - bool updateNeeded = setCursor(cur, cur.pit(), cur.pos() - 1, true, false); + if (cur.pos() > 0) { + if (cur.boundary()) + return setCursor(cur, cur.pit(), cur.pos(), true, false); + + bool updateNeeded = false; + // If checkAndActivateInset returns true, that means that + // the cursor was placed inside it, so we're done if (!checkAndActivateInset(cur, false)) { - /** FIXME: What's this cause purpose??? - bool boundary = cur.boundary(); - if (false && !boundary && - bidi.isBoundary(cur.buffer(), cur.paragraph(), cur.pos() + 1)) - updateNeeded |= - setCursor(cur, cur.pit(), cur.pos() + 1, true, true); - */ + if (!cur.boundary() && + cur.textRow().pos() == cur.pos() + // FIXME: the following two conditions are copied + // from cursorRight; however, isLineSeparator() + // is definitely wrong here, isNewline I'm not sure + // about. I'm leaving them as comments for now, + // until we understand why they should or shouldn't + // be here. + /*&& + !cur.paragraph().isLineSeparator(cur.pos()-1) && + !cur.paragraph().isNewline(cur.pos() - 1)*/) { + updateNeeded |= setCursor(cur, cur.pit(), cur.pos(), + true, true); + } + updateNeeded |= setCursor(cur, cur.pit(),cur.pos() - 1, + true, false); } return updateNeeded; } - if (cur.pit() != 0) { + if (cur.pit() > 0) { // Steps into the paragraph above return setCursor(cur, cur.pit() - 1, getPar(cur.pit() - 1).size()); } @@ -956,6 +977,8 @@ bool Text::cursorRight(Cursor & cur) true, false); bool updateNeeded = false; + // If checkAndActivateInset returns true, that means that + // the cursor was placed inside it, so we're done if (!checkAndActivateInset(cur, true)) { if (cur.textRow().endpos() == cur.pos() + 1 && cur.textRow().endpos() != cur.lastpos() && @@ -964,9 +987,6 @@ bool Text::cursorRight(Cursor & cur) cur.boundary(true); } updateNeeded |= setCursor(cur, cur.pit(), cur.pos() + 1, true, cur.boundary()); - if (false && bidi.isBoundary(cur.buffer(), cur.paragraph(), - cur.pos())) - updateNeeded |= setCursor(cur, cur.pit(), cur.pos(), true, true); } return updateNeeded; }