X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.cpp;h=c34fc5d230d1dd5094fee2acd0d4ad6ed7d37a29;hb=cadae068974fb25e97c5b2c38774a73ee23e92fc;hp=6d25addd3397322bf61a068a337685e6e232f2bf;hpb=0bf9ac02a8988b2747c15520780cbf4343dd6a45;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 6d25addd33..c34fc5d230 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -18,6 +18,7 @@ #include "Buffer.h" #include "buffer_funcs.h" #include "BufferParams.h" +#include "BufferView.h" #include "Cursor.h" #include "debug.h" #include "ErrorList.h" @@ -28,8 +29,8 @@ #include "lfuns.h" #include "LyXFunc.h" #include "LyXRC.h" -#include "LyXText.h" -#include "LyXTextClassList.h" +#include "Text.h" +#include "TextClassList.h" #include "Paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" @@ -128,7 +129,8 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, // Convert newline to paragraph break in ERT inset. // This should not be here! if (pars[pit].inInset() && - pars[pit].inInset()->lyxCode() == Inset::ERT_CODE) { + (pars[pit].inInset()->lyxCode() == Inset::ERT_CODE || + pars[pit].inInset()->lyxCode() == Inset::LISTINGS_CODE)) { for (ParagraphList::size_type i = 0; i < insertion.size(); ++i) { for (pos_type j = 0; j < insertion[i].size(); ++j) { if (insertion[i].isNewline(j)) { @@ -145,10 +147,10 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, // If we are in an inset which returns forceDefaultParagraphs, // set the paragraphs to default if (cur.inset().forceDefaultParagraphs(cur.idx())) { - Layout_ptr const layout = - buffer.params().getLyXTextClass().defaultLayout(); + Layout_ptr const layout = + buffer.params().getTextClass().defaultLayout(); ParagraphList::iterator const end = insertion.end(); - for (ParagraphList::iterator par = insertion.begin(); + for (ParagraphList::iterator par = insertion.begin(); par != end; ++par) par->layout(layout); } @@ -197,7 +199,7 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, } tmpbuf->setChange(Change(buffer.params().trackChanges ? - Change::INSERTED : Change::UNCHANGED)); + Change::INSERTED : Change::UNCHANGED)); } bool const empty = pars[pit].empty(); @@ -300,7 +302,12 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, for (pit_type pit = startpit; pit != endpit + 1;) { pos_type const left = (pit == startpit ? startpos : 0); - pos_type const right = (pit == endpit ? endpos : pars[pit].size() + 1); + pos_type right = (pit == endpit ? endpos : pars[pit].size() + 1); + // FIXME: this is a quick fix for bug 3600. It stops a crash but the problem + // still remains unsolved (e.g. the second example in the bug report). + // c.f. http://bugzilla.lyx.org/show_bug.cgi?id=3600 + if (right > pars[pit].size() + 1) + right = pars[pit].size() + 1; bool const merge = pars[pit].isMergedOnEndOfParDeletion(params.trackChanges); @@ -329,7 +336,7 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, void putClipboard(ParagraphList const & paragraphs, textclass_type textclass, - docstring const & plaintext) + docstring const & plaintext) { // For some strange reason gcc 3.2 and 3.3 do not accept // Buffer buffer(string(), false); @@ -374,20 +381,15 @@ void copySelectionHelper(Buffer const & buf, ParagraphList & pars, // ERT paragraphs have the Language latex_language. // This is invalid outside of ERT, so we need to change it // to the buffer language. - if (it->ownerCode() == Inset::ERT_CODE) { + if (it->ownerCode() == Inset::ERT_CODE || it->ownerCode() == Inset::LISTINGS_CODE) { it->changeLanguage(buf.params(), latex_language, - buf.getLanguage()); + buf.getLanguage()); } it->setInsetOwner(0); } // do not copy text (also nested in insets) which is marked as deleted - // acceptChanges() is defined for LyXText rather than ParagraphList - // Thus we must wrap copy_pars into a LyXText object and cross our fingers - LyXText lt; - copy_pars.swap(lt.paragraphs()); - lt.acceptChanges(buf.params()); - copy_pars.swap(lt.paragraphs()); + acceptChanges(copy_pars, buf.params()); cutstack.push(make_pair(copy_pars, tc)); } @@ -412,17 +414,19 @@ docstring grabAndEraseSelection(Cursor & cur) void switchBetweenClasses(textclass_type c1, textclass_type c2, InsetText & in, ErrorList & errorlist) { + errorlist.clear(); + BOOST_ASSERT(!in.paragraphs().empty()); if (c1 == c2) return; - LyXTextClass const & tclass1 = textclasslist[c1]; - LyXTextClass const & tclass2 = textclasslist[c2]; + TextClass const & tclass1 = textclasslist[c1]; + TextClass const & tclass2 = textclasslist[c2]; // layouts ParIterator end = par_iterator_end(in); for (ParIterator it = par_iterator_begin(in); it != end; ++it) { - string const name = it->layout()->name(); + docstring const name = it->layout()->name(); bool hasLayout = tclass2.hasLayout(name); if (hasLayout) @@ -434,7 +438,7 @@ void switchBetweenClasses(textclass_type c1, textclass_type c2, docstring const s = bformat( _("Layout had to be changed from\n%1$s to %2$s\n" "because of class conversion from\n%3$s to %4$s"), - from_utf8(name), from_utf8(it->layout()->name()), + name, it->layout()->name(), from_utf8(tclass1.name()), from_utf8(tclass2.name())); // To warn the user that something had to be done. errorlist.push_back(ErrorItem(_("Changed Layout"), s, @@ -492,7 +496,7 @@ std::vector const availableSelections(Buffer const & buffer) asciiSel += pit->asString(buffer, false); if (asciiSel.size() > 25) { asciiSel.replace(22, docstring::npos, - from_ascii("...")); + from_ascii("...")); break; } } @@ -520,9 +524,11 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) // and cur.selEnd() if (cur.inTexted()) { - LyXText * text = cur.text(); + Text * text = cur.text(); BOOST_ASSERT(text); + saveSelection(cur); + // make sure that the depth behind the selection are restored, too recordUndoSelection(cur); pit_type begpit = cur.selBegin().pit(); @@ -557,14 +563,13 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) cur.pit() = endpit; // sometimes necessary - if (doclear + if (doclear && text->paragraphs()[begpit].stripLeadingSpaces(bp.trackChanges)) cur.fixIfBroken(); // need a valid cursor. (Lgb) cur.clearSelection(); updateLabels(cur.buffer()); - theSelection().haveSelection(false); // tell tabular that a recent copy happened dirtyTabularStack(false); @@ -601,8 +606,12 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) if (!cur.selection()) return; + // copySelection can not yet handle the case of cross idx selection + if (cur.selBegin().idx() != cur.selEnd().idx()) + return; + if (cur.inTexted()) { - LyXText * text = cur.text(); + Text * text = cur.text(); BOOST_ASSERT(text); // ok we have a selection. This is always between cur.selBegin() // and sel_end cursor @@ -618,6 +627,7 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) copySelectionHelper(cur.buffer(), pars, par, cur.selEnd().pit(), pos, cur.selEnd().pos(), cur.buffer().params().textclass, cutstack); + dirtyTabularStack(false); } if (cur.inMathed()) { @@ -625,7 +635,7 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) ParagraphList pars; Paragraph par; BufferParams const & bp = cur.buffer().params(); - par.layout(bp.getLyXTextClass().defaultLayout()); + par.layout(bp.getTextClass().defaultLayout()); par.insert(0, grabSelection(cur), Font(), Change(Change::UNCHANGED)); pars.push_back(par); cutstack.push(make_pair(pars, bp.textclass)); @@ -645,14 +655,14 @@ void copySelectionToStack() void copySelection(Cursor & cur, docstring const & plaintext) { // In tablemode, because copy and paste actually use special table stack - // we do not attemp to get selected paragraphs under cursor. Instead, a + // we do not attemp to get selected paragraphs under cursor. Instead, a // paragraph with the plain text version is generated so that table cells // can be pasted as pure text somewhere else. if (cur.selBegin().idx() != cur.selEnd().idx()) { ParagraphList pars; Paragraph par; BufferParams const & bp = cur.buffer().params(); - par.layout(bp.getLyXTextClass().defaultLayout()); + par.layout(bp.getTextClass().defaultLayout()); par.insert(0, plaintext, Font(), Change(Change::UNCHANGED)); pars.push_back(par); theCuts.push(make_pair(pars, bp.textclass)); @@ -666,14 +676,17 @@ void copySelection(Cursor & cur, docstring const & plaintext) void saveSelection(Cursor & cur) { - LYXERR(Debug::ACTION) << BOOST_CURRENT_FUNCTION << ": `" - << to_utf8(cur.selectionAsString(true)) << "'." - << endl; - - if (cur.selection()) + // 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() + && cur.selBegin() == cur.bv().cursor().selBegin() + && cur.selEnd() == cur.bv().cursor().selEnd()) { + LYXERR(Debug::ACTION) << BOOST_CURRENT_FUNCTION << ": `" + << to_utf8(cur.selectionAsString(true)) << "'." + << endl; copySelectionToStack(cur, selectionBuffer); - // tell X whether we now have a valid selection - theSelection().haveSelection(cur.selection()); + } } @@ -701,7 +714,7 @@ void pasteParagraphList(Cursor & cur, ParagraphList const & parlist, textclass_type textclass, ErrorList & errorList) { if (cur.inTexted()) { - LyXText * text = cur.text(); + Text * text = cur.text(); BOOST_ASSERT(text); pit_type endpit; @@ -712,7 +725,7 @@ void pasteParagraphList(Cursor & cur, ParagraphList const & parlist, textclass, errorList); updateLabels(cur.buffer()); cur.clearSelection(); - text->setCursor(cur.top(), ppp.first, ppp.second); + text->setCursor(cur, ppp.first, ppp.second); } // mathed is handled in InsetMathNest/InsetMathGrid @@ -730,7 +743,6 @@ void pasteFromStack(Cursor & cur, ErrorList & errorList, size_t sel_index) pasteParagraphList(cur, theCuts[sel_index].first, theCuts[sel_index].second, errorList); cur.setSelection(); - saveSelection(cur); } @@ -778,7 +790,7 @@ void pasteSelection(Cursor & cur, ErrorList & errorList) return; recordUndo(cur); pasteParagraphList(cur, selectionBuffer[0].first, - selectionBuffer[0].second, errorList); + selectionBuffer[0].second, errorList); cur.setSelection(); } @@ -809,7 +821,6 @@ void replaceSelectionWithString(Cursor & cur, docstring const & str, bool backwa cur.setSelection(selbeg, -int(str.length())); } else cur.setSelection(selbeg, str.length()); - saveSelection(cur); } @@ -826,6 +837,7 @@ void eraseSelection(Cursor & cur) CursorSlice const & i1 = cur.selBegin(); CursorSlice const & i2 = cur.selEnd(); if (i1.inset().asInsetMath()) { + saveSelection(cur); cur.top() = i1; if (i1.idx() == i2.idx()) { i1.cell().erase(i1.pos(), i2.pos()); @@ -846,7 +858,6 @@ void eraseSelection(Cursor & cur) } // need a valid cursor. (Lgb) cur.clearSelection(); - theSelection().haveSelection(false); } else { lyxerr << "can't erase this selection 1" << endl; }