]> git.lyx.org Git - lyx.git/blobdiff - src/CutAndPaste.cpp
Fix bug #6367: Screen jumps around when using undo/redo
[lyx.git] / src / CutAndPaste.cpp
index 99f8383e6b027abf14a4fa222942e182cb34ccf8..c8e99abcabb9cb3b894e033299f0e9b674c93d0a 100644 (file)
@@ -56,6 +56,7 @@
 #include "support/debug.h"
 #include "support/docstream.h"
 #include "support/gettext.h"
+#include "support/lassert.h"
 #include "support/limited_stack.h"
 #include "support/lstrings.h"
 
@@ -227,7 +228,7 @@ pasteSelectionHelper(Cursor 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, e.g., InsetLabel::updateCommand() is going to try to access
+               // since some inset might going to try to access
                // the buffer() member.
                it->setBuffer(const_cast<Buffer &>(buffer));
                switch (it->lyxCode()) {
@@ -241,7 +242,7 @@ pasteSelectionHelper(Cursor const & cur, ParagraphList const & parlist,
                                        continue;
                                InsetLabel * lab = labels[i];
                                docstring const oldname = lab->getParam("name");
-                               lab->updateCommand(oldname, false);
+                               lab->updateLabel(oldname);
                                // We need to update the buffer reference cache.
                                cur.forceBufferUpdate();
                                docstring const newname = lab->getParam("name");
@@ -272,7 +273,7 @@ pasteSelectionHelper(Cursor const & cur, ParagraphList const & parlist,
                        // check for duplicates
                        InsetLabel & lab = static_cast<InsetLabel &>(*it);
                        docstring const oldname = lab.getParam("name");
-                       lab.updateCommand(oldname, false);
+                       lab.updateLabel(oldname);
                        // We need to update the buffer reference cache.
                        cur.forceBufferUpdate();
                        docstring const newname = lab.getParam("name");
@@ -647,13 +648,25 @@ void switchBetweenClasses(DocumentClass const * const oldone,
        DocumentClass const & newtc = *newone;
 
        // layouts
+       ParIterator it = par_iterator_begin(in);
        ParIterator end = par_iterator_end(in);
-       for (ParIterator it = par_iterator_begin(in); it != end; ++it) {
+       // for remembering which layouts we've had to add
+       set<docstring> newlayouts;
+       for (; it != end; ++it) {
                docstring const name = it->layout().name();
 
                // the pasted text will keep their own layout name. If this layout does
                // not exist in the new document, it will behave like a standard layout.
-               newtc.addLayoutIfNeeded(name);
+               bool const added_one = newtc.addLayoutIfNeeded(name);
+               if (added_one)
+                       newlayouts.insert(name);
+
+               if (added_one || newlayouts.find(name) != newlayouts.end()) {
+                       // Warn the user.
+                       docstring const s = bformat(_("Layout `%1$s' was not found."), name);
+                       errorlist.push_back(
+                               ErrorItem(_("Layout Not Found"), s, it->id(), 0, it->size()));
+               }
 
                if (in.usePlainLayout())
                        it->setLayout(newtc.plainLayout());
@@ -667,18 +680,25 @@ void switchBetweenClasses(DocumentClass const * const oldone,
                if (it->lyxCode() != FLEX_CODE)
                        // FIXME: Should we verify all InsetCollapsable?
                        continue;
-               docstring const & n = newone->insetLayout(it->name()).name();
+
+               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 s = bformat(_(
-                       "Flex inset %1$s is "
-                       "undefined because of class "
-                       "conversion from\n%2$s to %3$s"),
-                       it->name(), from_utf8(oldtc.name()),
-                       from_utf8(newtc.name()));
+               docstring const oldname = from_utf8(oldtc.name());
+               docstring const newname = from_utf8(newtc.name());
+               docstring s;
+               if (oldname == newname)
+                       s = bformat(_("Flex inset %1$s is undefined after "
+                               "reloading `%2$s' layout."), layoutName, oldname);
+               else
+                       s = bformat(_("Flex inset %1$s is undefined because of "
+                               "conversion from `%2$s' layout to `%3$s'."),
+                               layoutName, oldname, newname);
                // To warn the user that something had to be done.
                errorlist.push_back(ErrorItem(
                                _("Undefined flex inset"),
@@ -1025,6 +1045,40 @@ void pasteClipboardText(Cursor & cur, ErrorList & errorList, bool asParagraphs)
                cur.text()->insertStringAsParagraphs(cur, text, cur.current_font);
        else
                cur.text()->insertStringAsLines(cur, text, cur.current_font);
+       cur.setSelection();
+}
+
+
+void pasteSimpleText(Cursor & cur, bool asParagraphs)
+{
+       docstring text;
+       // Use internal clipboard if it is the most recent one
+       if (theClipboard().isInternal()) {
+               if (!checkPastePossible(0))
+                       return;
+
+               ParagraphList const & pars = theCuts[0].first;
+               ParagraphList::const_iterator it = pars.begin();
+               for (; it != pars.end(); ++it) {
+                       if (it != pars.begin())
+                               text += "\n";
+                       text += (*it).asString();
+               }
+               asParagraphs = false;
+       } else {
+               // Then try plain text
+               text = theClipboard().getAsText();
+       }
+
+       if (text.empty())
+               return;
+
+       cur.recordUndo();
+       cutSelection(cur, true, false);
+       if (asParagraphs)
+               cur.text()->insertStringAsParagraphs(cur, text, cur.current_font);
+       else
+               cur.text()->insertStringAsLines(cur, text, cur.current_font);
 }