X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.cpp;h=f657d57cbde9d0a876bc52c623142cb96964902f;hb=6b651f2ad9f698c01993dcc6e340682c279f1c55;hp=7aeed7a2cdd60f07f8dd005ca7bd91e0d9a7e6f8;hpb=12e1d4bc8d0fc7daa015e74028be2d7b2860d69f;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 7aeed7a2cd..f657d57cbd 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -19,18 +19,17 @@ #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 "Text.h" -#include "TextClass_ptr.h" #include "TextClassList.h" #include "Paragraph.h" #include "paragraph_funcs.h" @@ -39,40 +38,39 @@ #include "Undo.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 @@ -92,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); } @@ -108,7 +106,7 @@ bool checkPastePossible(int index) pair pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, - TextClass_ptr textclass, ErrorList & errorlist) + TextClassPtr textclass, ErrorList & errorlist) { Buffer const & buffer = cur.buffer(); pit_type pit = cur.pit(); @@ -122,7 +120,7 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist, // Make a copy of the CaP paragraphs. ParagraphList insertion = parlist; - TextClass_ptr const tc = buffer.params().getTextClass_ptr(); + TextClassPtr const tc = buffer.params().getTextClassPtr(); // Now remove all out of the pars which is NOT allowed in the // new environment and set also another font if that is required. @@ -130,8 +128,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::LISTINGS_CODE)) { + (pars[pit].inInset()->lyxCode() == ERT_CODE || + pars[pit].inInset()->lyxCode() == 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)) { @@ -193,7 +191,7 @@ 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 && + if (tmpbuf->isInset(i) && !pars[pit].insetAllowed(tmpbuf->getInset(i)->lyxCode())) // do not track deletion of invalid insets tmpbuf->eraseChar(i--, false); @@ -218,12 +216,12 @@ 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(); + 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: { + case TABULAR_CODE: { InsetTabular * it = static_cast(lit->inset); it->buffer(&buffer); break; @@ -327,7 +325,7 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, } -void putClipboard(ParagraphList const & paragraphs, TextClass_ptr textclass, +void putClipboard(ParagraphList const & paragraphs, TextClassPtr textclass, docstring const & plaintext) { // For some strange reason gcc 3.2 and 3.3 do not accept @@ -336,7 +334,7 @@ void putClipboard(ParagraphList const & paragraphs, TextClass_ptr textclass, buffer.setUnnamed(true); buffer.paragraphs() = paragraphs; buffer.params().setTextClass(textclass); - std::ostringstream lyx; + ostringstream lyx; if (buffer.write(lyx)) theClipboard().put(lyx.str(), plaintext); else @@ -346,7 +344,7 @@ void putClipboard(ParagraphList const & paragraphs, TextClass_ptr textclass, void copySelectionHelper(Buffer const & buf, ParagraphList & pars, pit_type startpit, pit_type endpit, - int start, int end, TextClass_ptr 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()); @@ -373,9 +371,8 @@ 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->ownerCode() == Inset::LISTINGS_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); } @@ -403,8 +400,8 @@ docstring grabAndEraseSelection(Cursor & cur) } -void switchBetweenClasses(TextClass_ptr const & c1, - TextClass_ptr const & c2, InsetText & in, ErrorList & errorlist) +void switchBetweenClasses(TextClassPtr const & c1, + TextClassPtr const & c2, InsetText & in, ErrorList & errorlist) { errorlist.clear(); @@ -442,32 +439,33 @@ void switchBetweenClasses(TextClass_ptr const & c1, // 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::FLEX_CODE) { - InsetFlex & inset = - static_cast(*it); - string const name = inset.params().name; - InsetLayout const il = - tclass2.insetlayout(from_utf8(name)); - inset.setLayout(il); - if (il.labelstring == from_utf8("UNDEFINED")) { - // The flex inset is undefined in tclass2 - docstring const s = bformat(_( - "Flex inset %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 flex inset"), - s, it.paragraph().id(), it.pos(), it.pos() + 1)); - } - } + InsetCollapsable * inset = it->asInsetCollapsable(); + if (!inset) + continue; + if (inset->lyxCode() != FLEX_CODE) + // FIXME: Should we verify all InsetCollapsable? + continue; + docstring const name = inset->name(); + InsetLayout const & il = tclass2.insetlayout(name); + inset->setLayout(il); + if (il.labelstring != from_utf8("UNDEFINED")) + continue; + // The flex inset is undefined in tclass2 + docstring const s = bformat(_( + "Flex inset %1$s is " + "undefined because of class " + "conversion from\n%2$s to %3$s"), + name, from_utf8(tclass1.name()), + from_utf8(tclass2.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; @@ -518,7 +516,7 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) 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(); @@ -530,7 +528,7 @@ void cutSelection(Cursor & cur, bool doclear, bool realcut) text->paragraphs(), begpit, endpit, cur.selBegin().pos(), endpos, - bp.getTextClass_ptr(), theCuts); + bp.getTextClassPtr(), theCuts); // Stuff what we got on the clipboard. // Even if there is no selection. putClipboard(theCuts[0].first, theCuts[0].second, @@ -566,11 +564,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); @@ -614,7 +612,7 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) copySelectionHelper(cur.buffer(), pars, par, cur.selEnd().pit(), pos, cur.selEnd().pos(), - cur.buffer().params().getTextClass_ptr(), cutstack); + cur.buffer().params().getTextClassPtr(), cutstack); dirtyTabularStack(false); } @@ -626,7 +624,7 @@ void copySelectionToStack(Cursor & cur, CutStack & cutstack) par.layout(bp.getTextClass().defaultLayout()); par.insert(0, grabSelection(cur), Font(), Change(Change::UNCHANGED)); pars.push_back(par); - cutstack.push(make_pair(pars, bp.getTextClass_ptr())); + cutstack.push(make_pair(pars, bp.getTextClassPtr())); } } @@ -643,7 +641,7 @@ 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()) { @@ -653,9 +651,10 @@ void copySelection(Cursor & cur, docstring const & plaintext) par.layout(bp.getTextClass().defaultLayout()); par.insert(0, plaintext, Font(), Change(Change::UNCHANGED)); pars.push_back(par); - theCuts.push(make_pair(pars, bp.getTextClass_ptr())); - } else + theCuts.push(make_pair(pars, bp.getTextClassPtr())); + } else { copySelectionToStack(cur, theCuts); + } // stuff the selection onto the X clipboard, from an explicit copy request putClipboard(theCuts[0].first, theCuts[0].second, plaintext); @@ -670,9 +669,7 @@ void saveSelection(Cursor & cur) 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; + LYXERR(Debug::ACTION, "'" << cur.selectionAsString(true) << "'"); copySelectionToStack(cur, selectionBuffer); } } @@ -690,6 +687,12 @@ void clearSelection() } +void clearCutStack() +{ + theCuts.clear(); +} + + docstring getSelection(Buffer const & buf, size_t sel_index) { return sel_index < theCuts.size() @@ -699,7 +702,7 @@ docstring getSelection(Buffer const & buf, size_t sel_index) void pasteParagraphList(Cursor & cur, ParagraphList const & parlist, - TextClass_ptr textclass, ErrorList & errorList) + TextClassPtr textclass, ErrorList & errorList) { if (cur.inTexted()) { Text * text = cur.text(); @@ -727,14 +730,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(); } -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 +754,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().getTextClass_ptr(), errorList); + buffer.params().getTextClassPtr(), errorList); cur.setSelection(); return; } @@ -764,7 +767,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,11 +775,31 @@ 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); } @@ -784,7 +807,7 @@ void pasteSelection(Cursor & cur, ErrorList & errorList) void replaceSelectionWithString(Cursor & cur, docstring const & str, bool backwards) { - recordUndo(cur); + cur.recordUndo(); DocIterator selbeg = cur.selectionBegin(); // Get font setting before we cut @@ -877,7 +900,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());