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);

Reply via email to