X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.C;h=373ee6c01b80f31833daacc0e5112e708e9c2466;hb=e7fc677261bd14fdf159e594fcf422e985c72664;hp=b74d018dccc11dcaa80abb531c3107812493e4c2;hpb=2eb67150a4eb894fdebd515425ff1ec1ac01ae2f;p=lyx.git diff --git a/src/CutAndPaste.C b/src/CutAndPaste.C index b74d018dcc..373ee6c01b 100644 --- a/src/CutAndPaste.C +++ b/src/CutAndPaste.C @@ -105,18 +105,19 @@ bool checkPastePossible(int index) pair -pasteSelectionHelper(Buffer const & buffer, ParagraphList & pars, - pit_type pit, int pos, - textclass_type tc, size_t cut_index, ErrorList & errorlist) +pasteSelectionHelper(Buffer const & buffer, + ParagraphList & pars, pit_type pit, int pos, + ParagraphList const & parlist, textclass_type textclass, + ErrorList & errorlist) { - if (!checkPastePossible(cut_index)) + if (parlist.empty()) return make_pair(PitPosPair(pit, pos), pit); BOOST_ASSERT (pos <= pars[pit].size()); // Make a copy of the CaP paragraphs. - ParagraphList insertion = theCuts[cut_index].first; - textclass_type const textclass = theCuts[cut_index].second; + ParagraphList insertion = parlist; + textclass_type const tc = buffer.params().textclass; // Now remove all out of the pars which is NOT allowed in the // new environment and set also another font if that is required. @@ -213,14 +214,16 @@ pasteSelectionHelper(Buffer const & buffer, ParagraphList & pars, // Paste it! if (empty) { - pars.insert(pars.begin() + pit, insertion.begin(), + pars.insert(boost::next(pars.begin(), pit), + insertion.begin(), insertion.end()); // merge the empty par with the last par of the insertion mergeParagraph(buffer.params(), pars, pit + insertion.size() - 1); } else { - pars.insert(pars.begin() + pit + 1, insertion.begin(), + pars.insert(boost::next(pars.begin(), pit + 1), + insertion.begin(), insertion.end()); // merge the first par of the insertion with the current par @@ -233,7 +236,8 @@ pasteSelectionHelper(Buffer const & buffer, ParagraphList & pars, pit = last_paste; pos = pars[last_paste].size(); - // Maybe some pasting. + // Join (conditionally) last pasted paragraph with next one, i.e., + // the tail of the spliced document paragraph if (!empty && last_paste + 1 != pit_type(pars.size())) { if (pars[last_paste + 1].hasSameLayout(pars[last_paste])) { mergeParagraph(buffer.params(), pars, last_paste); @@ -270,64 +274,35 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, return PitPosPair(endpit, endpos); } - bool all_erased = true; - - // Clear fragments of the first par in selection - pars[startpit].erase(startpos, pars[startpit].size()); - if (pars[startpit].size() != startpos) - all_erased = false; - - // Clear fragments of the last par in selection - endpos -= pars[endpit].erase(0, endpos); - if (endpos != 0) - all_erased = false; - - // Erase all the "middle" paragraphs. - if (params.tracking_changes) { - // Look through the deleted pars if any, erasing as needed - for (pit_type pit = startpit + 1; pit != endpit;) { - // "erase" the contents of the par - pars[pit].erase(0, pars[pit].size()); - if (pars[pit].empty()) { - // remove the par if it's now empty - pars.erase(pars.begin() + pit); - --endpit; - } else { - ++pit; - all_erased = false; - } - } - } else { - pars.erase(pars.begin() + startpit + 1, pars.begin() + endpit); - endpit = startpit + 1; - } - -#if 0 // FIXME: why for cut but not copy ? - // the cut selection should begin with standard layout - if (realcut) { - buf->params().clear(); - buf->bibkey = 0; - buf->layout(textclasslist[buffer->params.textclass].defaultLayoutName()); - } -#endif - - if (startpit + 1 == pit_type(pars.size())) - return PitPosPair(endpit, endpos); - - if (doclear) { - pars[startpit + 1].stripLeadingSpaces(); - } - - // Merge first and last paragraph, if possible - if (all_erased && - (pars[startpit].hasSameLayout(pars[startpit + 1]) || - pars[startpit + 1].empty())) { - mergeParagraph(params, pars, startpit); - // This because endpar gets deleted here! - endpit = startpit; - endpos = startpos; + // A paragraph break has to be physically removed by merging, but + // only if either (1) change tracking is off, or (2) the para break + // is "blue" + for (pit_type pit = startpit; pit != endpit + 1;) { + bool const merge = !params.tracking_changes || + pars[pit].lookupChange(pars[pit].size()) == + Change::INSERTED; + pos_type const left = ( pit == startpit ? startpos : 0 ); + pos_type const right = ( pit == endpit ? endpos : + pars[pit].size() + 1 ); + // Logical erase only: + pars[pit].erase(left, right); + // Separate handling of para break: + if (merge && pit != endpit && + pars[pit].hasSameLayout(pars[pit + 1])) { + pos_type const thissize = pars[pit].size(); + if (doclear) + pars[pit + 1].stripLeadingSpaces(); + mergeParagraph(params, pars, pit); + --endpit; + if (pit == endpit) + endpos += thissize; + } else + ++pit; } + // Ensure legal cursor pos: + endpit = startpit; + endpos = startpos; return PitPosPair(endpit, endpos); } @@ -341,7 +316,8 @@ void copySelectionHelper(ParagraphList & pars, BOOST_ASSERT(startpit != endpit || start <= end); // Clone the paragraphs within the selection. - ParagraphList paragraphs(pars.begin() + startpit, pars.begin() + endpit + 1); + ParagraphList paragraphs(boost::next(pars.begin(), startpit), + boost::next(pars.begin(), endpit + 1)); for_each(paragraphs.begin(), paragraphs.end(), resetOwnerAndChanges()); @@ -608,13 +584,9 @@ std::string getSelection(Buffer const & buf, size_t sel_index) } -void pasteSelection(LCursor & cur, size_t sel_index) +void pasteParagraphList(LCursor & cur, ParagraphList const & parlist, + textclass_type textclass) { - // this does not make sense, if there is nothing to paste - lyxerr << "#### pasteSelection " << sel_index << endl; - if (!checkPastePossible(sel_index)) - return; - if (cur.inTexted()) { LyXText * text = cur.text(); BOOST_ASSERT(text); @@ -623,22 +595,18 @@ void pasteSelection(LCursor & cur, size_t sel_index) pit_type endpit; PitPosPair ppp; - ErrorList el; boost::tie(ppp, endpit) = pasteSelectionHelper(cur.buffer(), text->paragraphs(), cur.pit(), cur.pos(), - cur.buffer().params().textclass, - sel_index, el); + parlist, textclass, + el); bufferErrors(cur.buffer(), el); - cur.bv().showErrorList(_("Paste")); - + updateCounters(cur.buffer()); cur.clearSelection(); text->setCursor(cur, ppp.first, ppp.second); - cur.setSelection(); - updateCounters(cur.buffer()); } // mathed is handled in MathNestInset/MathGridInset @@ -646,6 +614,19 @@ void pasteSelection(LCursor & cur, size_t sel_index) } +void pasteSelection(LCursor & cur, size_t sel_index) +{ + // this does not make sense, if there is nothing to paste + if (!checkPastePossible(sel_index)) + return; + + pasteParagraphList(cur, theCuts[sel_index].first, + theCuts[sel_index].second); + cur.bv().showErrorList(_("Paste")); + cur.setSelection(); +} + + void setSelectionRange(LCursor & cur, pos_type length) { LyXText * text = cur.text();