mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
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
This commit is contained in:
parent
f44bc0a0d1
commit
8b56166641
@ -63,7 +63,6 @@
|
|||||||
#include "frontends/Alert.h"
|
#include "frontends/Alert.h"
|
||||||
#include "frontends/FileDialog.h"
|
#include "frontends/FileDialog.h"
|
||||||
#include "frontends/FontMetrics.h"
|
#include "frontends/FontMetrics.h"
|
||||||
#include "frontends/Selection.h"
|
|
||||||
|
|
||||||
#include "graphics/Previews.h"
|
#include "graphics/Previews.h"
|
||||||
|
|
||||||
@ -209,7 +208,8 @@ void BufferView::setBuffer(Buffer * b)
|
|||||||
cursor_.resetAnchor();
|
cursor_.resetAnchor();
|
||||||
cursor_.setCursor(buffer_->getCursor().asDocIterator(&(buffer_->inset())));
|
cursor_.setCursor(buffer_->getCursor().asDocIterator(&(buffer_->inset())));
|
||||||
cursor_.setSelection();
|
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_) {
|
if (buffer_) {
|
||||||
cursor_.clearSelection();
|
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;
|
xsel_cache_.set = false;
|
||||||
// The buffer did not really change, but this causes the
|
// The buffer did not really change, but this causes the
|
||||||
// redraw we need because we cleared the selection above.
|
// redraw we need because we cleared the selection above.
|
||||||
@ -1342,7 +1346,7 @@ void BufferView::putSelectionAt(DocIterator const & cur,
|
|||||||
cursor_.setSelection(cursor_, -length);
|
cursor_.setSelection(cursor_, -length);
|
||||||
} else
|
} else
|
||||||
cursor_.setSelection(cursor_, length);
|
cursor_.setSelection(cursor_, length);
|
||||||
theSelection().haveSelection(cursor_.selection());
|
cap::saveSelection(cursor_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@ typedef std::pair<pit_type, int> PitPosPair;
|
|||||||
typedef limited_stack<pair<ParagraphList, textclass_type> > CutStack;
|
typedef limited_stack<pair<ParagraphList, textclass_type> > CutStack;
|
||||||
|
|
||||||
CutStack theCuts(10);
|
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
|
// 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,
|
// 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,
|
void copySelectionHelper(Buffer const & buf, ParagraphList & pars,
|
||||||
pit_type startpit, pit_type endpit,
|
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 <= start && start <= pars[startpit].size());
|
||||||
BOOST_ASSERT(0 <= end && end <= pars[endpit].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
|
// again, do not track deletion
|
||||||
front.eraseChars(0, start, false);
|
front.eraseChars(0, start, false);
|
||||||
|
|
||||||
theCuts.push(make_pair(paragraphs, tc));
|
cutstack.push(make_pair(paragraphs, tc));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace anon
|
} // namespace anon
|
||||||
@ -524,7 +526,7 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut)
|
|||||||
text->paragraphs(),
|
text->paragraphs(),
|
||||||
begpit, endpit,
|
begpit, endpit,
|
||||||
cur.selBegin().pos(), endpos,
|
cur.selBegin().pos(), endpos,
|
||||||
bp.textclass);
|
bp.textclass, theCuts);
|
||||||
// Stuff what we got on the clipboard.
|
// Stuff what we got on the clipboard.
|
||||||
// Even if there is no selection.
|
// Even if there is no selection.
|
||||||
putClipboard(theCuts[0].first, theCuts[0].second,
|
putClipboard(theCuts[0].first, theCuts[0].second,
|
||||||
@ -580,16 +582,9 @@ void copySelection(LCursor & cur)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void copySelection(LCursor & cur, docstring const & plaintext)
|
namespace {
|
||||||
{
|
|
||||||
copySelectionToStack(cur);
|
|
||||||
|
|
||||||
// stuff the selection onto the X clipboard, from an explicit copy request
|
void copySelectionToStack(LCursor & cur, CutStack & cutstack)
|
||||||
putClipboard(theCuts[0].first, theCuts[0].second, plaintext);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void copySelectionToStack(LCursor & cur)
|
|
||||||
{
|
{
|
||||||
// this doesn't make sense, if there is no selection
|
// this doesn't make sense, if there is no selection
|
||||||
if (!cur.selection())
|
if (!cur.selection())
|
||||||
@ -611,7 +606,7 @@ void copySelectionToStack(LCursor & cur)
|
|||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
copySelectionHelper(cur.buffer(), pars, par, cur.selEnd().pit(),
|
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()) {
|
if (cur.inMathed()) {
|
||||||
@ -622,10 +617,50 @@ void copySelectionToStack(LCursor & cur)
|
|||||||
par.layout(bp.getLyXTextClass().defaultLayout());
|
par.layout(bp.getLyXTextClass().defaultLayout());
|
||||||
par.insert(0, grabSelection(cur), LyXFont(), Change(Change::UNCHANGED));
|
par.insert(0, grabSelection(cur), LyXFont(), Change(Change::UNCHANGED));
|
||||||
pars.push_back(par);
|
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)
|
void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs)
|
||||||
{
|
{
|
||||||
// Use internal clipboard if it is the most recent one
|
// Use internal clipboard if it is the most recent one
|
||||||
if (theClipboard().isInternal()) {
|
if (theClipboard().isInternal()) {
|
||||||
pasteSelection(cur, errorList, 0);
|
pasteClipboard(cur, errorList, 0);
|
||||||
return;
|
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 (selectionBuffer.empty())
|
||||||
if (!checkPastePossible(sel_index))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
recordUndo(cur);
|
recordUndo(cur);
|
||||||
pasteParagraphList(cur, theCuts[sel_index].first,
|
pasteParagraphList(cur, selectionBuffer[0].first,
|
||||||
theCuts[sel_index].second, errorList);
|
selectionBuffer[0].second, errorList);
|
||||||
cur.setSelection();
|
cur.setSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,6 +782,7 @@ void replaceSelectionWithString(LCursor & cur, docstring const & str, bool backw
|
|||||||
cur.setSelection(selbeg, -int(str.length()));
|
cur.setSelection(selbeg, -int(str.length()));
|
||||||
} else
|
} else
|
||||||
cur.setSelection(selbeg, str.length());
|
cur.setSelection(selbeg, str.length());
|
||||||
|
saveSelection(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,15 +68,24 @@ void copySelection(LCursor & cur);
|
|||||||
* clipboard
|
* clipboard
|
||||||
*/
|
*/
|
||||||
void copySelection(LCursor & cur, docstring const & plaintext);
|
void copySelection(LCursor & cur, docstring const & plaintext);
|
||||||
/// Push the current selection to the cut buffer.
|
/// Push the selection buffer to the cut buffer.
|
||||||
void copySelectionToStack(LCursor & cur);
|
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
|
/// Replace the current selection with the clipboard contents (internal or
|
||||||
/// external: which is newer)
|
/// external: which is newer)
|
||||||
/// Does handle undo. Does only work in text, not mathed.
|
/// Does handle undo. Does only work in text, not mathed.
|
||||||
void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs = true);
|
void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs = true);
|
||||||
/// Replace the current selection with cut buffer \c sel_index
|
/// Replace the current selection with cut buffer \c sel_index
|
||||||
/// Does handle undo. Does only work in text, not mathed.
|
/// 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.
|
/// Paste the paragraph list \p parlist at the position given by \p cur.
|
||||||
/// Does not handle undo. Does only work in text, not mathed.
|
/// Does not handle undo. Does only work in text, not mathed.
|
||||||
|
@ -41,8 +41,6 @@
|
|||||||
#include "mathed/InsetMathScript.h"
|
#include "mathed/InsetMathScript.h"
|
||||||
#include "mathed/MathMacroTable.h"
|
#include "mathed/MathMacroTable.h"
|
||||||
|
|
||||||
#include "frontends/Selection.h"
|
|
||||||
|
|
||||||
#include "support/limited_stack.h"
|
#include "support/limited_stack.h"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
@ -560,7 +558,7 @@ bool LCursor::selHandle(bool sel)
|
|||||||
|
|
||||||
resetAnchor();
|
resetAnchor();
|
||||||
selection() = sel;
|
selection() = sel;
|
||||||
theSelection().haveSelection(sel);
|
cap::saveSelection(*this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ namespace lyx {
|
|||||||
|
|
||||||
using cap::dirtyTabularStack;
|
using cap::dirtyTabularStack;
|
||||||
using cap::tabularStackDirty;
|
using cap::tabularStackDirty;
|
||||||
|
using cap::saveSelection;
|
||||||
|
|
||||||
using graphics::PreviewLoader;
|
using graphics::PreviewLoader;
|
||||||
|
|
||||||
@ -501,12 +502,12 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.button() == mouse_button::button2) {
|
if (cmd.button() == mouse_button::button2) {
|
||||||
if (bvcur.selection()) {
|
if (cap::selection()) {
|
||||||
// See comment in LyXText::dispatch why we
|
// See comment in LyXText::dispatch why we
|
||||||
// do this
|
// do this
|
||||||
// FIXME This does not use paste_tabular,
|
// FIXME This does not use paste_tabular,
|
||||||
// another reason why paste_tabular should go.
|
// another reason why paste_tabular should go.
|
||||||
cap::copySelectionToStack(bvcur);
|
cap::copySelectionToStack();
|
||||||
cmd = FuncRequest(LFUN_PASTE, "0");
|
cmd = FuncRequest(LFUN_PASTE, "0");
|
||||||
} else {
|
} else {
|
||||||
cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE,
|
cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE,
|
||||||
@ -537,7 +538,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
//lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl;
|
//lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl;
|
||||||
if (cmd.button() == mouse_button::button1) {
|
if (cmd.button() == mouse_button::button1) {
|
||||||
if (bvcur.selection())
|
if (bvcur.selection())
|
||||||
theSelection().haveSelection(true);
|
saveSelection(bvcur);// theSelection().haveSelection(true);
|
||||||
} else if (cmd.button() == mouse_button::button3)
|
} else if (cmd.button() == mouse_button::button3)
|
||||||
InsetTabularMailer(*this).showDialog(&cur.bv());
|
InsetTabularMailer(*this).showDialog(&cur.bv());
|
||||||
break;
|
break;
|
||||||
@ -545,11 +546,13 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
case LFUN_CELL_BACKWARD:
|
case LFUN_CELL_BACKWARD:
|
||||||
movePrevCell(cur);
|
movePrevCell(cur);
|
||||||
cur.selection() = false;
|
cur.selection() = false;
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_CELL_FORWARD:
|
case LFUN_CELL_FORWARD:
|
||||||
moveNextCell(cur);
|
moveNextCell(cur);
|
||||||
cur.selection() = false;
|
cur.selection() = false;
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_CHAR_FORWARD_SELECT:
|
case LFUN_CHAR_FORWARD_SELECT:
|
||||||
@ -558,7 +561,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
if (!cur.result().dispatched()) {
|
if (!cur.result().dispatched()) {
|
||||||
isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur);
|
isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur);
|
||||||
if (cmd.action == LFUN_CHAR_FORWARD_SELECT)
|
if (cmd.action == LFUN_CHAR_FORWARD_SELECT)
|
||||||
theSelection().haveSelection(cur.selection());
|
saveSelection(cur);
|
||||||
if (sl == cur.top())
|
if (sl == cur.top())
|
||||||
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
||||||
else
|
else
|
||||||
@ -572,7 +575,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
if (!cur.result().dispatched()) {
|
if (!cur.result().dispatched()) {
|
||||||
isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur);
|
isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur);
|
||||||
if (cmd.action == LFUN_CHAR_BACKWARD_SELECT)
|
if (cmd.action == LFUN_CHAR_BACKWARD_SELECT)
|
||||||
theSelection().haveSelection(cur.selection());
|
saveSelection(cur);
|
||||||
if (sl == cur.top())
|
if (sl == cur.top())
|
||||||
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
||||||
else
|
else
|
||||||
@ -595,7 +598,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.bv().textMetrics(cell(cur.idx())->getText(0));
|
cur.bv().textMetrics(cell(cur.idx())->getText(0));
|
||||||
cur.pos() = tm.x2pos(cur.pit(), 0, cur.targetX());
|
cur.pos() = tm.x2pos(cur.pit(), 0, cur.targetX());
|
||||||
if (cmd.action == LFUN_DOWN_SELECT)
|
if (cmd.action == LFUN_DOWN_SELECT)
|
||||||
theSelection().haveSelection(cur.selection());
|
saveSelection(cur);
|
||||||
}
|
}
|
||||||
if (sl == cur.top()) {
|
if (sl == cur.top()) {
|
||||||
// we trick it to go to the RIGHT after leaving the
|
// 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());
|
tm.parMetrics(cur.lastpit());
|
||||||
cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
|
cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
|
||||||
if (cmd.action == LFUN_UP_SELECT)
|
if (cmd.action == LFUN_UP_SELECT)
|
||||||
theSelection().haveSelection(cur.selection());
|
saveSelection(cur);
|
||||||
}
|
}
|
||||||
if (sl == cur.top()) {
|
if (sl == cur.top()) {
|
||||||
cmd = FuncRequest(LFUN_FINISHED_UP);
|
cmd = FuncRequest(LFUN_FINISHED_UP);
|
||||||
@ -746,7 +749,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
case LFUN_PASTE:
|
case LFUN_PASTE:
|
||||||
if (tabularStackDirty() && theClipboard().isInternal()) {
|
if (tabularStackDirty() && theClipboard().isInternal()) {
|
||||||
recordUndoInset(cur, Undo::INSERT);
|
recordUndoInset(cur, Undo::INSERT);
|
||||||
pasteSelection(cur);
|
pasteClipboard(cur);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cell(cur.idx())->dispatch(cur, cmd);
|
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)
|
if (!paste_tabular)
|
||||||
return false;
|
return false;
|
||||||
|
@ -179,7 +179,7 @@ private:
|
|||||||
///
|
///
|
||||||
bool copySelection(LCursor & cur);
|
bool copySelection(LCursor & cur);
|
||||||
///
|
///
|
||||||
bool pasteSelection(LCursor & cur);
|
bool pasteClipboard(LCursor & cur);
|
||||||
///
|
///
|
||||||
void cutSelection(LCursor & cur);
|
void cutSelection(LCursor & cur);
|
||||||
///
|
///
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include "undo.h"
|
#include "undo.h"
|
||||||
|
|
||||||
#include "frontends/Alert.h"
|
#include "frontends/Alert.h"
|
||||||
#include "frontends/Selection.h"
|
|
||||||
|
|
||||||
#include "support/convert.h"
|
#include "support/convert.h"
|
||||||
#include "support/docstream.h"
|
#include "support/docstream.h"
|
||||||
@ -366,7 +365,6 @@ bool findNextChange(BufferView * bv)
|
|||||||
// Now put cursor to end of selection:
|
// Now put cursor to end of selection:
|
||||||
bv->cursor().setCursor(cur);
|
bv->cursor().setCursor(cur);
|
||||||
bv->cursor().setSelection();
|
bv->cursor().setSelection();
|
||||||
theSelection().haveSelection(bv->cursor().selection());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ using std::istream;
|
|||||||
using std::istringstream;
|
using std::istringstream;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
|
|
||||||
class GridInsetMailer : public MailInset {
|
class GridInsetMailer : public MailInset {
|
||||||
public:
|
public:
|
||||||
GridInsetMailer(InsetMathGrid & inset) : inset_(inset) {}
|
GridInsetMailer(InsetMathGrid & inset) : inset_(inset) {}
|
||||||
|
@ -1400,7 +1400,6 @@ bool InsetMathHull::searchForward(BufferView * bv, string const & str,
|
|||||||
MathArray const & a = top.asInsetMath()->cell(top.idx_);
|
MathArray const & a = top.asInsetMath()->cell(top.idx_);
|
||||||
if (a.matchpart(ar, top.pos_)) {
|
if (a.matchpart(ar, top.pos_)) {
|
||||||
bv->cursor().setSelection(it, ar.size());
|
bv->cursor().setSelection(it, ar.size());
|
||||||
theSelection().haveSelection(bv->cursor().selection());
|
|
||||||
current = it;
|
current = it;
|
||||||
top.pos_ += ar.size();
|
top.pos_ += ar.size();
|
||||||
bv->update();
|
bv->update();
|
||||||
|
@ -580,7 +580,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.selection() = true;
|
cur.selection() = true;
|
||||||
cur.pos() = cur.lastpos();
|
cur.pos() = cur.lastpos();
|
||||||
cur.idx() = cur.lastidx();
|
cur.idx() = cur.lastidx();
|
||||||
theSelection().haveSelection(true);
|
cap::saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_PARAGRAPH_UP:
|
case LFUN_PARAGRAPH_UP:
|
||||||
@ -1151,10 +1151,11 @@ void InsetMathNest::lfunMousePress(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.updateFlags(Update::Decoration | Update::FitCursor);
|
cur.updateFlags(Update::Decoration | Update::FitCursor);
|
||||||
} else if (cmd.button() == mouse_button::button2) {
|
} else if (cmd.button() == mouse_button::button2) {
|
||||||
MathArray ar;
|
MathArray ar;
|
||||||
if (cur.selection()) {
|
if (cap::selection()) {
|
||||||
// See comment in LyXText::dispatch why we do this
|
// See comment in LyXText::dispatch why we do this
|
||||||
cap::copySelectionToStack(bv.cursor());
|
cap::copySelectionToStack();
|
||||||
asArray(bv.cursor().selectionAsString(false), ar);
|
cmd = FuncRequest(LFUN_PASTE, "0");
|
||||||
|
doDispatch(cur, cmd);
|
||||||
} else
|
} else
|
||||||
asArray(theSelection().get(), ar);
|
asArray(theSelection().get(), ar);
|
||||||
|
|
||||||
@ -1185,10 +1186,13 @@ void InsetMathNest::lfunMouseRelease(LCursor & cur, FuncRequest & cmd)
|
|||||||
//lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl;
|
//lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl;
|
||||||
|
|
||||||
if (cmd.button() == mouse_button::button1) {
|
if (cmd.button() == mouse_button::button1) {
|
||||||
if (cur.bv().cursor().selection())
|
|
||||||
theSelection().haveSelection(true);
|
|
||||||
if (!cur.selection())
|
if (!cur.selection())
|
||||||
cur.noUpdate();
|
cur.noUpdate();
|
||||||
|
else {
|
||||||
|
LCursor & bvcur = cur.bv().cursor();
|
||||||
|
bvcur.selection() = true;
|
||||||
|
cap::saveSelection(bvcur);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
|
|
||||||
#include "frontends/FontMetrics.h"
|
#include "frontends/FontMetrics.h"
|
||||||
#include "frontends/Painter.h"
|
#include "frontends/Painter.h"
|
||||||
#include "frontends/Selection.h"
|
|
||||||
|
|
||||||
#include "insets/insettext.h"
|
#include "insets/insettext.h"
|
||||||
#include "insets/insetbibitem.h"
|
#include "insets/insetbibitem.h"
|
||||||
@ -829,7 +828,7 @@ void LyXText::selectWord(LCursor & cur, word_location loc)
|
|||||||
cur.resetAnchor();
|
cur.resetAnchor();
|
||||||
setCursor(cur, to.pit(), to.pos());
|
setCursor(cur, to.pit(), to.pos());
|
||||||
cur.setSelection();
|
cur.setSelection();
|
||||||
theSelection().haveSelection(cur.selection());
|
cap::saveSelection(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
78
src/text3.C
78
src/text3.C
@ -76,9 +76,10 @@ namespace lyx {
|
|||||||
|
|
||||||
using cap::copySelection;
|
using cap::copySelection;
|
||||||
using cap::cutSelection;
|
using cap::cutSelection;
|
||||||
|
using cap::pasteFromStack;
|
||||||
using cap::pasteClipboard;
|
using cap::pasteClipboard;
|
||||||
using cap::pasteSelection;
|
|
||||||
using cap::replaceSelection;
|
using cap::replaceSelection;
|
||||||
|
using cap::saveSelection;
|
||||||
|
|
||||||
using support::isStrUnsignedInt;
|
using support::isStrUnsignedInt;
|
||||||
using support::token;
|
using support::token;
|
||||||
@ -122,7 +123,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
if (selecting || cur.mark())
|
if (selecting || cur.mark())
|
||||||
cur.setSelection();
|
cur.setSelection();
|
||||||
theSelection().haveSelection(cur.selection());
|
saveSelection(cur);
|
||||||
cur.bv().switchKeyMap();
|
cur.bv().switchKeyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +139,6 @@ namespace {
|
|||||||
{
|
{
|
||||||
recordUndo(cur);
|
recordUndo(cur);
|
||||||
docstring sel = cur.selectionAsString(false);
|
docstring sel = cur.selectionAsString(false);
|
||||||
//lyxerr << "selection is: '" << sel << "'" << endl;
|
|
||||||
|
|
||||||
// It may happen that sel is empty but there is a selection
|
// It may happen that sel is empty but there is a selection
|
||||||
replaceSelection(cur);
|
replaceSelection(cur);
|
||||||
@ -434,6 +434,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.undispatched();
|
cur.undispatched();
|
||||||
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
||||||
}
|
}
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_CHAR_BACKWARD:
|
case LFUN_CHAR_BACKWARD:
|
||||||
@ -450,6 +452,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.undispatched();
|
cur.undispatched();
|
||||||
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
||||||
}
|
}
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_UP:
|
case LFUN_UP:
|
||||||
@ -464,6 +468,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.undispatched();
|
cur.undispatched();
|
||||||
cmd = FuncRequest(LFUN_FINISHED_UP);
|
cmd = FuncRequest(LFUN_FINISHED_UP);
|
||||||
}
|
}
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_DOWN:
|
case LFUN_DOWN:
|
||||||
@ -478,18 +484,24 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cur.undispatched();
|
cur.undispatched();
|
||||||
cmd = FuncRequest(LFUN_FINISHED_DOWN);
|
cmd = FuncRequest(LFUN_FINISHED_DOWN);
|
||||||
}
|
}
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_PARAGRAPH_UP:
|
case LFUN_PARAGRAPH_UP:
|
||||||
case LFUN_PARAGRAPH_UP_SELECT:
|
case LFUN_PARAGRAPH_UP_SELECT:
|
||||||
needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT);
|
needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT);
|
||||||
needsUpdate |= cursorUpParagraph(cur);
|
needsUpdate |= cursorUpParagraph(cur);
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_PARAGRAPH_DOWN:
|
case LFUN_PARAGRAPH_DOWN:
|
||||||
case LFUN_PARAGRAPH_DOWN_SELECT:
|
case LFUN_PARAGRAPH_DOWN_SELECT:
|
||||||
needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT);
|
needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT);
|
||||||
needsUpdate |= cursorDownParagraph(cur);
|
needsUpdate |= cursorDownParagraph(cur);
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_SCREEN_UP:
|
case LFUN_SCREEN_UP:
|
||||||
@ -501,6 +513,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
} else {
|
} else {
|
||||||
cursorPrevious(cur);
|
cursorPrevious(cur);
|
||||||
}
|
}
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_SCREEN_DOWN:
|
case LFUN_SCREEN_DOWN:
|
||||||
@ -513,6 +527,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
} else {
|
} else {
|
||||||
cursorNext(cur);
|
cursorNext(cur);
|
||||||
}
|
}
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_LINE_BEGIN:
|
case LFUN_LINE_BEGIN:
|
||||||
@ -525,6 +541,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
case LFUN_LINE_END_SELECT:
|
case LFUN_LINE_END_SELECT:
|
||||||
needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
|
needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
|
||||||
needsUpdate |= cursorEnd(cur);
|
needsUpdate |= cursorEnd(cur);
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_WORD_FORWARD:
|
case LFUN_WORD_FORWARD:
|
||||||
@ -534,6 +552,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
needsUpdate |= cursorLeftOneWord(cur);
|
needsUpdate |= cursorLeftOneWord(cur);
|
||||||
else
|
else
|
||||||
needsUpdate |= cursorRightOneWord(cur);
|
needsUpdate |= cursorRightOneWord(cur);
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_WORD_BACKWARD:
|
case LFUN_WORD_BACKWARD:
|
||||||
@ -543,6 +563,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
needsUpdate |= cursorRightOneWord(cur);
|
needsUpdate |= cursorRightOneWord(cur);
|
||||||
else
|
else
|
||||||
needsUpdate |= cursorLeftOneWord(cur);
|
needsUpdate |= cursorLeftOneWord(cur);
|
||||||
|
if (cur.selection())
|
||||||
|
saveSelection(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_WORD_SELECT: {
|
case LFUN_WORD_SELECT: {
|
||||||
@ -781,7 +803,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
pasteClipboard(cur, bv->buffer()->errorList("Paste"));
|
pasteClipboard(cur, bv->buffer()->errorList("Paste"));
|
||||||
else {
|
else {
|
||||||
string const arg(to_utf8(cmd.argument()));
|
string const arg(to_utf8(cmd.argument()));
|
||||||
pasteSelection(cur, bv->buffer()->errorList("Paste"),
|
pasteFromStack(cur, bv->buffer()->errorList("Paste"),
|
||||||
isStrUnsignedInt(arg) ?
|
isStrUnsignedInt(arg) ?
|
||||||
convert<unsigned int>(arg) :
|
convert<unsigned int>(arg) :
|
||||||
0);
|
0);
|
||||||
@ -960,7 +982,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
cursorEnd(cur);
|
cursorEnd(cur);
|
||||||
cur.setSelection();
|
cur.setSelection();
|
||||||
bv->cursor() = cur;
|
bv->cursor() = cur;
|
||||||
theSelection().haveSelection(cur.selection());
|
saveSelection(cur);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -968,7 +990,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
if (cmd.button() == mouse_button::button1) {
|
if (cmd.button() == mouse_button::button1) {
|
||||||
selectWord(cur, WHOLE_WORD_STRICT);
|
selectWord(cur, WHOLE_WORD_STRICT);
|
||||||
bv->cursor() = cur;
|
bv->cursor() = cur;
|
||||||
theSelection().haveSelection(cur.selection());
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -983,15 +1004,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
// it could get cleared on the unlocking of the inset so
|
// it could get cleared on the unlocking of the inset so
|
||||||
// we have to check this first
|
// we have to check this first
|
||||||
bool paste_internally = false;
|
bool paste_internally = false;
|
||||||
if (cmd.button() == mouse_button::button2 && cur.selection()) {
|
if (cmd.button() == mouse_button::button2 && cap::selection()) {
|
||||||
// Copy the selection to the clipboard stack. This
|
// Copy the selection buffer to the clipboard
|
||||||
// is done for two reasons:
|
// stack, because we want it to appear in the
|
||||||
// - We want it to appear in the "Edit->Paste recent"
|
// "Edit->Paste recent" menu.
|
||||||
// menu.
|
cap::copySelectionToStack();
|
||||||
// - 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());
|
|
||||||
paste_internally = true;
|
paste_internally = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1002,9 +1019,13 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
// if there is a local selection in the current buffer,
|
// if there is a local selection in the current buffer,
|
||||||
// insert this
|
// insert this
|
||||||
if (cmd.button() == mouse_button::button2) {
|
if (cmd.button() == mouse_button::button2) {
|
||||||
if (paste_internally)
|
if (paste_internally) {
|
||||||
lyx::dispatch(FuncRequest(LFUN_PASTE, "0"));
|
cap::pasteSelection(cur, bv->buffer()->errorList("Paste"));
|
||||||
else
|
bv->buffer()->errors("Paste");
|
||||||
|
cur.clearSelection(); // bug 393
|
||||||
|
bv->switchKeyMap();
|
||||||
|
finishUndo();
|
||||||
|
} else
|
||||||
lyx::dispatch(FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, "paragraph"));
|
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)
|
if (cmd.button() == mouse_button::button2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// finish selection
|
|
||||||
if (cmd.button() == mouse_button::button1) {
|
if (cmd.button() == mouse_button::button1) {
|
||||||
if (cur.selection())
|
// if there is new selection, update persistent
|
||||||
theSelection().haveSelection(true);
|
// 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;
|
needsUpdate = false;
|
||||||
cur.noUpdate();
|
cur.noUpdate();
|
||||||
}
|
}
|
||||||
@ -1083,13 +1112,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
// "auto_region_delete", which defaults to
|
// "auto_region_delete", which defaults to
|
||||||
// true (on).
|
// true (on).
|
||||||
|
|
||||||
if (lyxrc.auto_region_delete) {
|
if (lyxrc.auto_region_delete)
|
||||||
if (cur.selection())
|
if (cur.selection())
|
||||||
cutSelection(cur, false, false);
|
cutSelection(cur, false, false);
|
||||||
// cutSelection clears the X selection.
|
|
||||||
else
|
|
||||||
theSelection().haveSelection(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
cur.clearSelection();
|
cur.clearSelection();
|
||||||
LyXFont const old_font = real_current_font;
|
LyXFont const old_font = real_current_font;
|
||||||
@ -1508,6 +1533,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
|||||||
case LFUN_ESCAPE:
|
case LFUN_ESCAPE:
|
||||||
if (cur.selection()) {
|
if (cur.selection()) {
|
||||||
cur.selection() = false;
|
cur.selection() = false;
|
||||||
|
saveSelection(cur);
|
||||||
} else {
|
} else {
|
||||||
cur.undispatched();
|
cur.undispatched();
|
||||||
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
||||||
|
Loading…
Reference in New Issue
Block a user