X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.C;h=e554ac6311098839dcff14ca605c8e4445001370;hb=52eb91c94fb70d58dceef430659c8781de2eccda;hp=7a22cfc335d20ada62e9787142683096571c98b6;hpb=e89625ef28143545a511cdabc67dee8b7be1b216;p=lyx.git diff --git a/src/CutAndPaste.C b/src/CutAndPaste.C index 7a22cfc335..e554ac6311 100644 --- a/src/CutAndPaste.C +++ b/src/CutAndPaste.C @@ -6,6 +6,7 @@ * \author Jürgen Vigna * \author Lars Gullik Bjønnes * \author Alfredo Braunstein + * \author Michael Gerz * * Full author contact details are available in file CREDITS. */ @@ -17,7 +18,6 @@ #include "buffer.h" #include "buffer_funcs.h" #include "bufferparams.h" -#include "BufferView.h" #include "cursor.h" #include "debug.h" #include "errorlist.h" @@ -26,13 +26,13 @@ #include "insetiterator.h" #include "language.h" #include "lfuns.h" +#include "lyxfunc.h" #include "lyxrc.h" #include "lyxtext.h" #include "lyxtextclasslist.h" #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" -#include "ParagraphList_fwd.h" #include "pariterator.h" #include "undo.h" @@ -45,20 +45,13 @@ #include "support/lstrings.h" -#include "frontends/Gui.h" -#include "frontends/LyXView.h" #include "frontends/Clipboard.h" +#include "frontends/Selection.h" +#include #include -using lyx::pos_type; -using lyx::pit_type; -using lyx::textclass_type; - -using lyx::support::bformat; - -using lyx::frontend::Gui; -using lyx::frontend::Clipboard; +#include using std::endl; using std::for_each; @@ -68,36 +61,25 @@ using std::vector; using std::string; +namespace lyx { + +using support::bformat; +using frontend::Clipboard; + namespace { -typedef std::pair PitPosPair; +typedef std::pair PitPosPair; typedef limited_stack > CutStack; CutStack theCuts(10); +// persistent selection, cleared until the next selection +CutStack selectionBuffer(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, // when we (hopefully) have a one-for-all paste mechanism. -bool dirty_tabular_stack_; - -class resetParagraph : public std::unary_function { -public: - resetParagraph(Buffer const & b) : buffer_(b) {} - void operator()(Paragraph & p) const { - p.cleanChanges(); - // ERT paragraphs have the Language latex_language. - // This is invalid outside of ERT, so we need to change it - // to the buffer language. - if (p.ownerCode() == InsetBase::ERT_CODE) { - p.changeLanguage(buffer_.params(), latex_language, - buffer_.getLanguage()); - } - p.setInsetOwner(0); - } -private: - Buffer const & buffer_; -}; +bool dirty_tabular_stack_ = false; void region(CursorSlice const & i1, CursorSlice const & i2, @@ -123,11 +105,14 @@ bool checkPastePossible(int index) pair -pasteSelectionHelper(Buffer const & buffer, - ParagraphList & pars, pit_type pit, int pos, - ParagraphList const & parlist, textclass_type textclass, - ErrorList & errorlist) +pasteSelectionHelper(LCursor & cur, ParagraphList const & parlist, + textclass_type textclass, ErrorList & errorlist) { + Buffer const & buffer = cur.buffer(); + pit_type pit = cur.pit(); + pos_type pos = cur.pos(); + ParagraphList & pars = cur.text()->paragraphs(); + if (parlist.empty()) return make_pair(PitPosPair(pit, pos), pit); @@ -147,7 +132,8 @@ pasteSelectionHelper(Buffer const & buffer, 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)) { - insertion[i].erase(j); + // do not track deletion of newline + insertion[i].eraseChar(j, false); breakParagraphConservative( buffer.params(), insertion, i, j); @@ -156,6 +142,17 @@ pasteSelectionHelper(Buffer const & buffer, } } + // 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(); + ParagraphList::iterator const end = insertion.end(); + for (ParagraphList::iterator par = insertion.begin(); + par != end; ++par) + par->layout(layout); + } + // Make sure there is no class difference. InsetText in; // This works without copying any paragraph data because we have @@ -163,13 +160,13 @@ pasteSelectionHelper(Buffer const & buffer, // since we store pointers to insets at some places and we don't // want to invalidate them. insertion.swap(in.paragraphs()); - lyx::cap::switchBetweenClasses(textclass, tc, in, errorlist); + cap::switchBetweenClasses(textclass, tc, in, errorlist); insertion.swap(in.paragraphs()); ParagraphList::iterator tmpbuf = insertion.begin(); int depth_delta = pars[pit].params().depth() - tmpbuf->params().depth(); - Paragraph::depth_type max_depth = pars[pit].getMaxDepthAfter(); + depth_type max_depth = pars[pit].getMaxDepthAfter(); for (; tmpbuf != insertion.end(); ++tmpbuf) { // If we have a negative jump so that the depth would @@ -195,14 +192,12 @@ pasteSelectionHelper(Buffer const & buffer, for (pos_type i = 0; i < tmpbuf->size(); ++i) { if (tmpbuf->getChar(i) == Paragraph::META_INSET && !pars[pit].insetAllowed(tmpbuf->getInset(i)->lyxCode())) - tmpbuf->erase(i--); + // do not track deletion of invalid insets + tmpbuf->eraseChar(i--, false); } - // reset change tracking status - if (buffer.params().tracking_changes) - tmpbuf->cleanChanges(Paragraph::trackingOn); - else - tmpbuf->cleanChanges(Paragraph::trackingOff); + tmpbuf->setChange(Change(buffer.params().trackChanges ? + Change::INSERTED : Change::UNCHANGED)); } bool const empty = pars[pit].empty(); @@ -220,8 +215,8 @@ pasteSelectionHelper(Buffer const & buffer, ParIterator fend = par_iterator_end(in); for (; fpit != fend; ++fpit) { - InsetList::iterator lit = fpit->insetlist.begin(); - InsetList::iterator eit = fpit->insetlist.end(); + InsetList::const_iterator lit = fpit->insetlist.begin(); + InsetList::const_iterator eit = fpit->insetlist.end(); for (; lit != eit; ++lit) { switch (lit->inset->lyxCode()) { @@ -278,7 +273,7 @@ pasteSelectionHelper(Buffer const & buffer, pars[last_paste].makeSameLayout(pars[last_paste + 1]); mergeParagraph(buffer.params(), pars, last_paste); } else { - pars[last_paste + 1].stripLeadingSpaces(); + pars[last_paste + 1].stripLeadingSpaces(buffer.params().trackChanges); ++last_paste; } } @@ -298,30 +293,26 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, return PitPosPair(endpit, endpos); // Start and end is inside same paragraph - if (endpit == pit_type(pars.size()) || - startpit == endpit) { - endpos -= pars[startpit].erase(startpos, endpos); + if (endpit == pit_type(pars.size()) || startpit == endpit) { + endpos -= pars[startpit].eraseChars(startpos, endpos, params.trackChanges); return PitPosPair(endpit, endpos); } - // 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: + pos_type const left = (pit == startpit ? startpos : 0); + pos_type const 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 + pars[pit].eraseChars(left, right, params.trackChanges); + + // Separate handling of paragraph break: if (merge && pit != endpit && - (pit + 1 != endpit || pars[pit].hasSameLayout(pars[pit + 1]))) { + (pit + 1 != endpit || pars[pit].hasSameLayout(pars[pit + 1]))) { pos_type const thissize = pars[pit].size(); if (doclear) - pars[pit + 1].stripLeadingSpaces(); + pars[pit + 1].stripLeadingSpaces(params.trackChanges); mergeParagraph(params, pars, pit); --endpit; if (pit == endpit) @@ -337,29 +328,66 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, } +void putClipboard(ParagraphList const & paragraphs, textclass_type 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; + if (buffer.write(lyx)) + theClipboard().put(lyx.str(), plaintext); + else + theClipboard().put(string(), plaintext); +} + + void copySelectionHelper(Buffer const & buf, ParagraphList & pars, pit_type startpit, pit_type endpit, - int start, int end, textclass_type tc) + int start, int end, textclass_type tc, CutStack & cutstack) { BOOST_ASSERT(0 <= start && start <= pars[startpit].size()); BOOST_ASSERT(0 <= end && end <= pars[endpit].size()); BOOST_ASSERT(startpit != endpit || start <= end); // Clone the paragraphs within the selection. - ParagraphList paragraphs(boost::next(pars.begin(), startpit), - boost::next(pars.begin(), endpit + 1)); + ParagraphList copy_pars(boost::next(pars.begin(), startpit), + boost::next(pars.begin(), endpit + 1)); + + // Remove the end of the last paragraph; afterwards, remove the beginning + // of the first paragraph. Keep this order - there may only be one paragraph! + // Do not track deletions here; this is an internal action not visible to the user + Paragraph & back = copy_pars.back(); + back.eraseChars(end, back.size(), false); + Paragraph & front = copy_pars.front(); + front.eraseChars(0, start, false); - for_each(paragraphs.begin(), paragraphs.end(), resetParagraph(buf)); + ParagraphList::iterator it = copy_pars.begin(); + ParagraphList::iterator it_end = copy_pars.end(); - // Cut out the end of the last paragraph. - Paragraph & back = paragraphs.back(); - back.erase(end, back.size()); + for (; it != it_end; it++) { + // 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() == InsetBase::ERT_CODE) { + it->changeLanguage(buf.params(), latex_language, + buf.getLanguage()); + } + it->setInsetOwner(0); + } - // Cut out the begin of the first paragraph - Paragraph & front = paragraphs.front(); - front.erase(0, start); + // 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()); - theCuts.push(make_pair(paragraphs, tc)); + cutstack.push(make_pair(copy_pars, tc)); } } // namespace anon @@ -367,14 +395,13 @@ void copySelectionHelper(Buffer const & buf, ParagraphList & pars, -namespace lyx { namespace cap { -string grabAndEraseSelection(LCursor & cur) +docstring grabAndEraseSelection(LCursor & cur) { if (!cur.selection()) - return string(); - string res = grabSelection(cur); + return docstring(); + docstring res = grabSelection(cur); eraseSelection(cur); return res; } @@ -405,8 +432,8 @@ 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"), - lyx::from_utf8(name), lyx::from_utf8(it->layout()->name()), - lyx::from_utf8(tclass1.name()), lyx::from_utf8(tclass2.name())); + from_utf8(name), from_utf8(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, it->id(), 0, @@ -430,8 +457,8 @@ void switchBetweenClasses(textclass_type c1, textclass_type c2, "Character style %1$s is " "undefined because of class " "conversion from\n%2$s to %3$s"), - lyx::from_utf8(name), lyx::from_utf8(tclass1.name()), - lyx::from_utf8(tclass2.name())); + 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"), @@ -446,9 +473,9 @@ void switchBetweenClasses(textclass_type c1, textclass_type c2, } -std::vector const availableSelections(Buffer const & buffer) +std::vector const availableSelections(Buffer const & buffer) { - vector selList; + vector selList; CutStack::const_iterator cit = theCuts.begin(); CutStack::const_iterator end = theCuts.end(); @@ -456,13 +483,14 @@ std::vector const availableSelections(Buffer const & buffer) // we do not use cit-> here because gcc 2.9x does not // like it (JMarc) ParagraphList const & pars = (*cit).first; - string asciiSel; + docstring asciiSel; ParagraphList::const_iterator pit = pars.begin(); ParagraphList::const_iterator pend = pars.end(); for (; pit != pend; ++pit) { asciiSel += pit->asString(buffer, false); if (asciiSel.size() > 25) { - asciiSel.replace(22, string::npos, "..."); + asciiSel.replace(22, docstring::npos, + from_ascii("...")); break; } } @@ -474,7 +502,7 @@ std::vector const availableSelections(Buffer const & buffer) } -lyx::size_type numberOfSelections() +size_type numberOfSelections() { return theCuts.size(); } @@ -492,16 +520,6 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut) if (cur.inTexted()) { LyXText * text = cur.text(); BOOST_ASSERT(text); - // Stuff what we got on the clipboard. Even if there is no selection. - - // There is a problem with having the stuffing here in that the - // larger the selection the slower LyX will get. This can be - // solved by running the line below only when the selection has - // finished. The solution used currently just works, to make it - // faster we need to be more clever and probably also have more - // calls to cur.bv().owner()->gui().selection().put. (Lgb) -// cur.bv().owner()->gui().selection().put(cur.selectionAsString(true)); - // make sure that the depth behind the selection are restored, too recordUndoSelection(cur); @@ -516,7 +534,11 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut) text->paragraphs(), begpit, endpit, cur.selBegin().pos(), endpos, - bp.textclass); + bp.textclass, theCuts); + // Stuff what we got on the clipboard. + // Even if there is no selection. + putClipboard(theCuts[0].first, theCuts[0].second, + cur.selectionAsString(true)); } boost::tie(endpit, endpos) = @@ -526,19 +548,21 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut) cur.selBegin().pos(), endpos, doclear); - // sometimes necessary - if (doclear) - text->paragraphs()[begpit].stripLeadingSpaces(); - // cutSelection can invalidate the cursor so we need to set // it anew. (Lgb) // we prefer the end for when tracking changes cur.pos() = endpos; cur.pit() = endpit; + // sometimes necessary + 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); @@ -563,9 +587,14 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut) void copySelection(LCursor & cur) { - // stuff the selection onto the X clipboard, from an explicit copy request - cur.bv().owner()->gui().clipboard().put(cur.selectionAsString(true)); + copySelection(cur, cur.selectionAsString(true)); +} + +namespace { + +void copySelectionToStack(LCursor & cur, CutStack & cutstack) +{ // this doesn't make sense, if there is no selection if (!cur.selection()) return; @@ -580,35 +609,90 @@ void copySelection(LCursor & cur) ParagraphList & pars = text->paragraphs(); pos_type pos = cur.selBegin().pos(); pit_type par = cur.selBegin().pit(); - while (pos < pars[par].size() - && pars[par].isLineSeparator(pos) - && (par != cur.selEnd().pit() || pos < cur.selEnd().pos())) + while (pos < pars[par].size() && + pars[par].isLineSeparator(pos) && + (par != cur.selEnd().pit() || pos < cur.selEnd().pos())) ++pos; copySelectionHelper(cur.buffer(), pars, par, cur.selEnd().pit(), - pos, cur.selEnd().pos(), cur.buffer().params().textclass); + pos, cur.selEnd().pos(), cur.buffer().params().textclass, cutstack); } if (cur.inMathed()) { //lyxerr << "copySelection in mathed" << endl; ParagraphList pars; - pars.push_back(Paragraph()); + Paragraph par; BufferParams const & bp = cur.buffer().params(); - pars.back().layout(bp.getLyXTextClass().defaultLayout()); - for_each(pars.begin(), pars.end(), resetParagraph(cur.buffer())); - pars.back().insert(0, grabSelection(cur), LyXFont()); - theCuts.push(make_pair(pars, bp.textclass)); + par.layout(bp.getLyXTextClass().defaultLayout()); + par.insert(0, grabSelection(cur), LyXFont(), Change(Change::UNCHANGED)); + pars.push_back(par); + cutstack.push(make_pair(pars, bp.textclass)); } - // tell tabular that a recent copy happened - dirtyTabularStack(false); +} + +} + + +void copySelectionToStack() +{ + if (!selectionBuffer.empty()) + theCuts.push(selectionBuffer[0]); +} + + +void copySelection(LCursor & 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 + // 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)); + pars.push_back(par); + theCuts.push(make_pair(pars, bp.textclass)); + } else + copySelectionToStack(cur, theCuts); + + // stuff the selection onto the X clipboard, from an explicit copy request + putClipboard(theCuts[0].first, theCuts[0].second, plaintext); +} + + +void saveSelection(LCursor & cur) +{ + if (lyxerr.debugging(Debug::ACTION)) + lyxerr << BOOST_CURRENT_FUNCTION << ": `" + << to_utf8(cur.selectionAsString(true)) << "'." + << endl; + + if (cur.selection()) + copySelectionToStack(cur, selectionBuffer); + // tell X whether we now have a valid selection + theSelection().haveSelection(cur.selection()); +} + + +bool selection() +{ + return !selectionBuffer.empty(); +} + + +void clearSelection() +{ + selectionBuffer.clear(); } -std::string getSelection(Buffer const & buf, size_t sel_index) +docstring getSelection(Buffer const & buf, size_t sel_index) { return sel_index < theCuts.size() ? theCuts[sel_index].first.back().asString(buf, false) - : string(); + : docstring(); } @@ -619,20 +703,15 @@ void pasteParagraphList(LCursor & cur, ParagraphList const & parlist, LyXText * text = cur.text(); BOOST_ASSERT(text); - recordUndo(cur); - pit_type endpit; PitPosPair ppp; boost::tie(ppp, endpit) = - pasteSelectionHelper(cur.buffer(), - text->paragraphs(), - cur.pit(), cur.pos(), - parlist, textclass, - errorList); + pasteSelectionHelper(cur, parlist, + textclass, errorList); updateLabels(cur.buffer()); cur.clearSelection(); - text->setCursor(cur, ppp.first, ppp.second); + text->setCursor(cur.top(), ppp.first, ppp.second); } // mathed is handled in InsetMathNest/InsetMathGrid @@ -640,20 +719,70 @@ void pasteParagraphList(LCursor & cur, ParagraphList const & parlist, } -void pasteSelection(LCursor & cur, ErrorList & errorList, size_t sel_index) +void pasteFromStack(LCursor & cur, ErrorList & errorList, size_t sel_index) { // this does not make sense, if there is nothing to paste if (!checkPastePossible(sel_index)) return; + recordUndo(cur); pasteParagraphList(cur, theCuts[sel_index].first, theCuts[sel_index].second, errorList); cur.setSelection(); + saveSelection(cur); +} + + +void pasteClipboard(LCursor & cur, ErrorList & errorList, bool asParagraphs) +{ + // Use internal clipboard if it is the most recent one + if (theClipboard().isInternal()) { + pasteFromStack(cur, errorList, 0); + return; + } + + // First try LyX format + if (theClipboard().hasLyXContents()) { + string lyx = theClipboard().getAsLyX(); + if (!lyx.empty()) { + // For some strange reason gcc 3.2 and 3.3 do not accept + // Buffer buffer(string(), false); + Buffer buffer("", false); + buffer.setUnnamed(true); + if (buffer.readString(lyx)) { + recordUndo(cur); + pasteParagraphList(cur, buffer.paragraphs(), + buffer.params().textclass, errorList); + cur.setSelection(); + return; + } + } + } + + // Then try plain text + docstring const text = theClipboard().getAsText(); + if (text.empty()) + return; + recordUndo(cur); + if (asParagraphs) + cur.text()->insertStringAsParagraphs(cur, text); + else + cur.text()->insertStringAsLines(cur, text); +} + + +void pasteSelection(LCursor & cur, ErrorList & errorList) +{ + if (selectionBuffer.empty()) + return; + recordUndo(cur); + pasteParagraphList(cur, selectionBuffer[0].first, + selectionBuffer[0].second, errorList); + cur.setSelection(); } -// simple replacing. The font of the first selected character is used -void replaceSelectionWithString(LCursor & cur, string const & str, bool backwards) +void replaceSelectionWithString(LCursor & cur, docstring const & str, bool backwards) { recordUndo(cur); DocIterator selbeg = cur.selectionBegin(); @@ -665,10 +794,10 @@ void replaceSelectionWithString(LCursor & cur, string const & str, bool backward // Insert the new string pos_type pos = cur.selEnd().pos(); Paragraph & par = cur.selEnd().paragraph(); - string::const_iterator cit = str.begin(); - string::const_iterator end = str.end(); + docstring::const_iterator cit = str.begin(); + docstring::const_iterator end = str.end(); for (; cit != end; ++cit, ++pos) - par.insertChar(pos, (*cit), font); + par.insertChar(pos, *cit, font, cur.buffer().params().trackChanges); // Cut the selection cutSelection(cur, true, false); @@ -676,9 +805,10 @@ void replaceSelectionWithString(LCursor & cur, string const & str, bool backward // select the replacement if (backwards) { selbeg.pos() += str.length(); - cur.setSelection(selbeg, -str.length()); + cur.setSelection(selbeg, -int(str.length())); } else cur.setSelection(selbeg, str.length()); + saveSelection(cur); } @@ -691,7 +821,7 @@ void replaceSelection(LCursor & cur) void eraseSelection(LCursor & cur) { - //lyxerr << "LCursor::eraseSelection begin: " << cur << endl; + //lyxerr << "cap::eraseSelection begin: " << cur << endl; CursorSlice const & i1 = cur.selBegin(); CursorSlice const & i2 = cur.selEnd(); if (i1.inset().asInsetMath()) { @@ -715,16 +845,17 @@ void eraseSelection(LCursor & cur) } // need a valid cursor. (Lgb) cur.clearSelection(); + theSelection().haveSelection(false); } else { lyxerr << "can't erase this selection 1" << endl; } - //lyxerr << "LCursor::eraseSelection end: " << cur << endl; + //lyxerr << "cap::eraseSelection end: " << cur << endl; } void selDel(LCursor & cur) { - //lyxerr << "LCursor::selDel" << endl; + //lyxerr << "cap::selDel" << endl; if (cur.selection()) eraseSelection(cur); } @@ -732,7 +863,7 @@ void selDel(LCursor & cur) void selClearOrDel(LCursor & cur) { - //lyxerr << "LCursor::selClearOrDel" << endl; + //lyxerr << "cap::selClearOrDel" << endl; if (lyxrc.auto_region_delete) selDel(cur); else @@ -740,10 +871,10 @@ void selClearOrDel(LCursor & cur) } -string grabSelection(LCursor const & cur) +docstring grabSelection(LCursor const & cur) { if (!cur.selection()) - return string(); + return docstring(); // FIXME: What is wrong with the following? #if 0 @@ -762,7 +893,7 @@ string grabSelection(LCursor const & cur) MathArray::const_iterator it = i1.cell().begin(); return asString(MathArray(it + i1.pos(), it + i2.pos())); } else { - return "unknown selection 1"; + return from_ascii("unknown selection 1"); } } @@ -770,7 +901,7 @@ string grabSelection(LCursor const & cur) InsetBase::col_type c1, c2; region(i1, i2, r1, r2, c1, c2); - string data; + docstring data; if (i1.inset().asInsetMath()) { for (InsetBase::row_type row = r1; row <= r2; ++row) { if (row > r1) @@ -783,7 +914,7 @@ string grabSelection(LCursor const & cur) } } } else { - data = "unknown selection 2"; + data = from_ascii("unknown selection 2"); } return data; } @@ -802,4 +933,5 @@ bool tabularStackDirty() } // namespace cap + } // namespace lyx