X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.cpp;h=f611d59395b8b9681b5a0d20c89435f1c684c52e;hb=c8230ab0d0a919530c43c29395f4d9961498bf15;hp=7e09ac9ff95bd7659cc9f783ac33add56f0181ee;hpb=004fdf6aebd7669c4b1df33236fe2a8f515584c0;p=lyx.git diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 7e09ac9ff9..f611d59395 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -159,6 +159,38 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, } } + // Prevent to paste uncodable characters in verbatim and ERT. + // The encoding is inherited from the context here. + docstring uncodable_content; + if (target_inset->getLayout().isPassThru() && cur.getEncoding()) { + odocstringstream res; + Encoding const * e = cur.getEncoding(); + for (size_t i = 0; i != insertion.size(); ++i) { + pos_type end = insertion[i].size(); + for (pos_type j = 0; j != end; ++j) { + char_type const c = insertion[i].getChar(j); + if (!e->encodable(c)) { + // do not track deletion + res.put(c); + insertion[i].eraseChar(j, false); + --end; + --j; + } + } + } + docstring const uncodable = res.str(); + if (!uncodable.empty()) { + if (uncodable.size() == 1) + uncodable_content = bformat(_("The character \"%1$s\" is uncodable in this verbatim context " + "and thus has not been pasted."), + uncodable); + else + uncodable_content = bformat(_("The characters \"%1$s\" are uncodable in this verbatim context " + "and thus have not been pasted."), + uncodable); + } + } + // set the paragraphs to plain layout if necessary DocumentClassConstPtr newDocClass = buffer.params().documentClassPtr(); if (cur.inset().usePlainLayout()) { @@ -194,6 +226,9 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist, // want to invalidate them. insertion.swap(in.paragraphs()); cap::switchBetweenClasses(oldDocClass, newDocClass, in, errorlist); + // Do this here since switchBetweenClasses clears the errorlist + if (!uncodable_content.empty()) + errorlist.push_back(ErrorItem(_("Uncodable content"), uncodable_content)); insertion.swap(in.paragraphs()); ParagraphList::iterator tmpbuf = insertion.begin(); @@ -243,7 +278,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 + // 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. it->setBuffer(const_cast(buffer)); @@ -471,7 +506,7 @@ PitPosPair eraseSelectionHelper(BufferParams const & params, // Separate handling of paragraph break: if (merge && pit != endpit && - (pit + 1 != endpit + (pit + 1 != endpit || pars[pit].hasSameLayout(pars[endpit]) || pars[endpit].size() == endpos)) { if (pit + 1 == endpit) @@ -536,7 +571,7 @@ Buffer * copyToTempBuffer(ParagraphList const & paragraphs, DocumentClassConstPt } -void putClipboard(ParagraphList const & paragraphs, +void putClipboard(ParagraphList const & paragraphs, DocumentClassConstPtr docclass, docstring const & plaintext) { Buffer * buffer = copyToTempBuffer(paragraphs, docclass); @@ -636,7 +671,7 @@ void copySelectionHelper(Buffer const & buf, Text const & text, // latex_language. This is invalid for others, so we // need to change it to the buffer language. if (it->isPassThru()) - it->changeLanguage(buf.params(), + it->changeLanguage(buf.params(), latex_language, buf.language()); } @@ -652,16 +687,14 @@ void copySelectionHelper(Buffer const & buf, Text const & text, // are not linked to something else. it = copy_pars.begin(); for (; it != it_end; ++it) { - it->setBuffer(*static_cast(0)); + it->resetBuffer(); it->setInsetOwner(0); } cutstack.push(make_pair(copy_pars, dc)); } -} // namespace anon - - +} // namespace namespace cap { @@ -705,11 +738,11 @@ bool reduceSelectionToOneCell(Cursor & cur) // the easy case: do nothing if only one cell is selected if (i1.idx() == i2.idx()) return true; - + cur.top().pos() = 0; cur.resetAnchor(); cur.top().pos() = cur.top().lastpos(); - + return true; } @@ -718,15 +751,15 @@ bool multipleCellsSelected(Cursor const & cur) { if (!cur.selection() || !cur.inMathed()) return false; - + CursorSlice i1 = cur.selBegin(); CursorSlice i2 = cur.selEnd(); if (!i1.inset().asInsetMath()) return false; - + if (i1.idx() == i2.idx()) return false; - + return true; } @@ -739,7 +772,7 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, LBUFERR(!in.paragraphs().empty()); if (oldone == newone) return; - + DocumentClass const & oldtc = *oldone; DocumentClass const & newtc = *newone; @@ -775,14 +808,14 @@ void switchBetweenClasses(DocumentClassConstPtr oldone, for (InsetIterator it = inset_iterator_begin(in); it != i_end; ++it) { InsetCode const code = it->lyxCode(); if (code == FLEX_CODE) { - // FIXME: Should we verify all InsetCollapsable? + // FIXME: Should we verify all InsetCollapsible? docstring const layoutName = it->layoutName(); docstring const & n = newone->insetLayout(layoutName).name(); bool const is_undefined = n.empty() || n == DocumentClass::plainInsetLayout().name(); if (!is_undefined) continue; - + // The flex inset is undefined in newtc docstring const oldname = from_utf8(oldtc.name()); docstring const newname = from_utf8(newtc.name()); @@ -933,7 +966,7 @@ void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool doclear, bool realcu } } -} +} // namespace void cutSelection(Cursor & cur, bool doclear, bool realcut) { @@ -988,7 +1021,7 @@ void copySelectionToStack(Cursor const & cur, CutStack & cutstack) // and sel_end cursor copySelectionHelper(*cur.buffer(), *text, cur.selBegin().pit(), cur.selEnd().pit(), - cur.selBegin().pos(), cur.selEnd().pos(), + cur.selBegin().pos(), cur.selEnd().pos(), cur.buffer()->params().documentClassPtr(), cutstack); // Reset the dirty_tabular_stack_ flag only when something @@ -1010,7 +1043,7 @@ void copySelectionToStack(Cursor const & cur, CutStack & cutstack) } } -} +} // namespace void copySelectionToStack() @@ -1048,7 +1081,7 @@ void saveSelection(Cursor const & cur) // 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() + if (cur.selection() && cur.selBegin() == cur.bv().cursor().selBegin() && cur.selEnd() == cur.bv().cursor().selEnd()) { LYXERR(Debug::SELECTION, "saveSelection: '" << cur.selectionAsString(true) << "'");