X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FCutAndPaste.cpp;h=d79ef5a655defd744cc98ac6adf26c561194d143;hb=ffd175b99f4e7957c4be9eed04f5124a78f192d5;hp=4ec9811d90bb8fd086e2e30be20ecb958bf1b620;hpb=2fd2e657458f571df373a1b3fba1e6a33c8f6d59;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 4ec9811d90..d79ef5a655 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -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, @@ -111,7 +113,7 @@ struct PasteReturnValue { PasteReturnValue pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, - DocumentClassConstPtr oldDocClass, Buffer * tmpbuffer, + DocumentClassConstPtr oldDocClass, cap::BranchAction branchAction, ErrorList & errorlist) { Buffer const & buffer = *cur.buffer(); @@ -241,7 +243,7 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, InsetIterator const i_end = inset_iterator_end(in); for (InsetIterator it = inset_iterator_begin(in); it != i_end; ++it) { - // Even though this will also be done later, it has to be done here + // Even though this will also be done later, it has to be done here // since some inset might going to try to access // the buffer() member. it->setBuffer(const_cast(buffer)); @@ -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; @@ -462,7 +471,7 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, // Separate handling of paragraph break: if (merge && pit != endpit && - (pit + 1 != endpit + (pit + 1 != endpit || pars[pit].hasSameLayout(pars[endpit]) || pars[endpit].size() == endpos)) { if (pit + 1 == endpit) @@ -521,13 +530,13 @@ 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; } -void putClipboard(ParagraphList const & paragraphs, +void putClipboard(ParagraphList const & paragraphs, DocumentClassConstPtr docclass, docstring const & plaintext) { Buffer * buffer = copyToTempBuffer(paragraphs, docclass); @@ -627,7 +636,7 @@ void copySelectionHelper(Buffer const & buf, Text const & text, // latex_language. This is invalid for others, so we // need to change it to the buffer language. if (it->isPassThru()) - it->changeLanguage(buf.params(), + it->changeLanguage(buf.params(), latex_language, buf.language()); } @@ -643,16 +652,14 @@ 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); } cutstack.push(make_pair(copy_pars, dc)); } -} // namespace anon - - +} // namespace namespace cap { @@ -696,11 +703,11 @@ bool reduceSelectionToOneCell(Cursor & cur) // the easy case: do nothing if only one cell is selected if (i1.idx() == i2.idx()) return true; - + cur.top().pos() = 0; cur.resetAnchor(); cur.top().pos() = cur.top().lastpos(); - + return true; } @@ -709,15 +716,15 @@ bool multipleCellsSelected(Cursor const & cur) { if (!cur.selection() || !cur.inMathed()) return false; - + CursorSlice i1 = cur.selBegin(); CursorSlice i2 = cur.selEnd(); if (!i1.inset().asInsetMath()) return false; - + if (i1.idx() == i2.idx()) return false; - + return true; } @@ -730,7 +737,7 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, LBUFERR(!in.paragraphs().empty()); if (oldone == newone) return; - + DocumentClass const & oldtc = *oldone; DocumentClass const & newtc = *newone; @@ -751,8 +758,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()) @@ -766,14 +773,14 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, for (InsetIterator it = inset_iterator_begin(in); it != i_end; ++it) { InsetCode const code = it->lyxCode(); if (code == FLEX_CODE) { - // FIXME: Should we verify all InsetCollapsable? + // FIXME: Should we verify all InsetCollapsible? docstring const layoutName = it->layoutName(); docstring const & n = newone->insetLayout(layoutName).name(); bool const is_undefined = n.empty() || n == DocumentClass::plainInsetLayout().name(); if (!is_undefined) continue; - + // The flex inset is undefined in newtc docstring const oldname = from_utf8(oldtc.name()); docstring const newname = from_utf8(newtc.name()); @@ -787,8 +794,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 @@ -838,8 +846,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()) @@ -867,11 +876,12 @@ 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) @@ -921,6 +931,19 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) } } +} // namespace + +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) { @@ -963,7 +986,7 @@ void copySelectionToStack(Cursor const & cur, CutStack & cutstack) // and sel_end cursor copySelectionHelper(*cur.buffer(), *text, cur.selBegin().pit(), cur.selEnd().pit(), - cur.selBegin().pos(), cur.selEnd().pos(), + cur.selBegin().pos(), cur.selEnd().pos(), cur.buffer()->params().documentClassPtr(), cutstack); // Reset the dirty_tabular_stack_ flag only when something @@ -985,7 +1008,7 @@ void copySelectionToStack(Cursor const & cur, CutStack & cutstack) } } -} +} // namespace void copySelectionToStack() @@ -1023,7 +1046,7 @@ void saveSelection(Cursor const & cur) // This function is called, not when a selection is formed, but when // a selection is cleared. Therefore, multiple keyboard selection // will not repeatively trigger this function (bug 3877). - if (cur.selection() + if (cur.selection() && cur.selBegin() == cur.bv().cursor().selBegin() && cur.selEnd() == cur.bv().cursor().selEnd()) { LYXERR(Debug::SELECTION, "saveSelection: '" << cur.selectionAsString(true) << "'"); @@ -1047,6 +1070,7 @@ void clearSelection() void clearCutStack() { theCuts.clear(); + tempCut.clear(); } @@ -1065,14 +1089,15 @@ 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.pit, prv.pos); @@ -1091,7 +1116,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; }