From 8b5616664142ff0c6384afc18248ae4bf002caa8 Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Fri, 2 Feb 2007 03:10:15 +0000 Subject: [PATCH] Persistent-selection (and fix bug 3162) * src/CutAndPaste.h/C: add selectionBuffer to save selected text * src/text3.C: proper handling of paste * src/lyxfind.C: save selection * src/BufferView.C: save selection * src/text.C: save selection * src/cursor.C: save selection * src/insets/insettabular.C: save selection * src/mathed/InsetMathGrid.C: save selection * src/mathed/InsetMathHull.C: save selection * src/mathed/InsetMathNest.C: save selection git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17022 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView.C | 10 ++-- src/CutAndPaste.C | 94 ++++++++++++++++++++++++++++---------- src/CutAndPaste.h | 15 ++++-- src/cursor.C | 4 +- src/insets/insettabular.C | 21 +++++---- src/insets/insettabular.h | 2 +- src/lyxfind.C | 2 - src/mathed/InsetMathGrid.C | 1 - src/mathed/InsetMathHull.C | 1 - src/mathed/InsetMathNest.C | 16 ++++--- src/text.C | 3 +- src/text3.C | 78 ++++++++++++++++++++----------- 12 files changed, 167 insertions(+), 80 deletions(-) diff --git a/src/BufferView.C b/src/BufferView.C index 8771f0d2e5..a0da8a82d8 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -63,7 +63,6 @@ #include "frontends/Alert.h" #include "frontends/FileDialog.h" #include "frontends/FontMetrics.h" -#include "frontends/Selection.h" #include "graphics/Previews.h" @@ -209,7 +208,8 @@ void BufferView::setBuffer(Buffer * b) cursor_.resetAnchor(); cursor_.setCursor(buffer_->getCursor().asDocIterator(&(buffer_->inset()))); cursor_.setSelection(); - theSelection().haveSelection(cursor_.selection()); + // do not set selection to the new buffer because we + // only paste recent selection. } } @@ -1054,6 +1054,10 @@ void BufferView::clearSelection() { if (buffer_) { cursor_.clearSelection(); + // Clear the selection buffer. Otherwise a subsequent + // middle-mouse-button paste would use the selection buffer, + // not the more current external selection. + cap::clearSelection(); xsel_cache_.set = false; // The buffer did not really change, but this causes the // redraw we need because we cleared the selection above. @@ -1342,7 +1346,7 @@ void BufferView::putSelectionAt(DocIterator const & cur, cursor_.setSelection(cursor_, -length); } else cursor_.setSelection(cursor_, length); - theSelection().haveSelection(cursor_.selection()); + cap::saveSelection(cursor_); } } diff --git a/src/CutAndPaste.C b/src/CutAndPaste.C index ee7b2d2495..dcab51805b 100644 --- a/src/CutAndPaste.C +++ b/src/CutAndPaste.C @@ -73,6 +73,8 @@ typedef std::pair PitPosPair; typedef limited_stack > CutStack; CutStack theCuts(10); +// persistent selection, cleared until the next selection +CutStack selectionBuffer(1); // store whether the tabular stack is newer than the normal copy stack // FIXME: this is a workaround for bug 1919. Should be removed for 1.5, @@ -343,7 +345,7 @@ void putClipboard(ParagraphList const & paragraphs, textclass_type textclass, void copySelectionHelper(Buffer const & buf, ParagraphList & pars, pit_type startpit, pit_type endpit, - int start, int end, textclass_type tc) + int start, int end, textclass_type tc, CutStack & cutstack) { BOOST_ASSERT(0 <= start && start <= pars[startpit].size()); BOOST_ASSERT(0 <= end && end <= pars[endpit].size()); @@ -377,7 +379,7 @@ void copySelectionHelper(Buffer const & buf, ParagraphList & pars, // again, do not track deletion front.eraseChars(0, start, false); - theCuts.push(make_pair(paragraphs, tc)); + cutstack.push(make_pair(paragraphs, tc)); } } // namespace anon @@ -524,7 +526,7 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut) text->paragraphs(), begpit, endpit, cur.selBegin().pos(), endpos, - bp.textclass); + bp.textclass, theCuts); // Stuff what we got on the clipboard. // Even if there is no selection. putClipboard(theCuts[0].first, theCuts[0].second, @@ -580,16 +582,9 @@ void copySelection(LCursor & cur) } -void copySelection(LCursor & cur, docstring const & plaintext) -{ - copySelectionToStack(cur); - - // stuff the selection onto the X clipboard, from an explicit copy request - putClipboard(theCuts[0].first, theCuts[0].second, plaintext); -} - +namespace { -void copySelectionToStack(LCursor & cur) +void copySelectionToStack(LCursor & cur, CutStack & cutstack) { // this doesn't make sense, if there is no selection if (!cur.selection()) @@ -611,7 +606,7 @@ void copySelectionToStack(LCursor & cur) ++pos; copySelectionHelper(cur.buffer(), pars, par, cur.selEnd().pit(), - pos, cur.selEnd().pos(), cur.buffer().params().textclass); + pos, cur.selEnd().pos(), cur.buffer().params().textclass, cutstack); } if (cur.inMathed()) { @@ -622,10 +617,50 @@ void copySelectionToStack(LCursor & cur) par.layout(bp.getLyXTextClass().defaultLayout()); par.insert(0, grabSelection(cur), LyXFont(), Change(Change::UNCHANGED)); pars.push_back(par); - theCuts.push(make_pair(pars, bp.textclass)); + cutstack.push(make_pair(pars, bp.textclass)); } - // tell tabular that a recent copy happened - dirtyTabularStack(false); +} + +} + + +void copySelectionToStack() +{ + if (!selectionBuffer.empty()) + theCuts.push(selectionBuffer[0]); +} + + +void copySelection(LCursor & cur, docstring const & plaintext) +{ + copySelectionToStack(cur, theCuts); + + // stuff the selection onto the X clipboard, from an explicit copy request + putClipboard(theCuts[0].first, theCuts[0].second, plaintext); +} + + +void saveSelection(LCursor & cur) +{ + lyxerr[Debug::ACTION] << "cap::saveSelection: `" + << to_utf8(cur.selectionAsString(true)) << "'." << endl; + + if (cur.selection()) + copySelectionToStack(cur, selectionBuffer); + // tell X whether we now have a valid selection + theSelection().haveSelection(cur.selection()); +} + + +bool selection() +{ + return !selectionBuffer.empty(); +} + + +void clearSelection() +{ + selectionBuffer.clear(); } @@ -660,11 +695,25 @@ void pasteParagraphList(LCursor & cur, ParagraphList const & parlist, } +void pasteFromStack(LCursor & cur, ErrorList & errorList, size_t sel_index) +{ + // this does not make sense, if there is nothing to paste + if (!checkPastePossible(sel_index)) + return; + + recordUndo(cur); + pasteParagraphList(cur, theCuts[sel_index].first, + theCuts[sel_index].second, errorList); + cur.setSelection(); + saveSelection(cur); +} + + void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs) { // Use internal clipboard if it is the most recent one if (theClipboard().isInternal()) { - pasteSelection(cur, errorList, 0); + pasteClipboard(cur, errorList, 0); return; } @@ -696,15 +745,13 @@ void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs) } -void pasteSelection(LCursor & cur, ErrorList & errorList, size_t sel_index) +void pasteSelection(LCursor & cur, ErrorList & errorList) { - // this does not make sense, if there is nothing to paste - if (!checkPastePossible(sel_index)) + if (selectionBuffer.empty()) return; - recordUndo(cur); - pasteParagraphList(cur, theCuts[sel_index].first, - theCuts[sel_index].second, errorList); + pasteParagraphList(cur, selectionBuffer[0].first, + selectionBuffer[0].second, errorList); cur.setSelection(); } @@ -735,6 +782,7 @@ void replaceSelectionWithString(LCursor & cur, docstring const & str, bool backw cur.setSelection(selbeg, -int(str.length())); } else cur.setSelection(selbeg, str.length()); + saveSelection(cur); } diff --git a/src/CutAndPaste.h b/src/CutAndPaste.h index a07d04c118..329c2e72b5 100644 --- a/src/CutAndPaste.h +++ b/src/CutAndPaste.h @@ -68,15 +68,24 @@ void copySelection(LCursor & cur); * clipboard */ void copySelection(LCursor & cur, docstring const & plaintext); -/// Push the current selection to the cut buffer. -void copySelectionToStack(LCursor & cur); +/// Push the selection buffer to the cut buffer. +void copySelectionToStack(); +/// Store the current selection in the internal selection buffer +void saveSelection(LCursor & cur); +/// Is a selection available in our selection buffer? +bool selection(); +/// Clear our selection buffer +void clearSelection(); +/// Paste the current selection at \p cur +/// Does handle undo. Does only work in text, not mathed. +void pasteSelection(LCursor & cur, ErrorList &); /// Replace the current selection with the clipboard contents (internal or /// external: which is newer) /// Does handle undo. Does only work in text, not mathed. void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs = true); /// Replace the current selection with cut buffer \c sel_index /// Does handle undo. Does only work in text, not mathed. -void pasteSelection(LCursor & cur, ErrorList &, size_t sel_index = 0); +void pasteFromStack(LCursor & cur, ErrorList & errorList, size_t sel_index); /// Paste the paragraph list \p parlist at the position given by \p cur. /// Does not handle undo. Does only work in text, not mathed. diff --git a/src/cursor.C b/src/cursor.C index e9c4d75349..ad749e3aaa 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -41,8 +41,6 @@ #include "mathed/InsetMathScript.h" #include "mathed/MathMacroTable.h" -#include "frontends/Selection.h" - #include "support/limited_stack.h" #include @@ -560,7 +558,7 @@ bool LCursor::selHandle(bool sel) resetAnchor(); selection() = sel; - theSelection().haveSelection(sel); + cap::saveSelection(*this); return true; } diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index eeda178a56..9443fc17ef 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -50,6 +50,7 @@ namespace lyx { using cap::dirtyTabularStack; using cap::tabularStackDirty; +using cap::saveSelection; using graphics::PreviewLoader; @@ -501,12 +502,12 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) } if (cmd.button() == mouse_button::button2) { - if (bvcur.selection()) { + if (cap::selection()) { // See comment in LyXText::dispatch why we // do this // FIXME This does not use paste_tabular, // another reason why paste_tabular should go. - cap::copySelectionToStack(bvcur); + cap::copySelectionToStack(); cmd = FuncRequest(LFUN_PASTE, "0"); } else { cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, @@ -537,7 +538,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) //lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl; if (cmd.button() == mouse_button::button1) { if (bvcur.selection()) - theSelection().haveSelection(true); + saveSelection(bvcur);// theSelection().haveSelection(true); } else if (cmd.button() == mouse_button::button3) InsetTabularMailer(*this).showDialog(&cur.bv()); break; @@ -545,11 +546,13 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CELL_BACKWARD: movePrevCell(cur); cur.selection() = false; + saveSelection(cur); break; case LFUN_CELL_FORWARD: moveNextCell(cur); cur.selection() = false; + saveSelection(cur); break; case LFUN_CHAR_FORWARD_SELECT: @@ -558,7 +561,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) if (!cur.result().dispatched()) { isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur); if (cmd.action == LFUN_CHAR_FORWARD_SELECT) - theSelection().haveSelection(cur.selection()); + saveSelection(cur); if (sl == cur.top()) cmd = FuncRequest(LFUN_FINISHED_RIGHT); else @@ -572,7 +575,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) if (!cur.result().dispatched()) { isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur); if (cmd.action == LFUN_CHAR_BACKWARD_SELECT) - theSelection().haveSelection(cur.selection()); + saveSelection(cur); if (sl == cur.top()) cmd = FuncRequest(LFUN_FINISHED_LEFT); else @@ -595,7 +598,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) cur.bv().textMetrics(cell(cur.idx())->getText(0)); cur.pos() = tm.x2pos(cur.pit(), 0, cur.targetX()); if (cmd.action == LFUN_DOWN_SELECT) - theSelection().haveSelection(cur.selection()); + saveSelection(cur); } if (sl == cur.top()) { // we trick it to go to the RIGHT after leaving the @@ -622,7 +625,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) tm.parMetrics(cur.lastpit()); cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX()); if (cmd.action == LFUN_UP_SELECT) - theSelection().haveSelection(cur.selection()); + saveSelection(cur); } if (sl == cur.top()) { cmd = FuncRequest(LFUN_FINISHED_UP); @@ -746,7 +749,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) case LFUN_PASTE: if (tabularStackDirty() && theClipboard().isInternal()) { recordUndoInset(cur, Undo::INSERT); - pasteSelection(cur); + pasteClipboard(cur); break; } cell(cur.idx())->dispatch(cur, cmd); @@ -1823,7 +1826,7 @@ bool InsetTabular::copySelection(LCursor & cur) } -bool InsetTabular::pasteSelection(LCursor & cur) +bool InsetTabular::pasteClipboard(LCursor & cur) { if (!paste_tabular) return false; diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index c9e5c5c68d..2ab5d2f327 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -179,7 +179,7 @@ private: /// bool copySelection(LCursor & cur); /// - bool pasteSelection(LCursor & cur); + bool pasteClipboard(LCursor & cur); /// void cutSelection(LCursor & cur); /// diff --git a/src/lyxfind.C b/src/lyxfind.C index c223c65b37..932cbec30e 100644 --- a/src/lyxfind.C +++ b/src/lyxfind.C @@ -29,7 +29,6 @@ #include "undo.h" #include "frontends/Alert.h" -#include "frontends/Selection.h" #include "support/convert.h" #include "support/docstream.h" @@ -366,7 +365,6 @@ bool findNextChange(BufferView * bv) // Now put cursor to end of selection: bv->cursor().setCursor(cur); bv->cursor().setSelection(); - theSelection().haveSelection(bv->cursor().selection()); return true; } diff --git a/src/mathed/InsetMathGrid.C b/src/mathed/InsetMathGrid.C index 9d0a5ddd3c..aac42634d7 100644 --- a/src/mathed/InsetMathGrid.C +++ b/src/mathed/InsetMathGrid.C @@ -50,7 +50,6 @@ using std::istream; using std::istringstream; using std::vector; - class GridInsetMailer : public MailInset { public: GridInsetMailer(InsetMathGrid & inset) : inset_(inset) {} diff --git a/src/mathed/InsetMathHull.C b/src/mathed/InsetMathHull.C index 55a51dc0ff..09ac010b27 100644 --- a/src/mathed/InsetMathHull.C +++ b/src/mathed/InsetMathHull.C @@ -1400,7 +1400,6 @@ bool InsetMathHull::searchForward(BufferView * bv, string const & str, MathArray const & a = top.asInsetMath()->cell(top.idx_); if (a.matchpart(ar, top.pos_)) { bv->cursor().setSelection(it, ar.size()); - theSelection().haveSelection(bv->cursor().selection()); current = it; top.pos_ += ar.size(); bv->update(); diff --git a/src/mathed/InsetMathNest.C b/src/mathed/InsetMathNest.C index 40dae7ee17..8488363616 100644 --- a/src/mathed/InsetMathNest.C +++ b/src/mathed/InsetMathNest.C @@ -580,7 +580,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd) cur.selection() = true; cur.pos() = cur.lastpos(); cur.idx() = cur.lastidx(); - theSelection().haveSelection(true); + cap::saveSelection(cur); break; case LFUN_PARAGRAPH_UP: @@ -1151,10 +1151,11 @@ void InsetMathNest::lfunMousePress(LCursor & cur, FuncRequest & cmd) cur.updateFlags(Update::Decoration | Update::FitCursor); } else if (cmd.button() == mouse_button::button2) { MathArray ar; - if (cur.selection()) { + if (cap::selection()) { // See comment in LyXText::dispatch why we do this - cap::copySelectionToStack(bv.cursor()); - asArray(bv.cursor().selectionAsString(false), ar); + cap::copySelectionToStack(); + cmd = FuncRequest(LFUN_PASTE, "0"); + doDispatch(cur, cmd); } else asArray(theSelection().get(), ar); @@ -1185,10 +1186,13 @@ void InsetMathNest::lfunMouseRelease(LCursor & cur, FuncRequest & cmd) //lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl; if (cmd.button() == mouse_button::button1) { - if (cur.bv().cursor().selection()) - theSelection().haveSelection(true); if (!cur.selection()) cur.noUpdate(); + else { + LCursor & bvcur = cur.bv().cursor(); + bvcur.selection() = true; + cap::saveSelection(bvcur); + } return; } diff --git a/src/text.C b/src/text.C index ce9e710fa8..d30bdeb20f 100644 --- a/src/text.C +++ b/src/text.C @@ -53,7 +53,6 @@ #include "frontends/FontMetrics.h" #include "frontends/Painter.h" -#include "frontends/Selection.h" #include "insets/insettext.h" #include "insets/insetbibitem.h" @@ -829,7 +828,7 @@ void LyXText::selectWord(LCursor & cur, word_location loc) cur.resetAnchor(); setCursor(cur, to.pit(), to.pos()); cur.setSelection(); - theSelection().haveSelection(cur.selection()); + cap::saveSelection(cur); } diff --git a/src/text3.C b/src/text3.C index a6103ec59c..fe9c9cd784 100644 --- a/src/text3.C +++ b/src/text3.C @@ -76,9 +76,10 @@ namespace lyx { using cap::copySelection; using cap::cutSelection; +using cap::pasteFromStack; using cap::pasteClipboard; -using cap::pasteSelection; using cap::replaceSelection; +using cap::saveSelection; using support::isStrUnsignedInt; using support::token; @@ -122,7 +123,7 @@ namespace { { if (selecting || cur.mark()) cur.setSelection(); - theSelection().haveSelection(cur.selection()); + saveSelection(cur); cur.bv().switchKeyMap(); } @@ -138,7 +139,6 @@ namespace { { recordUndo(cur); docstring sel = cur.selectionAsString(false); - //lyxerr << "selection is: '" << sel << "'" << endl; // It may happen that sel is empty but there is a selection replaceSelection(cur); @@ -434,6 +434,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_RIGHT); } + if (cur.selection()) + saveSelection(cur); break; case LFUN_CHAR_BACKWARD: @@ -450,6 +452,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_LEFT); } + if (cur.selection()) + saveSelection(cur); break; case LFUN_UP: @@ -464,6 +468,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_UP); } + if (cur.selection()) + saveSelection(cur); break; case LFUN_DOWN: @@ -478,18 +484,24 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_DOWN); } + if (cur.selection()) + saveSelection(cur); break; case LFUN_PARAGRAPH_UP: case LFUN_PARAGRAPH_UP_SELECT: needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT); needsUpdate |= cursorUpParagraph(cur); + if (cur.selection()) + saveSelection(cur); break; case LFUN_PARAGRAPH_DOWN: case LFUN_PARAGRAPH_DOWN_SELECT: needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT); needsUpdate |= cursorDownParagraph(cur); + if (cur.selection()) + saveSelection(cur); break; case LFUN_SCREEN_UP: @@ -501,6 +513,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } else { cursorPrevious(cur); } + if (cur.selection()) + saveSelection(cur); break; case LFUN_SCREEN_DOWN: @@ -513,6 +527,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } else { cursorNext(cur); } + if (cur.selection()) + saveSelection(cur); break; case LFUN_LINE_BEGIN: @@ -525,6 +541,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_LINE_END_SELECT: needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT); needsUpdate |= cursorEnd(cur); + if (cur.selection()) + saveSelection(cur); break; case LFUN_WORD_FORWARD: @@ -534,6 +552,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) needsUpdate |= cursorLeftOneWord(cur); else needsUpdate |= cursorRightOneWord(cur); + if (cur.selection()) + saveSelection(cur); break; case LFUN_WORD_BACKWARD: @@ -543,6 +563,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) needsUpdate |= cursorRightOneWord(cur); else needsUpdate |= cursorLeftOneWord(cur); + if (cur.selection()) + saveSelection(cur); break; case LFUN_WORD_SELECT: { @@ -781,7 +803,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) pasteClipboard(cur, bv->buffer()->errorList("Paste")); else { string const arg(to_utf8(cmd.argument())); - pasteSelection(cur, bv->buffer()->errorList("Paste"), + pasteFromStack(cur, bv->buffer()->errorList("Paste"), isStrUnsignedInt(arg) ? convert(arg) : 0); @@ -960,7 +982,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cursorEnd(cur); cur.setSelection(); bv->cursor() = cur; - theSelection().haveSelection(cur.selection()); + saveSelection(cur); } break; @@ -968,7 +990,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) if (cmd.button() == mouse_button::button1) { selectWord(cur, WHOLE_WORD_STRICT); bv->cursor() = cur; - theSelection().haveSelection(cur.selection()); } break; @@ -983,15 +1004,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) // it could get cleared on the unlocking of the inset so // we have to check this first bool paste_internally = false; - if (cmd.button() == mouse_button::button2 && cur.selection()) { - // Copy the selection to the clipboard stack. This - // is done for two reasons: - // - We want it to appear in the "Edit->Paste recent" - // menu. - // - We can then use the normal copy/paste machinery - // instead of theSelection().get() to preserve - // formatting of the pasted stuff. - cap::copySelectionToStack(cur.bv().cursor()); + if (cmd.button() == mouse_button::button2 && cap::selection()) { + // Copy the selection buffer to the clipboard + // stack, because we want it to appear in the + // "Edit->Paste recent" menu. + cap::copySelectionToStack(); paste_internally = true; } @@ -1002,9 +1019,13 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) // if there is a local selection in the current buffer, // insert this if (cmd.button() == mouse_button::button2) { - if (paste_internally) - lyx::dispatch(FuncRequest(LFUN_PASTE, "0")); - else + if (paste_internally) { + cap::pasteSelection(cur, bv->buffer()->errorList("Paste")); + bv->buffer()->errors("Paste"); + cur.clearSelection(); // bug 393 + bv->switchKeyMap(); + finishUndo(); + } else lyx::dispatch(FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, "paragraph")); } @@ -1061,10 +1082,18 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) if (cmd.button() == mouse_button::button2) break; - // finish selection if (cmd.button() == mouse_button::button1) { - if (cur.selection()) - theSelection().haveSelection(true); + // if there is new selection, update persistent + // selection, otherwise, single click does not + // clear persistent selection buffer + if (cur.selection()) { + // finish selection + // if double click, cur is moved to the end of word by selectWord + // but bvcur is current mouse position + LCursor & bvcur = cur.bv().cursor(); + bvcur.selection() = true; + saveSelection(bvcur); + } needsUpdate = false; cur.noUpdate(); } @@ -1083,13 +1112,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) // "auto_region_delete", which defaults to // true (on). - if (lyxrc.auto_region_delete) { + if (lyxrc.auto_region_delete) if (cur.selection()) cutSelection(cur, false, false); - // cutSelection clears the X selection. - else - theSelection().haveSelection(false); - } cur.clearSelection(); LyXFont const old_font = real_current_font; @@ -1508,6 +1533,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_ESCAPE: if (cur.selection()) { cur.selection() = false; + saveSelection(cur); } else { cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_RIGHT); -- 2.39.2