Abdel: Attached are two patches. They all enable persistent selection and fixes 3877. 3877-Bo adds flag SaveSelection to all LFUN, and 3877-JM calls SaveSelection at selHandle, cutSelection, MOUSE_PRESS, and a few DELETE lfuncs. Both patches should have caught 99%, if not 100%, cases when selection needs to be saved. I have not tried to move selHandle to BufferView.
I personally like my solution and I guess JMarc likes his so your vote will put one of them in. :-) Cheers, Bo
Index: src/LyXAction.cpp =================================================================== --- src/LyXAction.cpp (revision 19002) +++ src/LyXAction.cpp (working copy) @@ -109,13 +109,13 @@ { LFUN_BREAK_PARAGRAPH_SKIP, "break-paragraph-skip", Noop }, { LFUN_BUILD_PROGRAM, "build-program", ReadOnly }, { LFUN_BUFFER_AUTO_SAVE, "buffer-auto-save", Noop }, - { LFUN_BUFFER_BEGIN, "buffer-begin", ReadOnly }, + { LFUN_BUFFER_BEGIN, "buffer-begin", ReadOnly | SaveSelection }, { LFUN_BUFFER_BEGIN_SELECT, "buffer-begin-select", ReadOnly }, { LFUN_BUFFER_CHILD_OPEN, "buffer-child-open", ReadOnly }, { LFUN_BUFFER_CHKTEX, "buffer-chktex", ReadOnly }, { LFUN_BUFFER_TOGGLE_COMPRESSION, "buffer-toggle-compression", Noop}, { LFUN_BUFFER_CLOSE, "buffer-close", ReadOnly }, - { LFUN_BUFFER_END, "buffer-end", ReadOnly }, + { LFUN_BUFFER_END, "buffer-end", ReadOnly | SaveSelection }, { LFUN_BUFFER_END_SELECT, "buffer-end-select", ReadOnly }, { LFUN_BUFFER_EXPORT, "buffer-export", ReadOnly }, { LFUN_BUFFER_EXPORT_CUSTOM, "buffer-export-custom", ReadOnly }, @@ -124,7 +124,7 @@ { LFUN_BUFFER_NEW, "buffer-new", NoBuffer }, { LFUN_BUFFER_NEW_TEMPLATE,"buffer-new-template", NoBuffer }, { LFUN_BUFFER_RELOAD, "buffer-reload", ReadOnly }, - { LFUN_BUFFER_SWITCH, "buffer-switch", ReadOnly }, + { LFUN_BUFFER_SWITCH, "buffer-switch", ReadOnly | SaveSelection }, { LFUN_BUFFER_TOGGLE_READ_ONLY, "buffer-toggle-read-only", ReadOnly }, { LFUN_BUFFER_UPDATE, "buffer-update", ReadOnly }, { LFUN_BUFFER_VIEW, "buffer-view", ReadOnly }, @@ -132,25 +132,25 @@ { LFUN_BUFFER_WRITE_AS, "buffer-write-as", ReadOnly }, { LFUN_CANCEL, "cancel", NoBuffer }, { LFUN_CAPTION_INSERT, "caption-insert", Noop }, - { LFUN_CHAR_BACKWARD, "char-backward", ReadOnly | NoUpdate}, + { LFUN_CHAR_BACKWARD, "char-backward", ReadOnly | NoUpdate | SaveSelection}, { LFUN_CHAR_BACKWARD_SELECT, "backward-select", ReadOnly | SingleParUpdate }, - { LFUN_CHAR_DELETE_BACKWARD, "delete-backward", SingleParUpdate }, - { LFUN_CHAR_DELETE_FORWARD, "delete-forward", SingleParUpdate }, - { LFUN_CHAR_FORWARD, "char-forward", ReadOnly | NoUpdate}, + { LFUN_CHAR_DELETE_BACKWARD, "delete-backward", SingleParUpdate | SaveSelection }, + { LFUN_CHAR_DELETE_FORWARD, "delete-forward", SingleParUpdate | SaveSelection }, + { LFUN_CHAR_FORWARD, "char-forward", ReadOnly | NoUpdate | SaveSelection}, { LFUN_CHAR_FORWARD_SELECT, "forward-select", ReadOnly | SingleParUpdate }, { LFUN_CLIPBOARD_PASTE, "clipboard-paste", Noop }, { LFUN_COMMAND_EXECUTE, "command-execute", NoBuffer }, { LFUN_COMMAND_PREFIX, "command-prefix", NoBuffer }, { LFUN_COMMAND_SEQUENCE, "command-sequence", NoBuffer }, { LFUN_COPY, "copy", ReadOnly }, - { LFUN_CUT, "cut", Noop }, + { LFUN_CUT, "cut", SaveSelection | SaveSelection }, { LFUN_DATE_INSERT, "date-insert", Noop }, - { LFUN_DELETE_BACKWARD_SKIP, "delete-backward-skip", Noop }, - { LFUN_DELETE_FORWARD_SKIP, "delete-forward-skip", Noop }, + { LFUN_DELETE_BACKWARD_SKIP, "delete-backward-skip", SaveSelection }, + { LFUN_DELETE_FORWARD_SKIP, "delete-forward-skip", SaveSelection }, { LFUN_DEPTH_DECREMENT, "depth-decrement", Noop }, { LFUN_DEPTH_INCREMENT, "depth-increment", Noop }, { LFUN_DOTS_INSERT, "dots-insert", Noop }, - { LFUN_DOWN, "down", ReadOnly | NoUpdate }, + { LFUN_DOWN, "down", ReadOnly | NoUpdate | SaveSelection }, { LFUN_DOWN_SELECT, "down-select", ReadOnly | SingleParUpdate }, { LFUN_DROP_LAYOUTS_CHOICE, "drop-layouts-choice", ReadOnly }, { LFUN_END_OF_SENTENCE_PERIOD_INSERT, "end-of-sentence-period-insert", Noop }, @@ -203,10 +203,10 @@ { LFUN_LAYOUT, "layout", Noop }, { LFUN_LAYOUT_PARAGRAPH, "layout-paragraph", ReadOnly }, { LFUN_LAYOUT_TABULAR, "layout-tabular", Noop }, - { LFUN_LINE_BEGIN, "line-begin", ReadOnly | NoUpdate}, + { LFUN_LINE_BEGIN, "line-begin", ReadOnly | NoUpdate | SaveSelection}, { LFUN_LINE_BEGIN_SELECT, "line-begin-select", ReadOnly | SingleParUpdate }, - { LFUN_LINE_DELETE, "line-delete-forward", Noop }, // there is no line-delete-backward - { LFUN_LINE_END, "line-end", ReadOnly | NoUpdate}, + { LFUN_LINE_DELETE, "line-delete-forward", SaveSelection }, // there is no line-delete-backward + { LFUN_LINE_END, "line-end", ReadOnly | NoUpdate | SaveSelection}, { LFUN_LINE_END_SELECT, "line-end-select", ReadOnly | SingleParUpdate }, #if 0 { LFUN_LIST_INSERT, "list-insert", Noop }, @@ -244,7 +244,7 @@ { LFUN_INSET_TOGGLE, "", ReadOnly }, { LFUN_NEXT_INSET_TOGGLE, "next-inset-toggle", ReadOnly }, { LFUN_ALL_INSETS_TOGGLE, "all-insets-toggle", ReadOnly }, - { LFUN_PARAGRAPH_DOWN, "paragraph-down", ReadOnly | NoUpdate}, + { LFUN_PARAGRAPH_DOWN, "paragraph-down", ReadOnly | NoUpdate | SaveSelection}, { LFUN_PARAGRAPH_DOWN_SELECT, "paragraph-down-select", ReadOnly }, { LFUN_PARAGRAPH_GOTO, "paragraph-goto", ReadOnly }, { LFUN_OUTLINE_UP, "outline-up", Noop }, @@ -252,7 +252,7 @@ { LFUN_OUTLINE_IN, "outline-in", Noop }, { LFUN_OUTLINE_OUT, "outline-out", Noop }, { LFUN_PARAGRAPH_SPACING, "paragraph-spacing", Noop }, - { LFUN_PARAGRAPH_UP, "paragraph-up", ReadOnly | NoUpdate}, + { LFUN_PARAGRAPH_UP, "paragraph-up", ReadOnly | NoUpdate | SaveSelection}, { LFUN_PARAGRAPH_UP_SELECT, "paragraph-up-select", ReadOnly }, { LFUN_PASTE, "paste", Noop }, { LFUN_PREFERENCES_SAVE, "preferences-save", NoBuffer }, @@ -262,11 +262,11 @@ { LFUN_REDO, "redo", Noop }, { LFUN_LABEL_GOTO, "label-goto", ReadOnly }, { LFUN_REFERENCE_NEXT, "reference-next", ReadOnly }, - { LFUN_SCREEN_DOWN, "screen-down", ReadOnly }, + { LFUN_SCREEN_DOWN, "screen-down", ReadOnly | SaveSelection }, { LFUN_SCREEN_DOWN_SELECT, "screen-down-select", ReadOnly }, { LFUN_SCREEN_FONT_UPDATE, "screen-font-update", NoBuffer }, { LFUN_SCREEN_RECENTER, "screen-recenter", ReadOnly }, - { LFUN_SCREEN_UP, "screen-up", ReadOnly }, + { LFUN_SCREEN_UP, "screen-up", ReadOnly | SaveSelection }, { LFUN_SCREEN_UP_SELECT, "screen-up-select", ReadOnly }, { LFUN_SELF_INSERT, "self-insert", SingleParUpdate }, { LFUN_SPACE_INSERT, "space-insert", Noop }, @@ -279,8 +279,8 @@ { LFUN_SERVER_NOTIFY, "server-notify", ReadOnly }, { LFUN_SERVER_SET_XY, "server-set-xy", ReadOnly }, { LFUN_SET_COLOR, "set-color", ReadOnly | NoBuffer }, - { LFUN_CELL_BACKWARD, "cell-backward", Noop }, - { LFUN_CELL_FORWARD, "cell-forward", Noop }, + { LFUN_CELL_BACKWARD, "cell-backward", SaveSelection }, + { LFUN_CELL_FORWARD, "cell-forward", SaveSelection }, { LFUN_CELL_SPLIT, "cell-split", Noop }, { LFUN_TABULAR_INSERT, "tabular-insert", Noop }, { LFUN_TABULAR_FEATURE, "tabular-feature", Noop }, @@ -291,7 +291,7 @@ { LFUN_TOC_INSERT, "toc-insert", Noop }, { LFUN_TOGGLE_CURSOR_FOLLOWS_SCROLLBAR, "toggle-cursor-follows-scrollbar", ReadOnly }, { LFUN_UNDO, "undo", Noop }, - { LFUN_UP, "up", ReadOnly | NoUpdate}, + { LFUN_UP, "up", ReadOnly | NoUpdate | SaveSelection}, { LFUN_UP_SELECT, "up-select", ReadOnly | SingleParUpdate }, { LFUN_URL_INSERT, "url-insert", Noop }, { LFUN_VC_CHECK_IN, "vc-check-in", ReadOnly }, @@ -299,14 +299,14 @@ { LFUN_VC_REGISTER, "vc-register", ReadOnly }, { LFUN_VC_REVERT, "vc-revert", ReadOnly }, { LFUN_VC_UNDO_LAST, "vc-undo-last", ReadOnly }, - { LFUN_WORD_BACKWARD, "word-backward", ReadOnly | NoUpdate}, + { LFUN_WORD_BACKWARD, "word-backward", ReadOnly | NoUpdate | SaveSelection}, { LFUN_WORD_BACKWARD_SELECT, "word-backward-select", ReadOnly | SingleParUpdate }, { LFUN_WORD_CAPITALIZE, "word-capitalize", Noop }, - { LFUN_WORD_DELETE_BACKWARD, "word-delete-backward", Noop }, - { LFUN_WORD_DELETE_FORWARD, "word-delete-forward", Noop }, + { LFUN_WORD_DELETE_BACKWARD, "word-delete-backward", SaveSelection }, + { LFUN_WORD_DELETE_FORWARD, "word-delete-forward", SaveSelection }, { LFUN_WORD_FIND_BACKWARD, "word-find-backward", ReadOnly }, { LFUN_WORD_FIND_FORWARD, "word-find-forward", ReadOnly }, - { LFUN_WORD_FORWARD, "word-forward", ReadOnly | NoUpdate}, + { LFUN_WORD_FORWARD, "word-forward", ReadOnly | NoUpdate | SaveSelection}, { LFUN_WORD_FORWARD_SELECT, "word-forward-select", ReadOnly | SingleParUpdate }, { LFUN_WORD_LOWCASE, "word-lowcase", Noop }, { LFUN_WORD_SELECT, "word-select", ReadOnly }, @@ -354,13 +354,13 @@ { LFUN_WORDS_COUNT, "words-count", ReadOnly }, { LFUN_FINISHED_RIGHT, "", ReadOnly }, { LFUN_FINISHED_LEFT, "", ReadOnly }, - { LFUN_MOUSE_PRESS, "", ReadOnly }, + { LFUN_MOUSE_PRESS, "", ReadOnly | SaveSelection }, { LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate }, { LFUN_MOUSE_RELEASE, "", ReadOnly }, { LFUN_MOUSE_DOUBLE, "", ReadOnly }, { LFUN_MOUSE_TRIPLE, "", ReadOnly }, - { LFUN_PARAGRAPH_MOVE_DOWN, "paragraph-move-down", Noop }, - { LFUN_PARAGRAPH_MOVE_UP, "paragraph-move-up", Noop }, + { LFUN_PARAGRAPH_MOVE_DOWN, "paragraph-move-down", SaveSelection }, + { LFUN_PARAGRAPH_MOVE_UP, "paragraph-move-up", SaveSelection }, { LFUN_WINDOW_NEW, "window-new", NoBuffer }, { LFUN_WINDOW_CLOSE, "window-close", NoBuffer }, { LFUN_UNICODE_INSERT, "unicode-insert", Noop }, Index: src/insets/InsetTabular.cpp =================================================================== --- src/insets/InsetTabular.cpp (revision 19003) +++ src/insets/InsetTabular.cpp (working copy) @@ -42,6 +42,7 @@ #include "paragraph_funcs.h" #include "ParagraphParameters.h" #include "Undo.h" +#include "LyXAction.h" #include "support/convert.h" #include "support/lstrings.h" @@ -3188,6 +3189,11 @@ CursorSlice sl = cur.top(); Cursor & bvcur = cur.bv().cursor(); + // if this LFUN will clear selection, saveSelection for persistent + // selection + if (lyxaction.funcHasFlag(cmd.action, LyXAction::SaveSelection)) + cap::saveSelection(bvcur); + switch (cmd.action) { case LFUN_MOUSE_PRESS: Index: src/LyXAction.h =================================================================== --- src/LyXAction.h (revision 19002) +++ src/LyXAction.h (working copy) @@ -55,7 +55,8 @@ NoBuffer = 2, //< Can be used when there is no document open Argument = 4, //< Requires argument NoUpdate = 8, //< Does not (usually) require update - SingleParUpdate = 16 //< Usually only requires this par updated + SingleParUpdate = 16, //< Usually only requires this par updated + SaveSelection = 32, //< This LFUN will clear current selection }; LyXAction(); Index: src/mathed/InsetMathNest.cpp =================================================================== --- src/mathed/InsetMathNest.cpp (revision 19003) +++ src/mathed/InsetMathNest.cpp (working copy) @@ -47,6 +47,7 @@ #include "Text.h" #include "OutputParams.h" #include "Undo.h" +#include "LyXAction.h" #include "support/lstrings.h" #include "support/textutils.h" @@ -442,6 +443,11 @@ //lyxerr << "InsetMathNest: request: " << cmd << std::endl; //CursorSlice sl = cur.current(); + // if this LFUN will clear selection, saveSelection for persistent + // selection + if (lyxaction.funcHasFlag(cmd.action, LyXAction::SaveSelection)) + cap::saveSelection(cur.bv().cursor()); + switch (cmd.action) { case LFUN_PASTE: { Index: src/Text3.cpp =================================================================== --- src/Text3.cpp (revision 19003) +++ src/Text3.cpp (working copy) @@ -369,6 +369,11 @@ cur.bottom().text(), cur.bottom().pit()); Dimension olddim = pm.dim(); + // if this LFUN will clear selection, saveSelection for persistent + // selection + if (lyxaction.funcHasFlag(cmd.action, LyXAction::SaveSelection)) + saveSelection(cur.bv().cursor()); + switch (cmd.action) { case LFUN_PARAGRAPH_MOVE_DOWN: {
Index: src/insets/InsetTabular.cpp =================================================================== --- src/insets/InsetTabular.cpp (revision 19003) +++ src/insets/InsetTabular.cpp (working copy) @@ -3191,6 +3191,9 @@ switch (cmd.action) { case LFUN_MOUSE_PRESS: + // this event will clear selection so we save selection + // for persistent selection + saveSelection(cur.bv().cursor()); //lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl; if (cmd.button() == mouse_button::button1 Index: src/mathed/InsetMathNest.cpp =================================================================== --- src/mathed/InsetMathNest.cpp (revision 19003) +++ src/mathed/InsetMathNest.cpp (working copy) @@ -67,6 +67,7 @@ using cap::cutSelection; using cap::replaceSelection; using cap::selClearOrDel; +using cap::saveSelection; using std::endl; using std::string; @@ -478,6 +479,9 @@ break; case LFUN_MOUSE_PRESS: + // this event will clear selection so we save selection + // for persistent selection + saveSelection(cur.bv().cursor()); lfunMousePress(cur, cmd); break; @@ -660,6 +664,9 @@ case LFUN_WORD_DELETE_BACKWARD: case LFUN_CHAR_DELETE_BACKWARD: + // this event will clear selection so we save selection + // for persistent selection + saveSelection(cur); if (cur.pos() == 0) // May affect external cell: recordUndoInset(cur, Undo::ATOMIC); @@ -674,6 +681,9 @@ case LFUN_WORD_DELETE_FORWARD: case LFUN_CHAR_DELETE_FORWARD: + // this event will clear selection so we save selection + // for persistent selection + saveSelection(cur); if (cur.pos() == cur.lastpos()) // May affect external cell: recordUndoInset(cur, Undo::ATOMIC); Index: src/CutAndPaste.cpp =================================================================== --- src/CutAndPaste.cpp (revision 19003) +++ src/CutAndPaste.cpp (working copy) @@ -517,6 +517,9 @@ if (!cur.selection()) return; + // save selection for persistent selection + saveSelection(cur); + // OK, we have a selection. This is always between cur.selBegin() // and cur.selEnd() Index: src/Text3.cpp =================================================================== --- src/Text3.cpp (revision 19003) +++ src/Text3.cpp (working copy) @@ -1024,6 +1024,9 @@ // Single-click on work area case LFUN_MOUSE_PRESS: { + // this event will clear selection so we save selection + // for persistent selection + saveSelection(cur.bv().cursor()); // Right click on a footnote flag opens float menu if (cmd.button() == mouse_button::button3) cur.clearSelection(); Index: src/Cursor.cpp =================================================================== --- src/Cursor.cpp (revision 19002) +++ src/Cursor.cpp (working copy) @@ -588,6 +588,9 @@ if (sel == selection()) return false; + if (!sel) + cap::saveSelection(*this); + resetAnchor(); selection() = sel; cap::saveSelection(*this);