]> git.lyx.org Git - lyx.git/blobdiff - src/CutAndPaste.C
* src/frontends/qt4/QTocDialog.C (updateGui):
[lyx.git] / src / CutAndPaste.C
index e2c3afedb56403d3bf8ea62f783ecc67f4d6fc78..d111dc8a852dbfd7c301fe633ffb6fceac808dbc 100644 (file)
@@ -6,6 +6,7 @@
  * \author Jürgen Vigna
  * \author Lars Gullik Bjønnes
  * \author Alfredo Braunstein
+ * \author Michael Gerz
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -45,6 +46,7 @@
 #include "support/lstrings.h"
 
 #include "frontends/Clipboard.h"
+#include "frontends/Selection.h"
 
 #include <boost/tuple/tuple.hpp>
 
@@ -73,7 +75,7 @@ CutStack theCuts(10);
 // store whether the tabular stack is newer than the normal copy stack
 // FIXME: this is a workaround for bug 1919. Should be removed for 1.5,
 // when we (hopefully) have a one-for-all paste mechanism.
-bool dirty_tabular_stack_;
+bool dirty_tabular_stack_ = false;
 
 
 void region(CursorSlice const & i1, CursorSlice const & i2,
@@ -209,8 +211,8 @@ pasteSelectionHelper(LCursor & cur, ParagraphList const & parlist,
        ParIterator fend = par_iterator_end(in);
 
        for (; fpit != fend; ++fpit) {
-               InsetList::iterator lit = fpit->insetlist.begin();
-               InsetList::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()) {
@@ -292,21 +294,18 @@ PitPosPair eraseSelectionHelper(BufferParams const & params,
                return PitPosPair(endpit, endpos);
        }
 
-       // A paragraph break has to be physically removed by merging, but
-       // only if either (1) change tracking is off, or (2) the para break
-       // is "blue"
        for (pit_type pit = startpit; pit != endpit + 1;) {
-               // FIXME: Change tracking (MG)
-               bool const merge = !params.trackChanges ||
-                                  pars[pit].isInserted(pars[pit].size());
-               pos_type const left  = ( pit == startpit ? startpos : 0 );
-               pos_type const right = ( pit == endpit ? endpos :
-                               pars[pit].size() + 1 );
-               // Logical erase only:
-               pars[pit].eraseChars(left, right, false);
-               // Separate handling of para break:
+               pos_type const left  = (pit == startpit ? startpos : 0);
+               pos_type const right = (pit == endpit ? endpos : pars[pit].size() + 1);
+
+               bool const merge = pars[pit].isMergedOnEndOfParDeletion(params.trackChanges);
+
+               // Logically erase only, including the end-of-paragraph character
+               pars[pit].eraseChars(left, right, params.trackChanges);
+
+               // Separate handling of paragraph break:
                if (merge && pit != endpit &&
-                  (pit + 1 != endpit || pars[pit].hasSameLayout(pars[pit + 1]))) {
+                   (pit + 1 != endpit || pars[pit].hasSameLayout(pars[pit + 1]))) {
                        pos_type const thissize = pars[pit].size();
                        if (doclear)
                                pars[pit + 1].stripLeadingSpaces();
@@ -495,15 +494,8 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut)
                LyXText * text = cur.text();
                BOOST_ASSERT(text);
                // Stuff what we got on the clipboard. Even if there is no selection.
-
-               // There is a problem with having the stuffing here in that the
-               // larger the selection the slower LyX will get. This can be
-               // solved by running the line below only when the selection has
-               // finished. The solution used currently just works, to make it
-               // faster we need to be more clever and probably also have more
-               // calls to theSelection().put. (Lgb)
-//             theSelection().put(cur.selectionAsString(true));
-
+               if (realcut)
+                       theClipboard().put(cur.selectionAsString(true));
 
                // make sure that the depth behind the selection are restored, too
                recordUndoSelection(cur);
@@ -541,6 +533,7 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut)
                // need a valid cursor. (Lgb)
                cur.clearSelection();
                updateLabels(cur.buffer());
+               theSelection().haveSelection(false);
 
                // tell tabular that a recent copy happened
                dirtyTabularStack(false);
@@ -568,6 +561,12 @@ void copySelection(LCursor & cur)
        // stuff the selection onto the X clipboard, from an explicit copy request
        theClipboard().put(cur.selectionAsString(true));
 
+       copySelectionToStack(cur);
+}
+
+
+void copySelectionToStack(LCursor & cur)
+{
        // this doesn't make sense, if there is no selection
        if (!cur.selection())
                return;
@@ -629,7 +628,7 @@ void pasteParagraphList(LCursor & cur, ParagraphList const & parlist,
                                             textclass, errorList);
                updateLabels(cur.buffer());
                cur.clearSelection();
-               text->setCursor(cur, ppp.first, ppp.second);
+               text->setCursor(cur.top(), ppp.first, ppp.second);
        }
 
        // mathed is handled in InsetMathNest/InsetMathGrid
@@ -643,14 +642,14 @@ void pasteSelection(LCursor & cur, ErrorList & errorList, size_t sel_index)
        if (!checkPastePossible(sel_index))
                return;
 
+       recordUndo(cur);
        pasteParagraphList(cur, theCuts[sel_index].first,
                           theCuts[sel_index].second, errorList);
        cur.setSelection();
 }
 
 
-// simple replacing. The font of the first selected character is used
-void replaceSelectionWithString(LCursor & cur, string const & str, bool backwards)
+void replaceSelectionWithString(LCursor & cur, docstring const & str, bool backwards)
 {
        recordUndo(cur);
        DocIterator selbeg = cur.selectionBegin();
@@ -662,10 +661,10 @@ void replaceSelectionWithString(LCursor & cur, string const & str, bool backward
        // Insert the new string
        pos_type pos = cur.selEnd().pos();
        Paragraph & par = cur.selEnd().paragraph();
-       string::const_iterator cit = str.begin();
-       string::const_iterator end = str.end();
+       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().trackChanges);
+               par.insertChar(pos, *cit, font, cur.buffer().params().trackChanges);
 
        // Cut the selection
        cutSelection(cur, true, false);
@@ -688,7 +687,7 @@ void replaceSelection(LCursor & cur)
 
 void eraseSelection(LCursor & cur)
 {
-       //lyxerr << "LCursor::eraseSelection begin: " << cur << endl;
+       //lyxerr << "cap::eraseSelection begin: " << cur << endl;
        CursorSlice const & i1 = cur.selBegin();
        CursorSlice const & i2 = cur.selEnd();
        if (i1.inset().asInsetMath()) {
@@ -712,16 +711,17 @@ void eraseSelection(LCursor & cur)
                }
                // need a valid cursor. (Lgb)
                cur.clearSelection();
+               theSelection().haveSelection(false);
        } else {
                lyxerr << "can't erase this selection 1" << endl;
        }
-       //lyxerr << "LCursor::eraseSelection end: " << cur << endl;
+       //lyxerr << "cap::eraseSelection end: " << cur << endl;
 }
 
 
 void selDel(LCursor & cur)
 {
-       //lyxerr << "LCursor::selDel" << endl;
+       //lyxerr << "cap::selDel" << endl;
        if (cur.selection())
                eraseSelection(cur);
 }
@@ -729,7 +729,7 @@ void selDel(LCursor & cur)
 
 void selClearOrDel(LCursor & cur)
 {
-       //lyxerr << "LCursor::selClearOrDel" << endl;
+       //lyxerr << "cap::selClearOrDel" << endl;
        if (lyxrc.auto_region_delete)
                selDel(cur);
        else