]> git.lyx.org Git - features.git/commitdiff
redo undo
authorAndré Pönitz <poenitz@gmx.net>
Mon, 8 Mar 2004 21:14:45 +0000 (21:14 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Mon, 8 Mar 2004 21:14:45 +0000 (21:14 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8481 a592a061-630c-0410-9148-cb99ea01b6c8

14 files changed:
src/BufferView_pimpl.C
src/ChangeLog
src/cursor.C
src/cursor.h
src/dociterator.C
src/dociterator.h
src/insets/insetcollapsable.C
src/lyxfunc.C
src/mathed/math_nestinset.C
src/text.C
src/text2.C
src/text3.C
src/undo.C
src/undo.h

index a523795405e975cef6c7e109fd7346fc9c9b6424..c7d75389e963259752391c68fcca46e687ec0821 100644 (file)
@@ -607,6 +607,7 @@ void BufferView::Pimpl::update()
                updateScrollbar();
        }
        screen().redraw(*bv_);
+       bv_->owner()->view_state_changed();
 }
 
 
index 5ef35da4c6bdc25387cb570b19b40f032581b55b..c1ad6d27cb3a57d4d5983dd8d6d025abb6a501a9 100644 (file)
@@ -1,3 +1,9 @@
+
+2004-03-08  André Pönitz  <poenitz@gmx.net>
+
+       * undo.[Ch]: use 'StableDocumentIterator' as base for
+       the Undo struct.
+
 2004-03-07  Jürgen Spitzmüller  <j.spitzmueller@gmx.de>
 
        * LaTeXFeatures.C:
index e712ea42d67f91c744fa8a1d33f710f61ae1711f..ab0fc05d9411d3c94f69f73dc709de520f89f856 100644 (file)
@@ -85,7 +85,7 @@ void LCursor::setCursor(DocumentIterator const & cur, bool sel)
 
 DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
 {
-       lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
+       //lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
        BOOST_ASSERT(pos() <= lastpos());
        BOOST_ASSERT(idx() <= lastidx());
        BOOST_ASSERT(par() <= lastpar());
@@ -1235,38 +1235,6 @@ CursorSlice LCursor::normalAnchor()
 }
 
 
-/*
-DispatchResult dispatch(LCursor & cur, FuncRequest const & cmd)
-{
-       // mouse clicks are somewhat special
-       // check
-       switch (cmd.action) {
-       case LFUN_MOUSE_PRESS:
-       case LFUN_MOUSE_MOTION:
-       case LFUN_MOUSE_RELEASE:
-       case LFUN_MOUSE_DOUBLE: {
-               CursorSlice & pos = back();
-               int x = 0;
-               int y = 0;
-               getPos(x, y);
-               if (x < cmd.x && pos() != 0) {
-                       DispatchResult const res = prevAtom().nucleus()->dispatch(cmd);
-                       if (res.dispatched())
-                               return res;
-               }
-               if (x > cmd.x && pos() != lastpos()) {
-                       DispatchResult const res = inset()->dispatch(cmd);
-                       if (res.dispatched())
-                               return res;
-               }
-       }
-       default:
-       break;
-       }
-}
-*/
-
-
 void LCursor::handleFont(string const & font)
 {
        lyxerr << "LCursor::handleFont: " << font << endl;
index e14fb97006e9efe7959fe0362559d7e058ea91ac..6654f1660b3c316d9a8c888ab9ddfcd18abb3289 100644 (file)
@@ -30,9 +30,7 @@ class MathUnknownInset;
 class MathGridInset;
 
 
-/**
- * The cursor class describes the position of a cursor within a document.
- */
+/// The cursor class describes the position of a cursor within a document.
 
 // The public inheritance should go in favour of a suitable data member
 // (or maybe private inheritance) at some point of time.
index fb7b7482adc1c2397417a2c6842ff48496c8db82..1293fb3d0223d59a723bfa73fcd23feeb820b096 100644 (file)
@@ -14,9 +14,6 @@
 
 
 
-std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur);
-
-
 DocumentIterator::DocumentIterator()
        : bv_(0)
 {}
@@ -393,9 +390,49 @@ DocumentIterator insetEnd()
 }
 
 
-std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur)
+std::ostream & operator<<(std::ostream & os, DocumentIterator const & dit)
 {
-       for (size_t i = 0, n = cur.size(); i != n; ++i)
-               os << " " << cur.operator[](i) << "\n";
+       os << "bv: " << &dit.bv() << "\n";
+       for (size_t i = 0, n = dit.size(); i != n; ++i)
+               os << " " << dit.operator[](i) << "\n";
        return os;
 }
+
+
+
+///////////////////////////////////////////////////////
+
+StableDocumentIterator::StableDocumentIterator(const DocumentIterator & dit)
+{
+       data_ = dit;
+       for (size_t i = 0, n = data_.size(); i != n; ++i)
+               data_[i].inset_ = 0;
+}
+
+
+DocumentIterator
+StableDocumentIterator::asDocumentIterator(BufferView & bv) const
+{
+       // this function re-creates the cache of inset pointers
+       //lyxerr << "converting:\n" << *this << std::endl;
+       DocumentIterator dit(bv);
+       dit.clear();
+       InsetBase * inset = 0;
+       for (size_t i = 0, n = data_.size(); i != n; ++i) {
+               dit.push_back(data_[i]);
+               dit.back().inset_ = inset;
+               if (i + 1 != n)
+                       inset = dit.nextInset();
+       }
+       //lyxerr << "convert:\n" << *this << " to:\n" << dit << std::endl;
+       return dit;
+}
+
+
+std::ostream & operator<<(std::ostream & os, StableDocumentIterator const & dit)
+{
+       for (size_t i = 0, n = dit.data_.size(); i != n; ++i)
+               os << " " << dit.data_[i] << "\n";
+       return os;
+}
+
index 24c2b49a6979668faa75598e8cb1001bc35245b6..22e49c8b455ecf6d9c2bbf8eaf82dd473c0a89e3 100644 (file)
@@ -15,6 +15,7 @@
 #include "cursor_slice.h"
 
 #include <vector>
+#include <iosfwd>
 
 class BufferView;
 class MathAtom;
@@ -23,6 +24,7 @@ class Paragraph;
 class Row;
 
 
+
 // only needed for gcc 2.95, remove when support terminated
 template <typename A, typename B>
 bool ptr_cmp(A const * a, B const * b)
@@ -166,6 +168,9 @@ public:
        void forwardIdx();
        /// move on one inset
        void forwardInset();
+       /// output
+       friend std::ostream &
+       operator<<(std::ostream & os, DocumentIterator const & cur);
 
 private:
        ///
@@ -182,4 +187,31 @@ DocumentIterator insetBegin(BufferView & bv, InsetBase * inset);
 ///
 DocumentIterator insetEnd();
 
+
+// The difference to a ('non stable') DocumentIterator is the removed
+// (overwritte by 0...) part of the CursorSlice data items. So this thing
+// is suitable for external storage, but not for iteration as such.
+
+class StableDocumentIterator {
+public:
+       ///
+       StableDocumentIterator() {}
+       /// non-explicit intended
+       StableDocumentIterator(const DocumentIterator & it);
+       ///
+       DocumentIterator asDocumentIterator(BufferView & bv) const;
+       ///
+       size_t size() const { return data_.size(); }
+       ///
+       friend std::ostream &
+       operator<<(std::ostream & os, StableDocumentIterator const & cur);
+       ///
+       friend std::istream &
+       operator>>(std::istream & is, StableDocumentIterator & cur);
+private:
+       std::vector<CursorSlice> data_;
+};
+
+bool operator==(StableDocumentIterator const &, StableDocumentIterator const &);
+
 #endif
index 17b81c6bf2feeaeccb6f74d47122752ccb5a56cb..8174217e5dac6f317a89280aa85ffab0154c33b3 100644 (file)
@@ -272,7 +272,7 @@ bool InsetCollapsable::hitButton(FuncRequest const & cmd) const
 
 string const InsetCollapsable::getNewLabel(string const & l) const
 {
-       string la;
+       string label;
        pos_type const max_length = 15;
        pos_type const p_siz = inset.paragraphs().begin()->size();
        pos_type const n = min(max_length, p_siz);
@@ -281,13 +281,13 @@ string const InsetCollapsable::getNewLabel(string const & l) const
        for( ; i < n && j < p_siz; ++j) {
                if (inset.paragraphs().begin()->isInset(j))
                        continue;
-               la += inset.paragraphs().begin()->getChar(j);
+               label += inset.paragraphs().begin()->getChar(j);
                ++i;
        }
        if (inset.paragraphs().size() > 1 || (i > 0 && j < p_siz)) {
-               la += "...";
+               label += "...";
        }
-       return la.empty() ? l : la;
+       return label.empty() ? l : label;
 }
 
 
index dee64f6b12fb0775d078f91f64c1660a32e5ee17..63cda7cf37d6f123811d4eeeaa5666d7204a770d 100644 (file)
@@ -820,7 +820,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose)
        kb_action action = cmd.action;
 
        lyxerr[Debug::ACTION] << "LyXFunc::dispatch: cmd: " << cmd << endl;
-       lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl;
+       //lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl;
 
        // we have not done anything wrong yet.
        errorstat = false;
index 099f31766c0558d2c0a7b62dc6a56d4ca42983ff..2c58c03fb33391a58005113ad35385e75b8f068b 100644 (file)
@@ -307,7 +307,7 @@ void MathNestInset::handleFont
 {
        // this whole function is a hack and won't work for incremental font
        // changes...
-       //recordUndo(cur, Undo::ATOMIC);
+       recordUndo(cur, Undo::ATOMIC);
 
        if (cur.inset()->asMathInset()->name() == font)
                cur.handleFont(font);
@@ -320,7 +320,7 @@ void MathNestInset::handleFont
 
 void MathNestInset::handleFont2(LCursor & cur, string const & arg)
 {
-       //recordUndo(cur, Undo::ATOMIC);
+       recordUndo(cur, Undo::ATOMIC);
        LyXFont font;
        bool b;
        bv_funcs::string2font(arg, font, b);
@@ -354,7 +354,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
                is >> n;
                if (was_macro)
                        cur.macroModeClose();
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                cur.selPaste(n);
                break;
        }
@@ -531,13 +531,13 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
 
        case LFUN_DELETE_WORD_BACKWARD:
        case LFUN_BACKSPACE:
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                cur.backspace();
                break;
 
        case LFUN_DELETE_WORD_FORWARD:
        case LFUN_DELETE:
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                cur.erase();
                cur.dispatched(FINISHED_LEFT);
                break;
@@ -566,7 +566,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
                        cur.dispatched(FINISHED_RIGHT);
                        break;
                }
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                if (cmd.argument.size() != 1) {
                        cur.insert(cmd.argument);
                        break;
@@ -604,7 +604,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
        }
 
        case LFUN_CUT:
-               //recordUndo(cur, Undo::DELETE);
+               recordUndo(cur, Undo::DELETE);
                cur.selCut();
                break;
 
@@ -618,7 +618,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
                if (cmd.argument.empty()) {
                        // do superscript if LyX handles
                        // deadkeys
-                       //recordUndo(cur, Undo::ATOMIC);
+                       recordUndo(cur, Undo::ATOMIC);
                        script(cur, true);
                }
                break;
@@ -695,14 +695,14 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
        case LFUN_MATH_SIZE:
 #if 0
                if (!arg.empty()) {
-                       //recordUndo(cur, Undo::ATOMIC);
+                       recordUndo(cur, Undo::ATOMIC);
                        cur.setSize(arg);
                }
 #endif
                break;
 
        case LFUN_INSERT_MATRIX: {
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                unsigned int m = 1;
                unsigned int n = 1;
                string v_align;
@@ -728,14 +728,14 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
                        ls = '(';
                if (rs.empty())
                        rs = ')';
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                cur.handleNest(MathAtom(new MathDelimInset(ls, rs)));
                break;
        }
 
        case LFUN_SPACE_INSERT:
        case LFUN_MATH_SPACE:
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                cur.insert(MathAtom(new MathSpaceInset(",")));
                break;
 
@@ -746,7 +746,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
 
        case LFUN_INSET_ERT:
                // interpret this as if a backslash was typed
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                interpret(cur, '\\');
                break;
 
@@ -754,7 +754,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
 // handling such that "self-insert" works on "arbitrary stuff" too, and
 // math-insert only handles special math things like "matrix".
        case LFUN_INSERT_MATH:
-               //recordUndo(cur, Undo::ATOMIC);
+               recordUndo(cur, Undo::ATOMIC);
                cur.niceInsert(cmd.argument);
                break;
 
index 74ccfbef415d0244415da1b8a230f134b206f474..8cef593271959d27c3ba245b67ba3d7ee82f76ee 100644 (file)
@@ -898,6 +898,8 @@ void LyXText::redoParagraph(LCursor & cur)
 void LyXText::insertChar(LCursor & cur, char c)
 {
        BOOST_ASSERT(this == cur.text());
+       BOOST_ASSERT(c != Paragraph::META_INSET);
+
        recordUndo(cur, Undo::INSERT);
 
        Paragraph & par = cur.paragraph();
@@ -983,10 +985,7 @@ void LyXText::insertChar(LCursor & cur, char c)
                }
        }
 
-       // Here case LyXText::InsertInset already inserted the character
-       if (c != Paragraph::META_INSET)
-               par.insertChar(cur.pos(), c);
-
+       par.insertChar(cur.pos(), c);
        setCharFont(pit, cur.pos(), rawtmpfont);
 
        current_font = rawtmpfont;
index f5acc81d85e1aafea8b3d99a20dc634481cb48b5..9515b426625a0c0c2c5b3fca710b948faab62c45 100644 (file)
@@ -72,7 +72,7 @@ using std::string;
 
 
 LyXText::LyXText(BufferView * bv, bool in_inset)
-       : height_(0), width_(0), maxwidth_(bv ? bv->workWidth() : 100),
+       : width_(0), maxwidth_(bv ? bv->workWidth() : 100), height_(0),
          background_color_(LColor::background),
          bv_owner(bv), in_inset_(in_inset), xo_(0), yo_(0)
 {}
@@ -865,19 +865,9 @@ void LyXText::updateCounters()
 void LyXText::insertInset(LCursor & cur, InsetBase * inset)
 {
        BOOST_ASSERT(this == cur.text());
-       recordUndo(cur);
-       freezeUndo();
+       BOOST_ASSERT(inset);
        cur.paragraph().insertInset(cur.pos(), inset);
-       // Just to rebreak and refresh correctly.
-       // The character will not be inserted a second time
-       insertChar(cur, Paragraph::META_INSET);
-       // If we enter a highly editable inset the cursor should be before
-       // the inset. After an undo LyX tries to call inset->edit(...)
-       // and fails if the cursor is behind the inset and getInset
-       // does not return the inset!
-       if (isHighlyEditableInset(inset))
-               cursorLeft(cur);
-       unFreezeUndo();
+       redoParagraph(cur);
 }
 
 
@@ -1014,7 +1004,6 @@ void LyXText::setSelectionRange(LCursor & cur, lyx::pos_type length)
 void LyXText::replaceSelectionWithString(LCursor & cur, string const & str)
 {
        recordUndo(cur);
-       freezeUndo();
 
        // Get font setting before we cut
        pos_type pos = cur.selEnd().pos();
@@ -1032,7 +1021,6 @@ void LyXText::replaceSelectionWithString(LCursor & cur, string const & str)
 
        // Cut the selection
        cutSelection(cur, true, false);
-       unFreezeUndo();
 }
 
 
@@ -1124,7 +1112,10 @@ void LyXText::setCursor(CursorSlice & cur, par_type par,
        }
 
        if (pos > end) {
-               lyxerr << "dont like 2 please report" << endl;
+               lyxerr << "dont like 2, pos: " << pos
+                      << " size: " << para.size()
+                      << " row.pos():" << row.pos()
+                      << " par: " << par << endl;
                // This shouldn't happen.
                BOOST_ASSERT(false);
        }
index 113d7b90a368d8a31b804e78abd974b1f381b8a5..ba25ab6020abd888b57e0956ef6811087f30f937 100644 (file)
@@ -90,9 +90,6 @@ namespace {
        void toggleAndShow(LCursor & cur, LyXText * text,
                LyXFont const & font, bool toggleall = true)
        {
-               if (!cur.bv().available())
-                       return;
-
                text->toggleFree(cur, font, toggleall);
 
                if (font.language() != ignore_language ||
@@ -106,7 +103,6 @@ namespace {
                                text->setCursor(cur, cur.par(), cur.pos(),
                                                false, !cur.boundary());
                }
-               cur.update();
        }
 
 
@@ -120,17 +116,17 @@ namespace {
        }
 
 
-       void finishChange(LCursor & cur, bool selecting = false)
+       void finishChange(LCursor & cur, bool selecting)
        {
                finishUndo();
                moveCursor(cur, selecting);
-               cur.bv().owner()->view_state_changed();
        }
 
 
        void mathDispatch(LCursor & cur, LyXText * text,
                FuncRequest const & cmd, bool display)
        {
+               recordUndo(cur);
                string sel = cur.selectionAsString(false);
                lyxerr << "selection is: '" << sel << "'" << endl;
 
@@ -341,6 +337,7 @@ void doInsertInset(LCursor & cur, LyXText * text,
        if (!inset)
                return;
 
+       recordUndo(cur);
        bool gotsel = false;
        if (cur.selection()) {
                cur.bv().owner()->dispatch(FuncRequest(LFUN_CUT));
@@ -410,19 +407,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
        case LFUN_DELETE_WORD_FORWARD:
                cur.clearSelection();
                deleteWordForward(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_DELETE_WORD_BACKWARD:
                cur.clearSelection();
                deleteWordBackward(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_DELETE_LINE_FORWARD:
                cur.clearSelection();
                deleteLineForward(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_WORDRIGHT:
@@ -432,7 +429,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                        cursorLeftOneWord(cur);
                else
                        cursorRightOneWord(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_WORDLEFT:
@@ -442,21 +439,21 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                        cursorRightOneWord(cur);
                else
                        cursorLeftOneWord(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_BEGINNINGBUF:
                if (!cur.mark())
                        cur.clearSelection();
                cursorTop(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_ENDBUF:
                if (!cur.mark())
                        cur.clearSelection();
                cursorBottom(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_RIGHT:
@@ -569,7 +566,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                if (!cur.mark())
                        cur.clearSelection();
                cursorUpParagraph(cur);
-               finishChange(cur);
+               finishChange(cur, false);
                break;
 
        case LFUN_DOWN_PARAGRAPH:
@@ -634,7 +631,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                        cutSelection(cur, true, false);
                }
                moveCursor(cur, false);
-               bv->owner()->view_state_changed();
                break;
 
        case LFUN_DELETE_SKIP:
@@ -664,7 +660,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                } else {
                        cutSelection(cur, true, false);
                }
-               bv->owner()->view_state_changed();
                bv->switchKeyMap();
                cur.update();
                break;
@@ -688,7 +683,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                cur.update();
                cur.resetAnchor();
                bv->switchKeyMap();
-               bv->owner()->view_state_changed();
                break;
 
        case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
@@ -697,7 +691,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                cur.update();
                cur.resetAnchor();
                bv->switchKeyMap();
-               bv->owner()->view_state_changed();
                break;
 
        case LFUN_BREAKPARAGRAPH_SKIP: {
@@ -717,7 +710,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                cur.update();
 //     anchor() = cur;
                bv->switchKeyMap();
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -774,6 +766,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
        }
 
        case LFUN_INSET_INSERT: {
+               recordUndo(cur);
                InsetBase * inset = createInset(bv, cmd);
                if (inset)
                        insertInset(cur, inset);
@@ -1192,7 +1185,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                        bv->haveSelection(cur.selection());
 
                bv->switchKeyMap();
-               bv->owner()->view_state_changed();
                bv->owner()->updateMenubar();
                bv->owner()->updateToolbar();
                break;
@@ -1229,7 +1221,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                // real_current_font.number can change so we need to
                // update the minibuffer
                if (old_font != real_current_font)
-                       bv->owner()->view_state_changed();
                bv->updateScrollbar();
                break;
        }
@@ -1341,7 +1332,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setEmph(LyXFont::TOGGLE);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1349,7 +1339,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setSeries(LyXFont::BOLD_SERIES);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1357,7 +1346,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setNoun(LyXFont::TOGGLE);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1365,7 +1353,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1373,7 +1360,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setFamily(LyXFont::SANS_FAMILY);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1381,14 +1367,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setFamily(LyXFont::ROMAN_FAMILY);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
        case LFUN_DEFAULT: {
                LyXFont font(LyXFont::ALL_INHERIT, ignore_language);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1396,7 +1380,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setUnderbar(LyXFont::TOGGLE);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1404,7 +1387,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                LyXFont font(LyXFont::ALL_IGNORE);
                font.setLyXSize(cmd.argument);
                toggleAndShow(cur, this, font);
-               bv->owner()->view_state_changed();
                break;
        }
 
@@ -1416,13 +1398,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                font.setLanguage(lang);
                toggleAndShow(cur, this, font);
                bv->switchKeyMap();
-               bv->owner()->view_state_changed();
                break;
        }
 
        case LFUN_FREEFONT_APPLY:
                toggleAndShow(cur, this, freefont, toggleall);
-               bv->owner()->view_state_changed();
                cur.message(_("Character set"));
                break;
 
@@ -1435,7 +1415,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                        freefont = font;
                        toggleall = toggle;
                        toggleAndShow(cur, this, freefont, toggleall);
-                       bv->owner()->view_state_changed();
                        cur.message(_("Character set"));
                }
                break;
@@ -1519,7 +1498,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
                if (tclass.floats().typeExist(cmd.argument)) {
                        // not quite sure if we want this...
                        recordUndo(cur);
-                       freezeUndo();
                        cur.clearSelection();
                        breakParagraph(cur);
 
@@ -1530,8 +1508,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
 
                        setLayout(cur, tclass.defaultLayoutName());
                        setParagraph(cur, Spacing(), LYX_ALIGN_LAYOUT, string(), 0);
-                       cur.insert(new InsetFloatList(cmd.argument));
-                       unFreezeUndo();
+                       insertInset(cur, new InsetFloatList(cmd.argument));
                } else {
                        lyxerr << "Non-existent float type: "
                               << cmd.argument << endl;
index c5a14fe45b92a23600ed89f71b1f595cbb270439..9d028f03c7b18bf0d0764d5d2b23f7c44e481c8f 100644 (file)
 #include "cursor.h"
 #include "debug.h"
 #include "BufferView.h"
-#include "iterators.h"
 #include "lyxtext.h"
 #include "paragraph.h"
 
+#include "mathed/math_support.h"
+
+#include <algorithm>
+
 using lyx::paroffset_type;
 
 
@@ -38,46 +41,9 @@ bool undo_finished;
 
 std::ostream & operator<<(std::ostream & os, Undo const & undo)
 {
-       return os << " text: " << undo.text
-               << " index: " << undo.index
-               << " first: " << undo.first_par
-               << " from end: " << undo.end_par
-               << " cursor: " << undo.cursor_par
-               << "/" << undo.cursor_pos;
-}
-
-
-// translates LyXText pointer into offset count from document begin
-ParIterator text2pit(Buffer & buf, LyXText * text, int & tcount)
-{
-       tcount = 0;
-       ParIterator pit = buf.par_iterator_begin();
-       ParIterator end = buf.par_iterator_end();
-
-       for ( ; pit != end; ++pit, ++tcount)
-               if (pit.text(buf) == text)
-                       return pit;
-       lyxerr << "undo: should not happen" << std::endl;
-       return end;
-}
-
-
-// translates offset from buffer begin to ParIterator
-ParIterator num2pit(Buffer & buf, int num)
-{
-       ParIterator pit = buf.par_iterator_begin();
-       ParIterator end = buf.par_iterator_end();
-
-       for ( ; num && pit != end; ++pit, --num)
-               ;
-
-       if (pit != end)
-               return pit;
-
-       // don't crash early...
-       lyxerr << "undo: num2pit: num: " << num << std::endl;
-       BOOST_ASSERT(false);
-       return buf.par_iterator_begin();
+       return os << " from: " << undo.from
+               << " end: " << undo.end
+               << " cursor:\n" << undo.cursor;
 }
 
 
@@ -85,126 +51,90 @@ void recordUndo(Undo::undo_kind kind,
        LCursor & cur, paroffset_type first_par, paroffset_type last_par,
        limited_stack<Undo> & stack)
 {
-#if 0
-       DocumentIterator it = bufferBegin(cur.bv());
-       DocumentIterator et = bufferEnd();
-       size_t count = 0;
-       for ( ; it != et; it.forwardPos(), ++count)
-               if (it.top() == cur.top())
-                       lyxerr << "### found at " << count << std::endl;
-#endif
-
-       if (first_par > last_par) {
-               paroffset_type t = first_par;
-               first_par = last_par;
-               last_par = t;
-       }
+       BOOST_ASSERT(first_par <= cur.lastpar());
+       BOOST_ASSERT(last_par <= cur.lastpar());
 
-       Buffer & buf = *cur.bv().buffer();
-       int const end_par = cur.lastpar() + 1 - last_par;
+       if (first_par > last_par)
+               std::swap(first_par, last_par);
 
-       // Undo::ATOMIC are always recorded (no overlapping there).
-       // overlapping only with insert and delete inside one paragraph:
-       // nobody wants all removed character appear one by one when undoing.
-       if (!undo_finished && kind != Undo::ATOMIC) {
-               // Check whether storing is needed.
-               if (!buf.undostack().empty()
-                   && buf.undostack().top().kind == kind
-                   && buf.undostack().top().first_par == first_par
-                   && buf.undostack().top().end_par == end_par) {
-                       // No additonal undo recording needed -
-                       // effectively, we combine undo recordings to one.
-                       return;
-               }
-       }
+       // create the position information of the Undo entry
+       Undo undo;
+       undo.kind = kind;
+       undo.cursor = StableDocumentIterator(cur);
+       undo.from = first_par;
+       undo.end = cur.lastpar() - last_par;
 
-       // push and fill the Undo entry
-       if (cur.inTexted()) {
-               stack.push(Undo());
-               LyXText * text = cur.text();
-               int textnum;
-               ParIterator pit = text2pit(buf, text, textnum);
-               Undo & undo = stack.top();
-               undo.kind = kind;
-               undo.text = textnum;
-               undo.index = pit.index();
-               undo.first_par = first_par;
-               undo.end_par = end_par;
-               undo.cursor_par = cur.par();
-               undo.cursor_pos = cur.pos();
-               undo.math = false;
-               //lyxerr << "undo record: " << stack.top() << std::endl;
+       // Undo::ATOMIC are always recorded (no overlapping there).
+       // As nobody wants all removed character appear one by one when undoing,
+       // we want combine 'similar' non-ATOMIC undo recordings to one.
+       if (!undo_finished
+           && kind != Undo::ATOMIC
+           && !stack.empty()
+           && stack.top().cursor.size() == undo.cursor.size()
+                 && stack.top().kind == undo.kind
+                 && stack.top().from == undo.from
+                 && stack.top().end == undo.end)
+               return;
 
+       // fill in the real data to be saved
+       if (cur.inMathed()) {
+               // simply use the whole cell
+               undo.array = asString(cur.cell());
+       } else {
+               // some more effort needed here as 'the whole cell' of the
+               // main LyXText _is_ the whole document.
                // record the relevant paragraphs
+               LyXText * text = cur.text();
+               BOOST_ASSERT(text);
                ParagraphList & plist = text->paragraphs();
                ParagraphList::iterator first = plist.begin();
                advance(first, first_par);
                ParagraphList::iterator last = plist.begin();
-               advance(last, last_par);
-
-               for (ParagraphList::iterator it = first; it != last; ++it)
-                       undo.pars.push_back(*it);
-               undo.pars.push_back(*last);
-       } else {
-               BOOST_ASSERT(false); // not in mathed (yet)
-               stack.push(Undo());
-               Undo & undo = stack.top();
-               undo.math = false;
+               advance(last, last_par + 1);
+               undo.pars = ParagraphList(first, last);
        }
 
-       // and make sure that next time, we should be combining if possible
+       // push the undo entry to undo stack 
+       //lyxerr << "undo record: " << stack.top() << std::endl;
+       stack.push(undo);
+
+       // next time we'll try again to combine entries if possible
        undo_finished = false;
 }
 
 
-// returns false if no undo possible
-bool performUndoOrRedo(BufferView & bv, Undo const & undo)
+void performUndoOrRedo(BufferView & bv, Undo const & undo)
 {
-       Buffer & buf = *bv.buffer();
+       LCursor & cur = bv.cursor();
        lyxerr << "undo, performing: " << undo << std::endl;
-       ParIterator pit = num2pit(buf, undo.text);
-       LyXText * text = pit.text(buf);
-       ParagraphList & plist = text->paragraphs();
+       cur.setCursor(undo.cursor.asDocumentIterator(bv), false);
 
-       // remove new stuff between first and last
-       {
+       if (cur.inMathed()) {
+               // We stored the full cell here as there is not much to be
+               // gained by storing just 'a few' paragraphs (most if not
+               // all math inset cells have just one paragraph!)
+               asArray(undo.array, cur.cell());
+       } else {
+               // Some finer machinery is needed here.
+               LyXText * text = cur.text();
+               BOOST_ASSERT(text);
+               ParagraphList & plist = text->paragraphs();
+
+               // remove new stuff between first and last
                ParagraphList::iterator first = plist.begin();
-               advance(first, undo.first_par);
+               advance(first, undo.from);
                ParagraphList::iterator last = plist.begin();
-               advance(last, plist.size() - undo.end_par);
-               plist.erase(first, ++last);
-       }
+               advance(last, plist.size() - undo.end);
+               plist.erase(first, last);
 
-       // re-insert old stuff instead
-       if (plist.empty()) {
-               plist.assign(undo.pars.begin(), undo.pars.end());
-       } else {
-               ParagraphList::iterator first = plist.begin();
-               advance(first, undo.first_par);
+               // re-insert old stuff instead
+               first = plist.begin();
+               advance(first, undo.from);
                plist.insert(first, undo.pars.begin(), undo.pars.end());
        }
 
-       // set cursor
-       lyxerr << "undo, text: " << undo.text
-              << " inset: " << pit.inset()
-              << " index: " << undo.index
-              << " par: " << undo.cursor_par
-              << " pos: " << undo.cursor_pos
-              << std::endl;
-
-       text->updateCounters();
-
-       // rebreak the entire lyxtext
-#warning needed?
-       text->redoParagraphs(buf.paragraphs().begin(), buf.paragraphs().end());
-       bv.cursor().resetAnchor();
-
-       ParIterator pit2 = num2pit(buf, undo.text);
-       advance(pit2, undo.cursor_par);
-       bv.setCursor(pit2, undo.cursor_pos);
-
+       cur.resetAnchor();
        finishUndo();
-       return true;
 }
 
 
@@ -212,7 +142,6 @@ bool performUndoOrRedo(BufferView & bv, Undo const & undo)
 bool textUndoOrRedo(BufferView & bv,
        limited_stack<Undo> & stack, limited_stack<Undo> & otherstack)
 {
-       Buffer & buf = *bv.buffer();
        if (stack.empty()) {
                // nothing to do
                finishUndo();
@@ -223,45 +152,37 @@ bool textUndoOrRedo(BufferView & bv,
        stack.pop();
        finishUndo();
 
+       // this implements redo
        if (!undo_frozen) {
                otherstack.push(undo);
-               otherstack.top().pars.clear();
-               ParIterator pit = num2pit(buf, undo.text);
-               ParagraphList & plist = pit.plist();
-               if (undo.first_par + undo.end_par <= int(plist.size())) {
-                       ParagraphList::iterator first = plist.begin();
-                       advance(first, undo.first_par);
-                       ParagraphList::iterator last = plist.begin();
-                       advance(last, plist.size() - undo.end_par + 1);
-                       otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last);
+               DocumentIterator dit = undo.cursor.asDocumentIterator(bv);
+               if (dit.inMathed()) {
+                       // not much to be done
+               } else {
+                       otherstack.top().pars.clear();
+                       LyXText * text = dit.text();
+                       BOOST_ASSERT(text);
+                       ParagraphList & plist = text->paragraphs();
+                       if (undo.from + undo.end <= int(plist.size())) {
+                               ParagraphList::iterator first = plist.begin();
+                               advance(first, undo.from);
+                               ParagraphList::iterator last = plist.begin();
+                               advance(last, plist.size() - undo.end);
+                               otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last);
+                       }
                }
-               otherstack.top().cursor_pos = bv.cursor().pos();
-               otherstack.top().cursor_par = bv.cursor().par();
-               lyxerr << " undo other: " << otherstack.top() << std::endl;
+               otherstack.top().cursor = bv.cursor();
+               //lyxerr << " undo other: " << otherstack.top() << std::endl;
        }
 
-       freezeUndo();
-       bool const ret = performUndoOrRedo(bv, undo);
-       unFreezeUndo();
-       return ret;
-}
-
-} // namespace anon
-
-
-void freezeUndo()
-{
-       // this is dangerous and for internal use only
        undo_frozen = true;
-}
-
-
-void unFreezeUndo()
-{
-       // this is dangerous and for internal use only
+       performUndoOrRedo(bv, undo);
        undo_frozen = false;
+       return true;
 }
 
+} // namespace anon
+
 
 void finishUndo()
 {
@@ -292,6 +213,9 @@ void recordUndo(Undo::undo_kind kind,
        Buffer * buf = cur.bv().buffer();
        recordUndo(kind, cur, first, last, buf->undostack());
        buf->redostack().clear();
+       //lyxerr << "undostack:\n";
+       //for (size_t i = 0, n = buf->undostack().size(); i != n && i < 6; ++i)
+       //      lyxerr << "  " << i << ": " << buf->undostack()[i] << std::endl;
 }
 
 
index 17fc89dc62309c559f3fcf4b2822d1a7e46b4849..6c3dcdd59a8b70677ab496ecbe138cca3965ca2d 100644 (file)
@@ -16,7 +16,9 @@
 #ifndef UNDO_H
 #define UNDO_H
 
+#include "dociterator.h"
 #include "ParagraphList_fwd.h"
+
 #include "support/types.h"
 
 #include <string>
@@ -49,24 +51,16 @@ struct Undo {
 
        /// which kind of operation are we recording for?
        undo_kind kind;
-       /// hosting LyXText counted from buffer begin
-       int text;
-       /// cell in a tabular or similar
-       int index;
-       /// offset to the first paragraph in the paragraph list
-       int first_par;
-       /// offset to the last paragraph from the end of paragraph list
-       int end_par;
-       /// offset to the first paragraph in the paragraph list
-       int cursor_par;
-       /// the position of the cursor in the hosting paragraph
-       int cursor_pos;
+       /// the position of the cursor
+       StableDocumentIterator cursor;
+       /// counted from begin of buffer
+       lyx::paroffset_type from;
+       /// complement to end of this cell
+       lyx::paroffset_type end;
        /// the contents of the saved paragraphs (for texted)
        ParagraphList pars;
        /// the contents of the saved matharray (for mathed)
        std::string array;
-       /// in mathed?
-       bool math;
 };
 
 
@@ -79,12 +73,6 @@ bool textRedo(BufferView &);
 /// makes sure the next operation will be stored
 void finishUndo();
 
-/// whilst undo is frozen, no actions gets added to the undo stack
-void freezeUndo();
-
-/// track undos again
-void unFreezeUndo();
-
 
 /**
  * Record undo information - call with the current cursor and the 'other