diff --git a/src/Text.cpp b/src/Text.cpp index dde070405f..91b8a5f02a 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -757,6 +757,25 @@ void Text::selectWord(Cursor & cur, word_location loc) } +void Text::selectAll(Cursor & cur) +{ + LASSERT(this == cur.text(), /**/); + if (cur.lastpos() == 0 && cur.lastpit() == 0) + return; + // If the cursor is at the beginning, make sure the cursor ends there + if (cur.pit() == 0 && cur.pos() == 0) { + setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size()); + cur.resetAnchor(); + setCursor(cur, 0, 0); + } else { + setCursor(cur, 0, 0); + cur.resetAnchor(); + setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size()); + } + cur.setSelection(); +} + + // Select the word currently under the cursor when no // selection is currently set bool Text::selectWordWhenUnderCursor(Cursor & cur, word_location loc) diff --git a/src/Text.h b/src/Text.h index 3beda155a5..df19ca7ae2 100644 --- a/src/Text.h +++ b/src/Text.h @@ -149,6 +149,8 @@ public: void getWord(CursorSlice & from, CursorSlice & to, word_location const) const; /// just selects the word the cursor is in void selectWord(Cursor & cur, word_location loc); + /// select all text + void selectAll(Cursor & cur); /// convenience function get the previous word or an empty string docstring previousWord(CursorSlice const & sl) const; diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index 6e871a6098..e518ce3430 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -3401,18 +3401,43 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) finish_lfun = right ? LFUN_FINISHED_RIGHT : LFUN_FINISHED_LEFT; } - // if we don't have a multicell selection... - if (!cur.selIsMultiCell() || - // ...or we're not doing some LFUN_*_SELECT thing, anyway... - (cmd.action != LFUN_CHAR_FORWARD_SELECT && - cmd.action != LFUN_CHAR_BACKWARD_SELECT && - cmd.action != LFUN_CHAR_RIGHT_SELECT && - cmd.action != LFUN_CHAR_LEFT_SELECT)) { + bool const select = cmd.action == LFUN_CHAR_FORWARD_SELECT || + cmd.action == LFUN_CHAR_BACKWARD_SELECT || + cmd.action == LFUN_CHAR_RIGHT_SELECT || + cmd.action == LFUN_CHAR_LEFT_SELECT; + + // If we have a multicell selection or we're + // not doing some LFUN_*_SELECT thing anyway... + if (!cur.selIsMultiCell() || !select) { + col_type const c = tabular.cellColumn(cur.idx()); + row_type const r = tabular.cellRow(cur.idx()); + // Are we trying to select the whole cell and is the whole cell + // not yet selected? + bool const select_whole = select && !isCellSelected(cur, r, c) && + ((next_cell && cur.pit() == cur.lastpit() + && cur.pos() == cur.lastpos()) + || (!next_cell && cur.pit() == 0 && cur.pos() == 0)); + // ...try to dispatch to the cell's inset. cell(cur.idx())->dispatch(cur, cmd); - if (cur.result().dispatched()) + + bool const empty_cell = cur.lastpos() == 0 && cur.lastpit() == 0; + + // When we already have a selection we want to select the whole cell + // before going to the next cell. + if (select_whole && !empty_cell){ + getText(cur.idx())->selectAll(cur); + cur.dispatched(); + break; + } + + // FIXME: When we support the selection of an empty cell, remove + // the !empty_cell from this condition. For now we jump to the next + // cell if the current cell is empty. + if (cur.result().dispatched() && !empty_cell) break; } + // move to next/prev cell, as appropriate // note that we will always do this if we're selecting and we have // a multicell selection