X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.cpp;h=2450e0fc5cbfa5dc5eec958adf8341ecf0ac7fe4;hb=dfd786e6a0cb8d2d9548d1a0ef17eb47b0752e1b;hp=5c04ed88a468f7ab1d3b008c8626154a31cc03fa;hpb=32871c1284f15265f652ff01c438e539a7c8181f;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 5c04ed88a4..2450e0fc5c 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -1,4 +1,4 @@ -/* +/** * \file CutAndPaste.cpp * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. @@ -15,62 +15,62 @@ #include "CutAndPaste.h" +#include "BaseClassList.h" #include "Buffer.h" #include "buffer_funcs.h" #include "BufferParams.h" +#include "BufferView.h" +#include "Changes.h" #include "Cursor.h" -#include "debug.h" #include "ErrorList.h" #include "FuncRequest.h" -#include "gettext.h" #include "InsetIterator.h" +#include "InsetList.h" #include "Language.h" #include "lfuns.h" #include "LyXFunc.h" #include "LyXRC.h" -#include "LyXText.h" -#include "LyXTextClassList.h" +#include "Text.h" #include "Paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" #include "ParIterator.h" #include "Undo.h" -#include "insets/InsetCharStyle.h" +#include "insets/InsetFlex.h" +#include "insets/InsetGraphics.h" +#include "insets/InsetGraphicsParams.h" #include "insets/InsetTabular.h" #include "mathed/MathData.h" #include "mathed/InsetMath.h" #include "mathed/MathSupport.h" +#include "support/debug.h" +#include "support/docstream.h" +#include "support/gettext.h" +#include "support/limited_stack.h" #include "support/lstrings.h" #include "frontends/Clipboard.h" #include "frontends/Selection.h" -#include #include +#include #include -using std::endl; -using std::for_each; -using std::make_pair; -using std::pair; -using std::vector; -using std::string; - +using namespace std; +using namespace lyx::support; +using lyx::frontend::Clipboard; namespace lyx { -using support::bformat; -using frontend::Clipboard; - namespace { -typedef std::pair PitPosPair; +typedef pair PitPosPair; -typedef limited_stack > CutStack; +typedef limited_stack > CutStack; CutStack theCuts(10); // persistent selection, cleared until the next selection @@ -90,11 +90,11 @@ void region(CursorSlice const & i1, CursorSlice const & i2, c1 = p.col(i1.idx()); c2 = p.col(i2.idx()); if (c1 > c2) - std::swap(c1, c2); + swap(c1, c2); r1 = p.row(i1.idx()); r2 = p.row(i2.idx()); if (r1 > r2) - std::swap(r1, r2); + swap(r1, r2); } @@ -106,7 +106,7 @@ bool checkPastePossible(int index) pair pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, - textclass_type textclass, ErrorList & errorlist) + TextClassPtr textclass, ErrorList & errorlist) { Buffer const & buffer = cur.buffer(); pit_type pit = cur.pit(); @@ -120,17 +120,18 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, // Make a copy of the CaP paragraphs. ParagraphList insertion = parlist; - textclass_type const tc = buffer.params().textclass; + TextClassPtr const tc = buffer.params().textClassPtr(); // Now remove all out of the pars which is NOT allowed in the // new environment and set also another font if that is required. // Convert newline to paragraph break in ERT inset. // This should not be here! - if (pars[pit].inInset() && - pars[pit].inInset()->lyxCode() == Inset::ERT_CODE) { - for (ParagraphList::size_type i = 0; i < insertion.size(); ++i) { - for (pos_type j = 0; j < insertion[i].size(); ++j) { + Inset * inset = pars[pit].inInset(); + if (inset && (inset->lyxCode() == ERT_CODE || + inset->lyxCode() == LISTINGS_CODE)) { + for (size_t i = 0; i != insertion.size(); ++i) { + for (pos_type j = 0; j != insertion[i].size(); ++j) { if (insertion[i].isNewline(j)) { // do not track deletion of newline insertion[i].eraseChar(j, false); @@ -142,15 +143,16 @@ 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())) { - LyXLayout_ptr const layout = - buffer.params().getLyXTextClass().defaultLayout(); + // set the paragraphs to empty layout if necessary + // note that we are doing this if the empty layout is + // supposed to be the default, not just if it is forced + if (cur.inset().useEmptyLayout()) { + LayoutPtr const layout = + buffer.params().textClass().emptyLayout(); ParagraphList::iterator const end = insertion.end(); - for (ParagraphList::iterator par = insertion.begin(); + for (ParagraphList::iterator par = insertion.begin(); par != end; ++par) - par->layout(layout); + par->setLayout(layout); } // Make sure there is no class difference. @@ -190,14 +192,14 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, // Set the inset owner of this paragraph. tmpbuf->setInsetOwner(pars[pit].inInset()); for (pos_type i = 0; i < tmpbuf->size(); ++i) { - if (tmpbuf->getChar(i) == Paragraph::META_INSET && - !pars[pit].insetAllowed(tmpbuf->getInset(i)->lyxCode())) - // do not track deletion of invalid insets - tmpbuf->eraseChar(i--, false); + // do not track deletion of invalid insets + if (Inset * inset = tmpbuf->getInset(i)) + if (!pars[pit].insetAllowed(inset->lyxCode())) + tmpbuf->eraseChar(i--, false); } tmpbuf->setChange(Change(buffer.params().trackChanges ? - Change::INSERTED : Change::UNCHANGED)); + Change::INSERTED : Change::UNCHANGED)); } bool const empty = pars[pit].empty(); @@ -215,21 +217,10 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, ParIterator fend = par_iterator_end(in); for (; fpit != fend; ++fpit) { - InsetList::const_iterator lit = fpit->insetlist.begin(); - InsetList::const_iterator eit = fpit->insetlist.end(); - - for (; lit != eit; ++lit) { - switch (lit->inset->lyxCode()) { - case Inset::TABULAR_CODE: { - InsetTabular * it = static_cast(lit->inset); - it->buffer(&buffer); - break; - } - - default: - break; // nothing - } - } + InsetList::const_iterator it = fpit->insetList().begin(); + InsetList::const_iterator et = fpit->insetList().end(); + for (; it != et; ++it) + it->inset->setBuffer(const_cast(&buffer)); } insertion.swap(in.paragraphs()); @@ -285,7 +276,7 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, PitPosPair eraseSelectionHelper(BufferParams const & params, ParagraphList & pars, pit_type startpit, pit_type endpit, - int startpos, int endpos, bool doclear) + int startpos, int endpos) { // Start of selection is really invalid. if (startpit == pit_type(pars.size()) || @@ -300,8 +291,7 @@ 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); bool const merge = pars[pit].isMergedOnEndOfParDeletion(params.trackChanges); // Logically erase only, including the end-of-paragraph character @@ -309,14 +299,13 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, // Separate handling of paragraph break: if (merge && pit != endpit && - (pit + 1 != endpit || pars[pit].hasSameLayout(pars[pit + 1]))) { - pos_type const thissize = pars[pit].size(); - if (doclear) - pars[pit + 1].stripLeadingSpaces(params.trackChanges); + (pit + 1 != endpit + || pars[pit].hasSameLayout(pars[endpit]) + || pars[endpit].size() == endpos)) { + if (pit + 1 == endpit) + endpos += pars[pit].size(); mergeParagraph(params, pars, pit); --endpit; - if (pit == endpit) - endpos += thissize; } else ++pit; } @@ -328,16 +317,16 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, } -void putClipboard(ParagraphList const & paragraphs, textclass_type textclass, - docstring const & plaintext) +void putClipboard(ParagraphList const & paragraphs, TextClassPtr textclass, + docstring const & plaintext) { // For some strange reason gcc 3.2 and 3.3 do not accept // Buffer buffer(string(), false); Buffer buffer("", false); buffer.setUnnamed(true); buffer.paragraphs() = paragraphs; - buffer.params().textclass = textclass; - std::ostringstream lyx; + buffer.params().setTextClass(textclass); + ostringstream lyx; if (buffer.write(lyx)) theClipboard().put(lyx.str(), plaintext); else @@ -347,7 +336,7 @@ void putClipboard(ParagraphList const & paragraphs, textclass_type textclass, void copySelectionHelper(Buffer const & buf, ParagraphList & pars, pit_type startpit, pit_type endpit, - int start, int end, textclass_type tc, CutStack & cutstack) + int start, int end, TextClassPtr tc, CutStack & cutstack) { BOOST_ASSERT(0 <= start && start <= pars[startpit].size()); BOOST_ASSERT(0 <= end && end <= pars[endpit].size()); @@ -374,20 +363,14 @@ 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) { - it->changeLanguage(buf.params(), latex_language, - buf.getLanguage()); + if (it->ownerCode() == ERT_CODE || it->ownerCode() == LISTINGS_CODE) { + it->changeLanguage(buf.params(), latex_language, buf.language()); } 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)); } @@ -409,33 +392,35 @@ docstring grabAndEraseSelection(Cursor & cur) } -void switchBetweenClasses(textclass_type c1, textclass_type c2, - InsetText & in, ErrorList & errorlist) +void switchBetweenClasses(TextClassPtr const & oldone, + TextClassPtr const & newone, InsetText & in, ErrorList & errorlist) { + errorlist.clear(); + BOOST_ASSERT(!in.paragraphs().empty()); - if (c1 == c2) + if (oldone == newone) return; - - LyXTextClass const & tclass1 = textclasslist[c1]; - LyXTextClass const & tclass2 = textclasslist[c2]; + + TextClass const & oldtc = *oldone; + TextClass const & newtc = *newone; // layouts ParIterator end = par_iterator_end(in); for (ParIterator it = par_iterator_begin(in); it != end; ++it) { - string const name = it->layout()->name(); - bool hasLayout = tclass2.hasLayout(name); + docstring const name = it->layout()->name(); + bool hasLayout = newtc.hasLayout(name); if (hasLayout) - it->layout(tclass2[name]); + it->setLayout(newtc[name]); else - it->layout(tclass2.defaultLayout()); + it->setLayout(newtc.defaultLayout()); - if (!hasLayout && name != tclass1.defaultLayoutName()) { + if (!hasLayout && name != oldtc.defaultLayoutName()) { 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()), - from_utf8(tclass1.name()), from_utf8(tclass2.name())); + name, it->layout()->name(), + from_utf8(oldtc.name()), from_utf8(newtc.name())); // To warn the user that something had to be done. errorlist.push_back(ErrorItem(_("Changed Layout"), s, it->id(), 0, @@ -446,36 +431,31 @@ void switchBetweenClasses(textclass_type c1, textclass_type c2, // character styles InsetIterator const i_end = inset_iterator_end(in); for (InsetIterator it = inset_iterator_begin(in); it != i_end; ++it) { - if (it->lyxCode() == Inset::CHARSTYLE_CODE) { - InsetCharStyle & inset = - static_cast(*it); - string const name = inset.params().type; - CharStyles::iterator const found_cs = - tclass2.charstyle(name); - if (found_cs == tclass2.charstyles().end()) { - // The character style is undefined in tclass2 - inset.setUndefined(); - docstring const s = bformat(_( - "Character style %1$s is " - "undefined because of class " - "conversion from\n%2$s to %3$s"), - from_utf8(name), from_utf8(tclass1.name()), - from_utf8(tclass2.name())); - // To warn the user that something had to be done. - errorlist.push_back(ErrorItem( - _("Undefined character style"), - s, it.paragraph().id(), it.pos(), it.pos() + 1)); - } else if (inset.undefined()) { - // The character style is undefined in - // tclass1 and is defined in tclass2 - inset.setDefined(found_cs); - } - } + InsetCollapsable * inset = it->asInsetCollapsable(); + if (!inset) + continue; + if (inset->lyxCode() != FLEX_CODE) + // FIXME: Should we verify all InsetCollapsable? + continue; + inset->setLayout(newone); + if (!inset->undefined()) + continue; + // The flex inset is undefined in newtc + docstring const s = bformat(_( + "Flex inset %1$s is " + "undefined because of class " + "conversion from\n%2$s to %3$s"), + inset->name(), from_utf8(oldtc.name()), + from_utf8(newtc.name())); + // 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)); } } -std::vector const availableSelections(Buffer const & buffer) +vector const availableSelections(Buffer const & buffer) { vector selList; @@ -492,7 +472,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,11 +500,13 @@ 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); + cur.recordUndoSelection(); pit_type begpit = cur.selBegin().pit(); pit_type endpit = cur.selEnd().pit(); @@ -536,7 +518,7 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) text->paragraphs(), begpit, endpit, cur.selBegin().pos(), endpos, - bp.textclass, theCuts); + bp.textClassPtr(), theCuts); // Stuff what we got on the clipboard. // Even if there is no selection. putClipboard(theCuts[0].first, theCuts[0].second, @@ -547,8 +529,7 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) eraseSelectionHelper(bp, text->paragraphs(), begpit, endpit, - cur.selBegin().pos(), endpos, - doclear); + cur.selBegin().pos(), endpos); // cutSelection can invalidate the cursor so we need to set // it anew. (Lgb) @@ -557,14 +538,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); @@ -574,11 +554,11 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) if (cur.selBegin().idx() != cur.selEnd().idx()) { // The current selection spans more than one cell. // Record all cells - recordUndoInset(cur); + cur.recordUndoInset(); } else { // Record only the current cell to avoid a jumping // cursor after undo - recordUndo(cur); + cur.recordUndo(); } if (realcut) copySelection(cur); @@ -601,8 +581,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 @@ -617,7 +601,9 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) ++pos; copySelectionHelper(cur.buffer(), pars, par, cur.selEnd().pit(), - pos, cur.selEnd().pos(), cur.buffer().params().textclass, cutstack); + pos, cur.selEnd().pos(), + cur.buffer().params().textClassPtr(), cutstack); + dirtyTabularStack(false); } if (cur.inMathed()) { @@ -625,10 +611,10 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) ParagraphList pars; Paragraph par; BufferParams const & bp = cur.buffer().params(); - par.layout(bp.getLyXTextClass().defaultLayout()); - par.insert(0, grabSelection(cur), LyXFont(), Change(Change::UNCHANGED)); + par.setLayout(bp.textClass().defaultLayout()); + par.insert(0, grabSelection(cur), Font(), Change(Change::UNCHANGED)); pars.push_back(par); - cutstack.push(make_pair(pars, bp.textclass)); + cutstack.push(make_pair(pars, bp.textClassPtr())); } } @@ -645,19 +631,20 @@ 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 attempt 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.insert(0, plaintext, LyXFont(), Change(Change::UNCHANGED)); + par.setLayout(bp.textClass().defaultLayout()); + par.insert(0, plaintext, Font(), Change(Change::UNCHANGED)); pars.push_back(par); - theCuts.push(make_pair(pars, bp.textclass)); - } else + theCuts.push(make_pair(pars, bp.textClassPtr())); + } else { copySelectionToStack(cur, theCuts); + } // stuff the selection onto the X clipboard, from an explicit copy request putClipboard(theCuts[0].first, theCuts[0].second, plaintext); @@ -666,14 +653,15 @@ 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, "'" << cur.selectionAsString(true) << "'"); copySelectionToStack(cur, selectionBuffer); - // tell X whether we now have a valid selection - theSelection().haveSelection(cur.selection()); + } } @@ -689,6 +677,12 @@ void clearSelection() } +void clearCutStack() +{ + theCuts.clear(); +} + + docstring getSelection(Buffer const & buf, size_t sel_index) { return sel_index < theCuts.size() @@ -698,21 +692,20 @@ docstring getSelection(Buffer const & buf, size_t sel_index) void pasteParagraphList(Cursor & cur, ParagraphList const & parlist, - textclass_type textclass, ErrorList & errorList) + TextClassPtr textclass, ErrorList & errorList) { if (cur.inTexted()) { - LyXText * text = cur.text(); + Text * text = cur.text(); BOOST_ASSERT(text); pit_type endpit; PitPosPair ppp; boost::tie(ppp, endpit) = - pasteSelectionHelper(cur, parlist, - textclass, errorList); + pasteSelectionHelper(cur, 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 @@ -726,15 +719,14 @@ void pasteFromStack(Cursor & cur, ErrorList & errorList, size_t sel_index) if (!checkPastePossible(sel_index)) return; - recordUndo(cur); + cur.recordUndo(); pasteParagraphList(cur, theCuts[sel_index].first, theCuts[sel_index].second, errorList); cur.setSelection(); - saveSelection(cur); } -void pasteClipboard(Cursor & cur, ErrorList & errorList, bool asParagraphs) +void pasteClipboardText(Cursor & cur, ErrorList & errorList, bool asParagraphs) { // Use internal clipboard if it is the most recent one if (theClipboard().isInternal()) { @@ -751,9 +743,9 @@ void pasteClipboard(Cursor & cur, ErrorList & errorList, bool asParagraphs) Buffer buffer("", false); buffer.setUnnamed(true); if (buffer.readString(lyx)) { - recordUndo(cur); + cur.recordUndo(); pasteParagraphList(cur, buffer.paragraphs(), - buffer.params().textclass, errorList); + buffer.params().textClassPtr(), errorList); cur.setSelection(); return; } @@ -764,7 +756,7 @@ void pasteClipboard(Cursor & cur, ErrorList & errorList, bool asParagraphs) docstring const text = theClipboard().getAsText(); if (text.empty()) return; - recordUndo(cur); + cur.recordUndo(); if (asParagraphs) cur.text()->insertStringAsParagraphs(cur, text); else @@ -772,24 +764,43 @@ void pasteClipboard(Cursor & cur, ErrorList & errorList, bool asParagraphs) } +void pasteClipboardGraphics(Cursor & cur, ErrorList & /* errorList */, + Clipboard::GraphicsType preferedType) +{ + BOOST_ASSERT(theClipboard().hasGraphicsContents(preferedType)); + + // get picture from clipboard + FileName filename = theClipboard().getAsGraphics(cur, preferedType); + if (filename.empty()) + return; + + // create inset for graphic + InsetGraphics * inset = new InsetGraphics; + InsetGraphicsParams params; + params.filename = EmbeddedFile(filename.absFilename(), cur.buffer().filePath()); + inset->setParams(params); + cur.recordUndo(); + cur.insert(inset); +} + + void pasteSelection(Cursor & cur, ErrorList & errorList) { if (selectionBuffer.empty()) return; - recordUndo(cur); + cur.recordUndo(); pasteParagraphList(cur, selectionBuffer[0].first, - selectionBuffer[0].second, errorList); - cur.setSelection(); + selectionBuffer[0].second, errorList); } void replaceSelectionWithString(Cursor & cur, docstring const & str, bool backwards) { - recordUndo(cur); + cur.recordUndo(); DocIterator selbeg = cur.selectionBegin(); // Get font setting before we cut - LyXFont const font = + Font const font = selbeg.paragraph().getFontSettings(cur.buffer().params(), selbeg.pos()); // Insert the new string @@ -809,7 +820,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 +836,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 +857,6 @@ void eraseSelection(Cursor & cur) } // need a valid cursor. (Lgb) cur.clearSelection(); - theSelection().haveSelection(false); } else { lyxerr << "can't erase this selection 1" << endl; } @@ -879,7 +889,7 @@ docstring grabSelection(Cursor const & cur) // FIXME: What is wrong with the following? #if 0 - std::ostringstream os; + ostringstream os; for (DocIterator dit = cur.selectionBegin(); dit != cur.selectionEnd(); dit.forwardPos()) os << asString(dit.cell());