]> git.lyx.org Git - features.git/commitdiff
Alfredo's CutAndPaste fixes
authorAndré Pönitz <poenitz@gmx.net>
Tue, 29 Apr 2003 09:40:49 +0000 (09:40 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Tue, 29 Apr 2003 09:40:49 +0000 (09:40 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6877 a592a061-630c-0410-9148-cb99ea01b6c8

src/ChangeLog
src/CutAndPaste.C
src/CutAndPaste.h
src/paragraph.C
src/paragraph.h
src/paragraph_pimpl.C
src/paragraph_pimpl.h
src/text2.C

index 67e9158f2a4d12e934e155ba73c2f494f0f0d9c6..b9a28840fdfc78b7011ba63bf481a12479833153 100644 (file)
@@ -1,4 +1,7 @@
+2003-04-29  Alfredo Braunstein  <abraunst@libero.it>
 
+       * CutAndPaste.C (cutSelection): big rework, some bugs fixed
 2003-04-29 André Pönitz <poenitz@gmx.net>
 
        * ParagraphList.C: whitespace
index 8d76ec1df356c1f4e7f18bdfe7a3879873a35f20..e0312bdaeb4527d91f1b066b009f451f49de3d04 100644 (file)
@@ -61,64 +61,57 @@ textclass_type textclass = 0;
 
 } // namespace anon
 
+typedef std::pair<ParagraphList::iterator, int> pitPosPair;
 
-bool CutAndPaste::cutSelection(Paragraph * startpar, Paragraph * endpar,
-                              int start, int & end, textclass_type tc,
-                              bool doclear, bool realcut)
+pitPosPair CutAndPaste::cutSelection(ParagraphList & pars, 
+                                    ParagraphList::iterator startpit, 
+                                    ParagraphList::iterator endpit,
+                                    int startpos, int endpos, 
+                                    textclass_type tc, bool doclear)
 {
-       if (!startpar || (start > startpar->size()))
-               return false;
+       copySelection(&*startpit, &*endpit, startpos, endpos, tc);
+       return eraseSelection(pars, startpit, endpit, startpos, 
+                             endpos, doclear);
+}
 
-       if (realcut) {
-               copySelection(startpar, endpar, start, end, tc);
-       }
 
-       if (!endpar || startpar == endpar) {
-               if (startpar->erase(start, end)) {
-                       // Some chars were erased, go to start to be safe
-                       end = start;
-               }
-               return true;
-       }
+pitPosPair CutAndPaste::eraseSelection(ParagraphList & pars, 
+                                      ParagraphList::iterator startpit, 
+                                      ParagraphList::iterator endpit,
+                                      int startpos, int endpos, bool doclear)
+{
+       if (startpit == pars.end() || (startpos > startpit->size()))
+               return pitPosPair(endpit, endpos);
 
-       bool actually_erased = false;
+       if (endpit == pars.end() || startpit == endpit) {
+               endpos -= startpit->erase(startpos, endpos);
+               return pitPosPair(endpit, endpos);
+       }
 
        // clear end/begin fragments of the first/last par in selection
-       actually_erased |= (startpar)->erase(start, startpar->size());
-       if (endpar->erase(0, end)) {
-               actually_erased = true;
-               end = 0;
-       }
+       bool all_erased = true;
 
-       // Loop through the deleted pars if any, erasing as needed
+       startpit->erase(startpos, startpit->size());
+       if (startpit->size() != startpos)
+               all_erased = false;
 
-       Paragraph * pit = startpar->next();
+       endpos -= endpit->erase(0, endpos);
+       if (endpos != 0)
+               all_erased = false;
 
-       while (true) {
-               // *endpar can be 0
-               if (!pit)
-                       break;
+       // Loop through the deleted pars if any, erasing as needed
 
-               Paragraph * next = pit->next();
+       ParagraphList::iterator pit = boost::next(startpit);
 
+       while (pit != endpit && pit != pars.end()) {
+               ParagraphList::iterator const next = boost::next(pit);
                // "erase" the contents of the par
-               if (pit != endpar) {
-                       actually_erased |= pit->erase(0, pit->size());
-
+               pit->erase(0, pit->size());
+               if (!pit->size()) {
                        // remove the par if it's now empty
-                       if (actually_erased) {
-                               pit->previous()->next(pit->next());
-                               if (next) {
-                                       next->previous(pit->previous());
-                               }
-
-                               delete pit;
-                       }
-               }
-
-               if (pit == endpar)
-                       break;
-
+                       pars.erase(pit);
+               } else
+                       all_erased = false;
                pit = next;
        }
 
@@ -131,31 +124,28 @@ bool CutAndPaste::cutSelection(Paragraph * startpar, Paragraph * endpar,
        }
 #endif
 
-       if (!startpar->next())
-               return true;
-
-       Buffer * buffer = current_view->buffer();
+       if (boost::next(startpit) == pars.end())
+               return pitPosPair(endpit, endpos);
 
        if (doclear) {
-               startpar->next()->stripLeadingSpaces();
+               boost::next(startpit)->stripLeadingSpaces();
        }
 
-       if (!actually_erased)
-               return true;
-
        // paste the paragraphs again, if possible
-       if (startpar->hasSameLayout(startpar->next()) ||
-           startpar->next()->empty()) {
-#warning This is suspect. (Lgb)
-               // When doing this merge we must know if the par really
-               // belongs to an inset, and if it does then we have to use
-               // the insets paragraphs, and not the buffers. (Lgb)
-               mergeParagraph(buffer->params, buffer->paragraphs, startpar);
+       if (all_erased && 
+           (startpit->hasSameLayout(&*boost::next(startpit)) ||
+            boost::next(startpit)->empty())) {
+#warning current_view used here.
+// should we pass buffer or buffer->params around?
+               Buffer * buffer = current_view->buffer();
+               mergeParagraph(buffer->params, pars, &*startpit);
                // this because endpar gets deleted here!
-               endpar = startpar;
+               endpit = startpit;
+               endpos = startpos;
        }
 
-       return true;
+       return pitPosPair(endpit, endpos);
+
 }
 
 
index 61b0402152f3cc31fd455a512c4f0f331fca122c..e27cb4ccbe1e49f80a52933a269bd6f3281ba036 100644 (file)
@@ -12,6 +12,7 @@
 #define CUTANDPASTE_H
 
 #include "support/types.h"
+#include "ParagraphList.h"
 
 class Paragraph;
 class BufferParams;
@@ -19,12 +20,19 @@ class LyXTextClass;
 
 ///
 namespace CutAndPaste {
-
-/// realcut == false is we actually want a delete
-bool cutSelection(Paragraph * startpar, Paragraph * endpar,
-                 int start, int & end, lyx::textclass_type tc,
-                 bool doclear = false, bool realcut = true);
-
+///
+std::pair<ParagraphList::iterator, int>
+cutSelection(ParagraphList & pars,
+            ParagraphList::iterator startpit, 
+            ParagraphList::iterator endpit,
+            int start, int end, lyx::textclass_type tc,
+            bool doclear = false);
+///
+std::pair<ParagraphList::iterator, int>
+eraseSelection(ParagraphList & pars,
+              ParagraphList::iterator startpit, 
+              ParagraphList::iterator endpit,
+              int start, int end, bool doclear = false);
 ///
 bool copySelection(Paragraph * startpar, Paragraph * endpar,
                   int start, int end, lyx::textclass_type tc);
index 6f21d609c2c6aec28a212aed3be506a9306ae644..863e37346801ff0b68dc033623c8373c0034bdfd 100644 (file)
@@ -330,7 +330,7 @@ void Paragraph::erase(pos_type pos)
 }
 
 
-bool Paragraph::erase(pos_type start, pos_type end)
+int Paragraph::erase(pos_type start, pos_type end)
 {
        return pimpl_->erase(start, end);
 }
index 1842cd558e723d57237019df1adbd7b166e696f8..8281ef0d26fbb9f8d4d3e97761a1a748b8e74310 100644 (file)
@@ -219,8 +219,8 @@ public:
        void eraseIntern(lyx::pos_type pos);
        /// erase the char at the given position
        void erase(lyx::pos_type pos);
-       /// erase the given range. Returns true if actually erased.
-       bool erase(lyx::pos_type start, lyx::pos_type end);
+       /// erase the given range. Returns the number of chars actually erased
+       int erase(lyx::pos_type start, lyx::pos_type end);
 
        /** Get uninstantiated font setting. Returns the difference
            between the characters font and the layoutfont.
index 16a57fee5db4149d5e95f77849ea391acd157a1a..a29dd641853c56de9e50feecb52b4f07afe059cb 100644 (file)
@@ -409,21 +409,17 @@ void Paragraph::Pimpl::erase(pos_type pos)
 }
 
 
-bool Paragraph::Pimpl::erase(pos_type start, pos_type end)
+int Paragraph::Pimpl::erase(pos_type start, pos_type end)
 {
        pos_type i = start;
        pos_type count = end - start;
-       bool any_erased = false;
-
        while (count) {
                if (!erasePos(i)) {
                        ++i;
-               } else {
-                       any_erased = true;
-               }
+               } 
                --count;
        }
-       return any_erased;
+       return end - i;
 }
 
 
index 0031c5663518f07c2ffe92b080e24a6bfa249022..63e4f735e7e1b5fbf5419c46287d44ce46cfdbbc 100644 (file)
@@ -82,7 +82,7 @@ struct Paragraph::Pimpl {
        /// erase the given position
        void erase(lyx::pos_type pos);
        /// erase the given range
-       bool erase(lyx::pos_type start, lyx::pos_type end);
+       int erase(lyx::pos_type start, lyx::pos_type end);
        ///
        Inset * inset_owner;
 
index 4d2e015154d46f75d09462d8bbfdf2795cf2a337..940b08820d5c6241a73b98d5a264e14a1fbe81dd 100644 (file)
@@ -40,6 +40,7 @@
 #include "support/lstrings.h"
 
 #include "support/BoostFormat.h"
+#include <boost/tuple/tuple.hpp>
 
 using std::vector;
 using std::copy;
@@ -1309,41 +1310,34 @@ void LyXText::cutSelection(bool doclear, bool realcut)
 
        setUndo(bv(), Undo::DELETE, &*selection.start.par(), &*undoendpit);
 
-       // there are two cases: cut only within one paragraph or
-       // more than one paragraph
-       if (selection.start.par() == selection.end.par()) {
-               // only within one paragraph
-               endpit = selection.end.par();
-               int pos = selection.end.pos();
-               CutAndPaste::cutSelection(&*selection.start.par(), &*endpit,
-                                         selection.start.pos(), pos,
-                                         bv()->buffer()->params.textclass,
-                                         doclear, realcut);
-               selection.end.pos(pos);
-       } else {
-               endpit = selection.end.par();
-               int pos = selection.end.pos();
-               CutAndPaste::cutSelection(&*selection.start.par(), &*endpit,
-                                         selection.start.pos(), pos,
-                                         bv()->buffer()->params.textclass,
-                                         doclear, realcut);
-               cursor.par(endpit);
-               selection.end.par(endpit);
-               selection.end.pos(pos);
-               cursor.pos(selection.end.pos());
-       }
-       ++endpit;
 
+       endpit = selection.end.par();
+       int endpos = selection.end.pos();
+
+       boost::tie(endpit, endpos) = realcut ? 
+               CutAndPaste::cutSelection(ownerParagraphs(),
+                                         selection.start.par(), endpit,
+                                         selection.start.pos(), endpos,
+                                         bv()->buffer()->params.textclass,
+                                         doclear)
+               : CutAndPaste::eraseSelection(ownerParagraphs(),
+                                             selection.start.par(), endpit,
+                                             selection.start.pos(), endpos,
+                                             doclear);
        // sometimes necessary
        if (doclear)
                selection.start.par()->stripLeadingSpaces();
 
-       redoParagraphs(selection.start, endpit);
-
+       redoParagraphs(selection.start, boost::next(endpit));
+#warning FIXME latent bug
+       // endpit will be invalidated on redoParagraphs once ParagraphList
+       // becomes a std::list? There are maybe other places on which this
+       // can happend? (Ab)
        // cutSelection can invalidate the cursor so we need to set
        // it anew. (Lgb)
        // we prefer the end for when tracking changes
-       cursor = selection.end;
+       cursor.pos(endpos);
+       cursor.par(endpit);
 
        // need a valid cursor. (Lgb)
        clearSelection();
@@ -1632,17 +1626,18 @@ void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit,
        // same paragraph and there is a previous row then put the cursor on
        // the end of the previous row
        cur.iy(y + row->baseline());
-       Inset * ins;
-       if (row != beg && pos &&
-               boost::prior(row)->par() == row->par() &&
-           pos < pit->size() &&
-               pit->getChar(pos) == Paragraph::META_INSET &&
-               (ins = pit->getInset(pos)) && (ins->needFullRow() || ins->display()))
-       {
-               --row;
-               y -= row->height();
+       if (row != beg && 
+           pos && 
+           boost::prior(row)->par() == row->par() && 
+           pos < pit->size() && 
+           pit->getChar(pos) == Paragraph::META_INSET) {
+               Inset * ins = pit->getInset(pos);
+               if (ins && (ins->needFullRow() || ins->display())) {
+                       --row;
+                       y -= row->height();
+               }
        }
-
+       
        cur.row(row);
        // y is now the beginning of the cursor row
        y += row->baseline();