]> git.lyx.org Git - lyx.git/blobdiff - src/CutAndPaste.cpp
Merge remote-tracking branch 'features/properpaint' into 2.3.2-staging
[lyx.git] / src / CutAndPaste.cpp
index 7e09ac9ff95bd7659cc9f783ac33add56f0181ee..f611d59395b8b9681b5a0d20c89435f1c684c52e 100644 (file)
@@ -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 &>(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<Buffer *>(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) << "'");