X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.cpp;h=17dbdc626e1aa84f45e07e8f0f932eafecb33921;hb=28be7d552f62cc02fa86d7f79201d089bfb2d7b5;hp=5f3e8090fb524aa7d030309fe32e0bea46019da3;hpb=3a4af5a3e1238b44150ff37c9c39a4d3bde96e7f;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 5f3e8090fb..17dbdc626e 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -62,14 +62,14 @@ #include "support/lstrings.h" #include "support/lyxalgo.h" #include "support/TempFile.h" +#include "support/unique_ptr.h" #include "frontends/alert.h" #include "frontends/Clipboard.h" #include "frontends/Selection.h" -#include - #include +#include using namespace std; using namespace lyx::support; @@ -86,6 +86,8 @@ typedef limited_stack > CutStack; CutStack theCuts(10); // persistent selection, cleared until the next selection CutStack selectionBuffer(1); +// temporary scratch area +CutStack tempCut(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, @@ -100,18 +102,18 @@ bool checkPastePossible(int index) struct PasteReturnValue { - PasteReturnValue(pit_type r_par, pos_type r_pos, bool r_nu) : - par(r_par), pos(r_pos), needupdate(r_nu) + PasteReturnValue(pit_type r_pit, pos_type r_pos, bool r_nu) : + pit(r_pit), pos(r_pos), needupdate(r_nu) {} - pit_type par; + pit_type pit; pos_type pos; bool needupdate; }; PasteReturnValue pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, - DocumentClassConstPtr oldDocClass, Buffer * tmpbuffer, + DocumentClassConstPtr oldDocClass, cap::BranchAction branchAction, ErrorList & errorlist) { Buffer const & buffer = *cur.buffer(); @@ -160,7 +162,7 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, // set the paragraphs to plain layout if necessary DocumentClassConstPtr newDocClass = buffer.params().documentClassPtr(); if (cur.inset().usePlainLayout()) { - bool forcePlainLayout = cur.inset().forcePlainLayout(); + bool forcePlainLayout = target_inset->forcePlainLayout(); Layout const & plainLayout = newDocClass->plainLayout(); Layout const & defaultLayout = newDocClass->defaultLayout(); ParagraphList::iterator const end = insertion.end(); @@ -355,12 +357,15 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, || (is_child && (branchlist.find(name) || buffer.masterBuffer()->params().branchlist().find(name)))) break; - if (tmpbuffer) { + switch(branchAction) { + case cap::BRANCH_ADD: { // This is for a temporary buffer, so simply create the branch. // Must not use lyx::dispatch(), since tmpbuffer has no view. DispatchResult dr; - tmpbuffer->dispatch(FuncRequest(LFUN_BRANCH_ADD, name), dr); - } else { + const_cast(buffer).dispatch(FuncRequest(LFUN_BRANCH_ADD, name), dr); + break; + } + case cap::BRANCH_ASK: { docstring text = bformat( _("The pasted branch \"%1$s\" is undefined.\n" "Do you want to add it to the document's branch list?"), @@ -369,6 +374,10 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, text, 0, 1, _("&Add"), _("&Don't Add")) != 0) break; lyx::dispatch(FuncRequest(LFUN_BRANCH_ADD, name)); + break; + } + case cap::BRANCH_IGNORE: + break; } // We need to update the list of branches. need_update = true; @@ -486,16 +495,18 @@ Buffer * copyToTempBuffer(ParagraphList const & paragraphs, DocumentClassConstPt // to be so, but the alternative is to construct a new one of these (with a // new temporary directory, etc) every time, and then to destroy it. So maybe // it's worth just keeping this one around. - // FIXME THREAD static TempFile tempfile("clipboard.internal"); tempfile.setAutoRemove(false); - static Buffer * staticbuffer = theBufferList().newInternalBuffer( - tempfile.name().absFileName()); - - // These two things only really need doing the first time. - staticbuffer->setUnnamed(true); - staticbuffer->inset().setBuffer(*staticbuffer); - + // The initialization of staticbuffer is thread-safe. Using a lambda + // guarantees that the properties are set only once. + static Buffer * staticbuffer = [&](){ + Buffer * b = + theBufferList().newInternalBuffer(tempfile.name().absFileName()); + b->setUnnamed(true); + b->inset().setBuffer(*b); + //initialize staticbuffer with b + return b; + }(); // Use a clone for the complicated stuff so that we do not need to clean // up in order to avoid a crash. Buffer * buffer = staticbuffer->cloneBufferOnly(); @@ -519,7 +530,7 @@ Buffer * copyToTempBuffer(ParagraphList const & paragraphs, DocumentClassConstPt // temporary Buffer, since it does a lot of things to fix them up. DocIterator dit = doc_iterator_begin(buffer, &buffer->inset()); ErrorList el; - pasteSelectionHelper(dit, paragraphs, docclass, buffer, el); + pasteSelectionHelper(dit, paragraphs, docclass, cap::BRANCH_ADD, el); return buffer; } @@ -641,7 +652,7 @@ void copySelectionHelper(Buffer const & buf, Text const & text, // are not linked to something else. it = copy_pars.begin(); for (; it != it_end; ++it) { - it->setBuffer(*static_cast(0)); + it->resetBuffer(); it->setInsetOwner(0); } @@ -749,8 +760,8 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, if (added_one || newlayouts.find(name) != newlayouts.end()) { // Warn the user. docstring const s = bformat(_("Layout `%1$s' was not found."), name); - errorlist.push_back( - ErrorItem(_("Layout Not Found"), s, it->id(), 0, it->size())); + errorlist.push_back(ErrorItem(_("Layout Not Found"), s, + {it->id(), 0}, {it->id(), -1})); } if (in.usePlainLayout()) @@ -785,8 +796,9 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, layoutName, oldname, newname); // To warn the user that something had to be done. errorlist.push_back(ErrorItem( - _("Undefined flex inset"), - s, it.paragraph().id(), it.pos(), it.pos() + 1)); + _("Undefined flex inset"), s, + {it.paragraph().id(), it.pos()}, + {it.paragraph().id(), it.pos()+1})); } else if (code == TABULAR_CODE) { // The recursion above does not catch paragraphs in "hidden" cells, // i.e., ones that are part of a multirow or multicolum. So we need @@ -836,8 +848,9 @@ size_type numberOfSelections() return theCuts.size(); } +namespace { -void cutSelection(Cursor & cur, bool doclear, bool realcut) +void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool doclear, bool realcut, bool putclip) { // This doesn't make sense, if there is no selection if (!cur.selection()) @@ -865,21 +878,20 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) *text, begpit, endpit, cur.selBegin().pos(), endpos, - bp.documentClassPtr(), theCuts); + bp.documentClassPtr(), cuts); // Stuff what we got on the clipboard. // Even if there is no selection. - putClipboard(theCuts[0].first, theCuts[0].second, - cur.selectionAsString(true)); + if (putclip) + putClipboard(cuts[0].first, cuts[0].second, + cur.selectionAsString(true)); } if (begpit != endpit) cur.screenUpdateFlags(Update::Force | Update::FitCursor); - boost::tie(endpit, endpos) = - eraseSelectionHelper(bp, - text->paragraphs(), - begpit, endpit, - cur.selBegin().pos(), endpos); + tie(endpit, endpos) = + eraseSelectionHelper(bp, text->paragraphs(), begpit, endpit, + cur.selBegin().pos(), endpos); // cutSelection can invalidate the cursor so we need to set // it anew. (Lgb) @@ -921,6 +933,19 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) } } +} + +void cutSelection(Cursor & cur, bool doclear, bool realcut) +{ + cutSelectionHelper(cur, theCuts, doclear, realcut, true); +} + + +void cutSelectionToTemp(Cursor & cur, bool doclear, bool realcut) +{ + cutSelectionHelper(cur, tempCut, doclear, realcut, false); +} + void copySelection(Cursor const & cur) { @@ -1047,6 +1072,7 @@ void clearSelection() void clearCutStack() { theCuts.clear(); + tempCut.clear(); } @@ -1055,7 +1081,8 @@ docstring selection(size_t sel_index, DocumentClassConstPtr docclass) if (sel_index >= theCuts.size()) return docstring(); - boost::scoped_ptr buffer(copyToTempBuffer(theCuts[sel_index].first, docclass)); + unique_ptr buffer(copyToTempBuffer(theCuts[sel_index].first, + docclass)); if (!buffer) return docstring(); @@ -1064,17 +1091,18 @@ docstring selection(size_t sel_index, DocumentClassConstPtr docclass) void pasteParagraphList(Cursor & cur, ParagraphList const & parlist, - DocumentClassConstPtr docclass, ErrorList & errorList) + DocumentClassConstPtr docclass, ErrorList & errorList, + cap::BranchAction branchAction) { if (cur.inTexted()) { Text * text = cur.text(); LBUFERR(text); PasteReturnValue prv = - pasteSelectionHelper(cur, parlist, docclass, 0, errorList); + pasteSelectionHelper(cur, parlist, docclass, branchAction, errorList); cur.forceBufferUpdate(); cur.clearSelection(); - text->setCursor(cur, prv.par, prv.pos); + text->setCursor(cur, prv.pit, prv.pos); } // mathed is handled in InsetMathNest/InsetMathGrid @@ -1090,7 +1118,20 @@ bool pasteFromStack(Cursor & cur, ErrorList & errorList, size_t sel_index) cur.recordUndo(); pasteParagraphList(cur, theCuts[sel_index].first, - theCuts[sel_index].second, errorList); + theCuts[sel_index].second, errorList, BRANCH_ASK); + return true; +} + + +bool pasteFromTemp(Cursor & cur, ErrorList & errorList) +{ + // this does not make sense, if there is nothing to paste + if (tempCut.empty() || tempCut[0].first.empty()) + return false; + + cur.recordUndo(); + pasteParagraphList(cur, tempCut[0].first, + tempCut[0].second, errorList, BRANCH_IGNORE); return true; } @@ -1169,6 +1210,7 @@ bool pasteClipboardText(Cursor & cur, ErrorList & errorList, bool asParagraphs, cur.text()->insertStringAsParagraphs(cur, text, cur.current_font); else cur.text()->insertStringAsLines(cur, text, cur.current_font); + cur.forceBufferUpdate(); return true; } @@ -1325,7 +1367,7 @@ void selClearOrDel(Cursor & cur) if (lyxrc.auto_region_delete) selDel(cur); else - cur.setSelection(false); + cur.selection(false); }