X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.cpp;h=c8c084a7aac39ff08d44ca21dfeb1c3a0bb6e573;hb=b9e29418471d0d275650c52f976da300f4f42501;hp=be3197cd8c9ceaeb7479f87dcc2876b94eb973da;hpb=e85704020ba613594a38e6f016ca7905c8f84c94;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index be3197cd8c..c8c084a7aa 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -125,10 +125,23 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, if (parlist.empty()) return PasteReturnValue(pit, pos, need_update); + // Check whether we paste into an inset that does not + // produce output (needed for label duplicate check) + bool in_active_inset = cur.paragraph().inInset().producesOutput(); + if (in_active_inset) { + for (size_type sl = 0 ; sl < cur.depth() ; ++sl) { + Paragraph const & outer_par = cur[sl].paragraph(); + if (!outer_par.inInset().producesOutput()) { + in_active_inset = false; + break; + } + } + } + InsetText * target_inset = cur.inset().asInsetText(); if (!target_inset) { InsetTabular * it = cur.inset().asInsetTabular(); - target_inset = it ? it->cell(cur.idx())->asInsetText() : 0; + target_inset = it ? it->cell(cur.idx())->asInsetText() : nullptr; } LASSERT(target_inset, return PasteReturnValue(pit, pos, need_update)); @@ -142,6 +155,14 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, // Now remove all out of the pars which is NOT allowed in the // new environment and set also another font if that is required. + // Merge paragraphs that are to be pasted into a text inset + // that does not allow multiple pars. + InsetText * inset_text = target_inset->asInsetText(); + if (inset_text && !inset_text->allowMultiPar()) { + while (insertion.size() > 1) + mergeParagraph(buffer.params(), insertion, 0); + } + // Convert newline to paragraph break in ParbreakIsNewline if (target_inset->getLayout().parbreakIsNewline() || pars[pit].layout().parbreak_is_newline) { @@ -169,6 +190,9 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, for (size_t i = 0; i != insertion.size(); ++i) { pos_type end = insertion[i].size(); for (pos_type j = 0; j != end; ++j) { + // skip insets + if (insertion[i].isInset(j)) + continue; char_type const c = insertion[i].getChar(j); if (!e->encodable(c)) { // do not track deletion @@ -198,23 +222,19 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, bool forcePlainLayout = target_inset->forcePlainLayout(); Layout const & plainLayout = newDocClass->plainLayout(); Layout const & defaultLayout = newDocClass->defaultLayout(); - ParagraphList::iterator const end = insertion.end(); - ParagraphList::iterator par = insertion.begin(); - for (; par != end; ++par) { - Layout const & parLayout = par->layout(); + for (auto & par : insertion) { + Layout const & parLayout = par.layout(); if (forcePlainLayout || parLayout == defaultLayout) - par->setLayout(plainLayout); + par.setLayout(plainLayout); } } else { // check if we need to reset from plain layout Layout const & defaultLayout = newDocClass->defaultLayout(); Layout const & plainLayout = newDocClass->plainLayout(); - ParagraphList::iterator const end = insertion.end(); - ParagraphList::iterator par = insertion.begin(); - for (; par != end; ++par) { - Layout const & parLayout = par->layout(); + for (auto & par : insertion) { + Layout const & parLayout = par.layout(); if (parLayout == plainLayout) - par->setLayout(defaultLayout); + par.setLayout(defaultLayout); } } @@ -263,8 +283,9 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, tmpbuf->eraseChar(i--, false); } - tmpbuf->setChange(Change(buffer.params().track_changes ? - Change::INSERTED : Change::UNCHANGED)); + if (lyxrc.ct_markup_copied) + tmpbuf->setChange(Change(buffer.params().track_changes ? + Change::INSERTED : Change::UNCHANGED)); } bool const empty = pars[pit].empty(); @@ -280,8 +301,7 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, InsetIterator const i_end = inset_iterator_end(in); for (InsetIterator it = inset_iterator_begin(in); it != i_end; ++it) { // Even though this will also be done later, it has to be done here - // since some inset might going to try to access - // the buffer() member. + // since some inset might try to access the buffer() member. it->setBuffer(const_cast(buffer)); switch (it->lyxCode()) { @@ -294,7 +314,7 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, continue; InsetLabel * lab = labels[i]; docstring const oldname = lab->getParam("name"); - lab->updateLabel(oldname); + lab->updateLabel(oldname, in_active_inset); // We need to update the buffer reference cache. need_update = true; docstring const newname = lab->getParam("name"); @@ -325,7 +345,7 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, // check for duplicates InsetLabel & lab = static_cast(*it); docstring const oldname = lab.getParam("name"); - lab.updateLabel(oldname); + lab.updateLabel(oldname, in_active_inset); // We need to update the buffer reference cache. need_update = true; docstring const newname = lab.getParam("name"); @@ -556,7 +576,7 @@ Buffer * copyToTempBuffer(ParagraphList const & paragraphs, DocumentClassConstPt // Use a clone for the complicated stuff so that we do not need to clean // up in order to avoid a crash. Buffer * buffer = staticbuffer->cloneBufferOnly(); - LASSERT(buffer, return 0); + LASSERT(buffer, return nullptr); // This needs doing every time. // Since setDocumentClass() causes deletion of the old document class @@ -583,7 +603,8 @@ Buffer * copyToTempBuffer(ParagraphList const & paragraphs, DocumentClassConstPt void putClipboard(ParagraphList const & paragraphs, - DocumentClassConstPtr docclass, docstring const & plaintext) + DocumentClassConstPtr docclass, docstring const & plaintext, + BufferParams const bp) { Buffer * buffer = copyToTempBuffer(paragraphs, docclass); if (!buffer) // already asserted in copyToTempBuffer() @@ -594,6 +615,12 @@ void putClipboard(ParagraphList const & paragraphs, // applications, the number that can parse it should go up in the future. buffer->params().html_math_output = BufferParams::MathML; + if (lyxrc.ct_markup_copied) { + // Copy authors to the params. We need those pointers. + for (Author const & a : bp.authors()) + buffer->params().authors().record(a); + } + // Make sure MarkAsExporting is deleted before buffer is { // The Buffer is being used to export. This is necessary so that the @@ -669,37 +696,35 @@ void copySelectionHelper(Buffer const & buf, Text const & text, Paragraph & front = copy_pars.front(); front.eraseChars(0, start, false); - ParagraphList::iterator it = copy_pars.begin(); - ParagraphList::iterator it_end = copy_pars.end(); - - for (; it != it_end; ++it) { + for (auto & par : copy_pars) { // Since we have a copy of the paragraphs, the insets // do not have a proper buffer reference. It makes // sense to add them temporarily, because the // operations below depend on that (acceptChanges included). - it->setInsetBuffers(const_cast(buf)); + par.setInsetBuffers(const_cast(buf)); // PassThru paragraphs have the Language // latex_language. This is invalid for others, so we // need to change it to the buffer language. - if (it->isPassThru()) - it->changeLanguage(buf.params(), + if (par.isPassThru()) + par.changeLanguage(buf.params(), latex_language, buf.language()); } // do not copy text (also nested in insets) which is marked as // deleted, unless the whole selection was deleted - if (!isFullyDeleted(copy_pars)) - acceptChanges(copy_pars, buf.params()); - else - rejectChanges(copy_pars, buf.params()); + if (!lyxrc.ct_markup_copied) { + if (!isFullyDeleted(copy_pars)) + acceptChanges(copy_pars, buf.params()); + else + rejectChanges(copy_pars, buf.params()); + } // do some final cleanup now, to make sure that the paragraphs // are not linked to something else. - it = copy_pars.begin(); - for (; it != it_end; ++it) { - it->resetBuffer(); - it->setInsetOwner(0); + for (auto & par : copy_pars) { + par.resetBuffer(); + par.setInsetOwner(nullptr); } cutstack.push(make_pair(copy_pars, dc)); @@ -816,11 +841,11 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, // character styles and hidden table cells InsetIterator const i_end = inset_iterator_end(in); - for (InsetIterator it = inset_iterator_begin(in); it != i_end; ++it) { - InsetCode const code = it->lyxCode(); + for (InsetIterator iit = inset_iterator_begin(in); iit != i_end; ++iit) { + InsetCode const code = iit->lyxCode(); if (code == FLEX_CODE) { // FIXME: Should we verify all InsetCollapsible? - docstring const layoutName = it->layoutName(); + docstring const layoutName = iit->layoutName(); docstring const & n = newone->insetLayout(layoutName).name(); bool const is_undefined = n.empty() || n == DocumentClass::plainInsetLayout().name(); @@ -841,14 +866,14 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, // To warn the user that something had to be done. errorlist.push_back(ErrorItem( _("Undefined flex inset"), s, - {it.paragraph().id(), it.pos()}, - {it.paragraph().id(), it.pos()+1})); + {iit.paragraph().id(), iit.pos()}, + {iit.paragraph().id(), iit.pos() + 1})); } else if (code == TABULAR_CODE) { // The recursion above does not catch paragraphs in "hidden" cells, // i.e., ones that are part of a multirow or multicolum. So we need // to handle those separately. // This is the cause of bug #9049. - InsetTabular * table = it->asInsetTabular(); + InsetTabular * table = iit->asInsetTabular(); table->setLayoutForHiddenCells(newtc); } } @@ -861,17 +886,11 @@ vector availableSelections(Buffer const * buf) if (!buf) return selList; - CutStack::const_iterator cit = theCuts.begin(); - CutStack::const_iterator end = theCuts.end(); - for (; cit != end; ++cit) { - // we do not use cit-> here because gcc 2.9x does not - // like it (JMarc) - ParagraphList const & pars = (*cit).first; + for (auto const & cut : theCuts) { + ParagraphList const & pars = cut.first; docstring textSel; - ParagraphList::const_iterator pit = pars.begin(); - ParagraphList::const_iterator pend = pars.end(); - for (; pit != pend; ++pit) { - Paragraph par(*pit, 0, 46); + for (auto const & para : pars) { + Paragraph par(para, 0, 46); // adapt paragraph to current buffer. par.setInsetBuffers(const_cast(*buf)); textSel += par.asString(AS_STR_INSETS); @@ -894,7 +913,7 @@ size_type numberOfSelections() namespace { -void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool doclear, bool realcut, bool putclip) +void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool realcut, bool putclip) { // This doesn't make sense, if there is no selection if (!cur.selection()) @@ -927,7 +946,7 @@ void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool doclear, bool realcu // Even if there is no selection. if (putclip) putClipboard(cuts[0].first, cuts[0].second, - cur.selectionAsString(true)); + cur.selectionAsString(true, true), bp); } if (begpit != endpit) @@ -943,11 +962,6 @@ void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool doclear, bool realcu cur.pos() = endpos; cur.pit() = endpit; - // sometimes necessary - if (doclear - && text->paragraphs()[begpit].stripLeadingSpaces(bp.track_changes)) - cur.fixIfBroken(); - // need a valid cursor. (Lgb) cur.clearSelection(); @@ -979,21 +993,21 @@ void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool doclear, bool realcu } // namespace -void cutSelection(Cursor & cur, bool doclear, bool realcut) +void cutSelection(Cursor & cur, bool realcut) { - cutSelectionHelper(cur, theCuts, doclear, realcut, true); + cutSelectionHelper(cur, theCuts, realcut, true); } -void cutSelectionToTemp(Cursor & cur, bool doclear, bool realcut) +void cutSelectionToTemp(Cursor & cur, bool realcut) { - cutSelectionHelper(cur, tempCut, doclear, realcut, false); + cutSelectionHelper(cur, tempCut, realcut, false); } void copySelection(Cursor const & cur) { - copySelection(cur, cur.selectionAsString(true)); + copySelection(cur, cur.selectionAsString(true, true)); } @@ -1009,7 +1023,7 @@ void copyInset(Cursor const & cur, Inset * inset, docstring const & plaintext) theCuts.push(make_pair(pars, bp.documentClassPtr())); // stuff the selection onto the X clipboard, from an explicit copy request - putClipboard(theCuts[0].first, theCuts[0].second, plaintext); + putClipboard(theCuts[0].first, theCuts[0].second, plaintext, bp); } @@ -1048,7 +1062,10 @@ void copySelectionToStack(CursorData const & cur, CutStack & cutstack) BufferParams const & bp = cur.buffer()->params(); // FIXME This should be the plain layout...right? par.setLayout(bp.documentClass().plainLayout()); - par.insert(0, grabSelection(cur), Font(), Change(Change::UNCHANGED)); + // For pasting into text, we set the language to the paragraph language + // (rather than the default_language which is always English; see #2596) + par.insert(0, grabSelection(cur), Font(sane_font, par.getParLanguage(bp)), + Change(Change::UNCHANGED)); pars.push_back(par); cutstack.push(make_pair(pars, bp.documentClassPtr())); } @@ -1064,6 +1081,12 @@ void copySelectionToStack() } +void copySelectionToTemp(Cursor & cur) +{ + copySelectionToStack(cur, tempCut); +} + + void copySelection(Cursor const & cur, docstring const & plaintext) { // In tablemode, because copy and paste actually use special table stack @@ -1083,7 +1106,8 @@ void copySelection(Cursor const & cur, docstring const & plaintext) } // stuff the selection onto the X clipboard, from an explicit copy request - putClipboard(theCuts[0].first, theCuts[0].second, plaintext); + putClipboard(theCuts[0].first, theCuts[0].second, plaintext, + cur.buffer()->params()); } @@ -1095,7 +1119,7 @@ void saveSelection(Cursor const & cur) if (cur.selection() && cur.selBegin() == cur.bv().cursor().selBegin() && cur.selEnd() == cur.bv().cursor().selEnd()) { - LYXERR(Debug::SELECTION, "saveSelection: '" << cur.selectionAsString(true) << "'"); + LYXERR(Debug::SELECTION, "saveSelection: '" << cur.selectionAsString(true, true) << "'"); copySelectionToStack(cur, selectionBuffer); } } @@ -1135,8 +1159,8 @@ docstring selection(size_t sel_index, DocumentClassConstPtr docclass) void pasteParagraphList(Cursor & cur, ParagraphList const & parlist, - DocumentClassConstPtr docclass, ErrorList & errorList, - cap::BranchAction branchAction) + DocumentClassConstPtr docclass, ErrorList & errorList, + cap::BranchAction branchAction) { if (cur.inTexted()) { Text * text = cur.text(); @@ -1195,9 +1219,7 @@ bool pasteClipboardText(Cursor & cur, ErrorList & errorList, bool asParagraphs, theClipboard().hasTextContents(Clipboard::LyXTextType)) { 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 buffer(string(), false); buffer.setUnnamed(true); if (buffer.readString(lyx)) { cur.recordUndo(); @@ -1228,18 +1250,16 @@ bool pasteClipboardText(Cursor & cur, ErrorList & errorList, bool asParagraphs, docstring text = theClipboard().getAsText(types[i]); available = !text.empty(); if (available) { - // For some strange reason gcc 3.2 and 3.3 do not accept - // Buffer buffer(string(), false); - Buffer buffer("", false); + Buffer buffer(string(), false); buffer.setUnnamed(true); available = buffer.importString(names[i], text, errorList); - // TeX2lyx (also used in the HTML chain) assumes English as document language - // if no language is explicitly set (as is the case here). - // We thus reset the temp buffer's language to the context language - buffer.changeLanguage(buffer.language(), cur.getFont().language()); if (available) available = !buffer.paragraphs().empty(); if (available && !buffer.paragraphs()[0].empty()) { + // TeX2lyx (also used in the HTML chain) assumes English as document language + // if no language is explicitly set (as is the case here). + // We thus reset the temp buffer's language to the context language + buffer.changeLanguage(buffer.language(), cur.getFont().language()); cur.recordUndo(); pasteParagraphList(cur, buffer.paragraphs(), buffer.params().documentClassPtr(), errorList); @@ -1288,7 +1308,7 @@ void pasteSimpleText(Cursor & cur, bool asParagraphs) return; cur.recordUndo(); - cutSelection(cur, true, false); + cutSelection(cur, false); if (asParagraphs) cur.text()->insertStringAsParagraphs(cur, text, cur.current_font); else @@ -1338,20 +1358,20 @@ void replaceSelectionWithString(Cursor & cur, docstring const & str) // Insert the new string pos_type pos = cur.selEnd().pos(); Paragraph & par = cur.selEnd().paragraph(); - docstring::const_iterator cit = str.begin(); - docstring::const_iterator end = str.end(); - for (; cit != end; ++cit, ++pos) - par.insertChar(pos, *cit, font, cur.buffer()->params().track_changes); + for (auto const & c : str) { + par.insertChar(pos, c, font, cur.buffer()->params().track_changes); + ++pos; + } // Cut the selection - cutSelection(cur, true, false); + cutSelection(cur, false); } void replaceSelection(Cursor & cur) { if (cur.selection()) - cutSelection(cur, true, false); + cutSelection(cur, false); }