]> git.lyx.org Git - features.git/commitdiff
John's InsetTabular cursor patch and modifications/fixes to undo/redo code.
authorJürgen Vigna <jug@sad.it>
Fri, 14 Dec 2001 11:55:58 +0000 (11:55 +0000)
committerJürgen Vigna <jug@sad.it>
Fri, 14 Dec 2001 11:55:58 +0000 (11:55 +0000)
TODO: Still some problems in multiparagraph redo! And deleting of substituted
      paragraphs when undoing/redoing.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3209 a592a061-630c-0410-9148-cb99ea01b6c8

12 files changed:
src/BufferView2.C
src/ChangeLog
src/insets/ChangeLog
src/insets/inset.h
src/insets/insetcollapsable.h
src/insets/insettabular.C
src/insets/insettabular.h
src/insets/insettext.C
src/insets/insettext.h
src/lyxfunc.C
src/text2.C
src/undo_funcs.C

index 2fad793b7bab3817cda0e9e9499d4b671c6bcb04..2dde52ce02830d1566ff12c8f94cdf0783811f5c 100644 (file)
@@ -249,10 +249,12 @@ void BufferView::menuUndo()
 
 void BufferView::menuRedo()
 {
+#if 0 // this should not be here (Jug 20011206)
        if (theLockingInset()) {
                owner()->message(_("Redo not yet supported in math mode"));
                return;
-       }    
+       }
+#endif
    
        if (available()) {
                owner()->message(_("Redo"));
@@ -398,16 +400,46 @@ void BufferView::replaceWord(string const & replacestring)
 
 bool BufferView::lockInset(UpdatableInset * inset)
 {
+       if (!inset)
+               return false;
        // don't relock if we're already locked
        if (theLockingInset() == inset)
                return true;
-       if (!theLockingInset() && inset) {
-               theLockingInset(inset);
-               return true;
-       } else if (inset) {
-           return theLockingInset()->lockInsetInInset(this, inset);
+       if (!theLockingInset()) {
+               // first check if it's the inset under the cursor we want lock
+               // should be most of the time
+               char const c = text->cursor.par()->getChar(text->cursor.pos());
+               if (c == Paragraph::META_INSET) {
+                       Inset * in = text->cursor.par()->getInset(text->cursor.pos());
+                       if (inset == in) {
+                               theLockingInset(inset);
+                               return true;
+                       }
+               }
+               // Then do a deep look of the inset and lock the right one
+               Paragraph * par = buffer()->paragraph;
+               int const id = inset->id();
+               while(par) {
+                       Paragraph::inset_iterator it =
+                               par->inset_iterator_begin();
+                       Paragraph::inset_iterator const end =
+                               par->inset_iterator_end();
+                       for (; it != end; ++it) {
+                               if ((*it) == inset) {
+                                       theLockingInset(inset);
+                                       return true;
+                               }
+                               if ((*it)->getInsetFromID(id)) {
+                                       text->setCursorIntern(this, par, it.getPos());
+                                       theLockingInset(static_cast<UpdatableInset *>(*it));
+                                       return theLockingInset()->lockInsetInInset(this, inset);
+                               }
+                       }
+                       par = par->next();
+               }
+               return false;
        }
-       return false;
+       return theLockingInset()->lockInsetInInset(this, inset);
 }
 
 
@@ -461,6 +493,8 @@ void BufferView::fitLockedInsetCursor(int x, int y, int asc, int desc)
 
 int BufferView::unlockInset(UpdatableInset * inset)
 {
+       if (!inset)
+               return 0;
        if (inset && theLockingInset() == inset) {
                inset->insetUnlock(this);
                theLockingInset(0);
index 2d3cfd4cd0275e012b4e6cccd645c122ba30ff06..ff14ac48ab688c58702d2c7f70262c4e63066f7f 100644 (file)
@@ -1,3 +1,16 @@
+2001-12-13  Juergen Vigna  <jug@sad.it>
+
+       * undo_funcs.C (textRedo/Undo): fixed as the first paragraph was
+       actually sometimes the before-paragraph.
+       (setUndo): don't clear the redostack if we're not actually undoing!
+
+2001-12-06  Juergen Vigna  <jug@sad.it>
+
+       * undo_funcs.C (textHandleUndo): well after John's hint I got here
+       and fixed redoing of main paragraph, so we can use it now ;)
+
+       * text2.C (redoParagraphs): fixed a crash when having only 1 row!
+
 2001-12-13  Jean-Marc Lasgouttes  <lasgouttes@freesurf.fr>
 
        * undo_funcs.C (textHandleUndo): undo undo leak fix below, as per
index b783858270005ad0d82d9886d3b43252a52393e5..984d306d01e949b9ac7e7d5af0c48d746b6db015 100644 (file)
@@ -1,3 +1,14 @@
+2001-12-07  Juergen Vigna  <jug@sad.it>
+
+       * insettext.C (paragraph): remove the deleteing of paragraphs as
+       it was a WRONG move!
+
+2001-12-06  John Levon  <moz@compsoc.man.ac.uk>
+
+       * insettabular.h:
+       * insettabular.C: use new setSelection(). Allow
+         selection of single cells.
+
 2001-12-12  Jean-Marc Lasgouttes  <lasgouttes@freesurf.fr>
 
        * insetquotes.C (latex): fix to use the local language setting at
index a3b98f022ddbcd9fa345826eeabf196397b2cef4..9e9c654d1ab704855a0eab2d5cf44ac8102be078 100644 (file)
@@ -464,7 +464,7 @@ public:
                { return false; }
        ///
        virtual bool unlockInsetInInset(BufferView *, UpdatableInset *,
-                                       bool /*lr*/ = false)
+                                       bool /*lr*/ = false)
                { return false; }
        ///  An updatable inset could handle lyx editing commands
        virtual RESULT localDispatch(BufferView *, kb_action, string const &);
index 0e15112f60cdc515358b707935efbfe60cd1475a..9f73fbbbe8c5b88cdf6f29a90ff5362441388e1b 100644 (file)
@@ -83,7 +83,7 @@ public:
        bool lockInsetInInset(BufferView *, UpdatableInset *);
        ///
        bool unlockInsetInInset(BufferView *, UpdatableInset *,
-                               bool lr = false);
+                               bool lr = false);
        ///
        bool updateInsetInInset(BufferView *, Inset *);
        ///
index ebc196602a67770b3704d3fd547e1ba86867a2bb..2da68f6db4594aa409b9b391dd96a9c0395bec29 100644 (file)
@@ -134,7 +134,7 @@ InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
        // for now make it always display as display() inset
        // just for test!!!
        the_locking_inset = 0;
-       locked = no_selection = false;
+       locked = false;
        oldcell = -1;
        actrow = actcell = 0;
        clearSelection();
@@ -150,10 +150,10 @@ InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf,
 {
        tabular.reset(new LyXTabular(this, *(tab.tabular), same_id));
        the_locking_inset = 0;
-       locked = no_selection = false;
+       locked = false;
        oldcell = -1;
        actrow = actcell = 0;
-       sel_cell_start = sel_cell_end = 0;
+       clearSelection();
        need_update = INIT;
        in_update = false;
        in_reset_pos = false;
@@ -296,11 +296,11 @@ void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
                                cx = nx + tabular->GetBeginningOfTextInCell(cell);
                                if (first_visible_cell < 0)
                                        first_visible_cell = cell;
-                               if (hasSelection())
+                               if (hasSelection()) {
                                        drawCellSelection(pain, nx, baseline, i, j, cell);
+                               }
                                
-                               tabular->GetCellInset(cell)->draw(bv, font, baseline, cx,
-                                                                                                 cleared);
+                               tabular->GetCellInset(cell)->draw(bv, font, baseline, cx, cleared);
                                drawCellLines(pain, nx, baseline, i, cell);
                                nx += tabular->GetWidthOfColumn(cell);
                                ++cell;
@@ -448,6 +448,7 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int baseline,
 void InsetTabular::drawCellSelection(Painter & pain, int x, int baseline,
                                     int row, int column, int cell) const
 {
+       lyx::Assert(hasSelection());
        int cs = tabular->column_of_cell(sel_cell_start);
        int ce = tabular->column_of_cell(sel_cell_end);
        if (cs > ce) {
@@ -534,7 +535,7 @@ void InsetTabular::edit(BufferView * bv, int x, int y, unsigned int button)
        inset_x = 0;
        inset_y = 0;
        setPos(bv, x, y);
-       sel_cell_start = sel_cell_end = actcell;
+       clearSelection();
        finishUndo();
        if (insetHit(bv, x, y) && (button != 3)) {
                activateCellInsetAbs(bv, x, y, button);
@@ -558,7 +559,7 @@ void InsetTabular::edit(BufferView * bv, bool front)
                actcell = 0;
        else
                actcell = tabular->GetNumberOfCells() - 1;
-       sel_cell_start = sel_cell_end = actcell;
+       clearSelection();
        resetPos(bv);
        finishUndo();
 }
@@ -571,11 +572,10 @@ void InsetTabular::insetUnlock(BufferView * bv)
                the_locking_inset = 0;
        }
        hideInsetCursor(bv);
-       no_selection = false;
        oldcell = -1;
        locked = false;
        if (scroll(false) || hasSelection()) {
-               sel_cell_start = sel_cell_end = 0;
+               clearSelection();
                if (scroll(false)) {
                        scroll(bv, 0.0F);
                }
@@ -593,8 +593,9 @@ void InsetTabular::updateLocal(BufferView * bv, UpdateCodes what,
        }
        if (need_update < what) // only set this if it has greater update
                need_update = what;
-       if ((what == INIT) && hasSelection())
+       if ((what == INIT) && hasSelection()) {
                clearSelection();
+       }
        // Dirty Cast! (Lgb)
        if (need_update != NONE) {
                bv->updateInset(const_cast<InsetTabular *>(this), mark_dirty);
@@ -616,6 +617,26 @@ bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
                the_locking_inset = tabular->GetCellInset(actcell);
                resetPos(bv);
                return true;
+       } else if (!the_locking_inset) {
+               int const n = tabular->GetNumberOfCells();
+               int const id = inset->id();
+               for (int i = 0; i < n; ++i) {
+                       InsetText * in = tabular->GetCellInset(i);
+                       if (inset == in) {
+                               actcell = i;
+                               the_locking_inset = in;
+                               locked = true;
+                               resetPos(bv);
+                               return true;
+                       }
+                       if (in->getInsetFromID(id)) {
+                               actcell = i;
+                               the_locking_inset = in;
+                               locked = true;
+                               resetPos(bv);
+                               return the_locking_inset->lockInsetInInset(bv, inset);
+                       }
+               }
        } else if (the_locking_inset && (the_locking_inset == inset)) {
                lyxerr[Debug::INSETTEXT] << "OK" << endl;
                resetPos(bv);
@@ -716,8 +737,6 @@ void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button)
                updateLocal(bv, SELECTION, false);
        }
 
-       no_selection = false;
-
        int const ocell = actcell;
        int const orow = actrow;
 
@@ -725,7 +744,7 @@ void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button)
        setPos(bv, x, y);
        if (actrow != orow)
                updateLocal(bv, NONE, false);
-       sel_cell_start = sel_cell_end = actcell;
+       clearSelection();
        if (button == 3) {
                if ((ocell != actcell) && the_locking_inset) {
                        the_locking_inset->insetUnlock(bv);
@@ -783,7 +802,6 @@ void InsetTabular::insetButtonRelease(BufferView * bv,
                                                      button);
                return;
        }
-       no_selection = false;
 }
 
 
@@ -796,17 +814,18 @@ void InsetTabular::insetMotionNotify(BufferView * bv, int x, int y, int button)
                                                     button);
                return;
        }
-       if (!no_selection) {
-               hideInsetCursor(bv);
-               int const old_cell = actcell;
-               
-               setPos(bv, x, y);
-               sel_cell_end = actcell;
-               if (sel_cell_end != old_cell)
-                       updateLocal(bv, SELECTION, false);
-               showInsetCursor(bv);
+       hideInsetCursor(bv);
+//     int const old_cell = actcell;
+       
+       setPos(bv, x, y);
+       if (!hasSelection()) {
+               setSelection(actcell, actcell);
+       } else {
+               setSelection(sel_cell_start, actcell);
        }
-       no_selection = false;
+       updateLocal(bv, SELECTION, false);
+       showInsetCursor(bv);
 }
 
 
@@ -826,7 +845,6 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        // We need to save the value of the_locking_inset as the call to 
        // the_locking_inset->LocalDispatch might unlock it.
        old_locking_inset = the_locking_inset;
-       no_selection = false;
        UpdatableInset::RESULT result =
                UpdatableInset::localDispatch(bv, action, arg);
        if (result == DISPATCHED || result == DISPATCHED_NOUPDATE) {
@@ -852,7 +870,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                                moveNextCell(bv, old_locking_inset != 0);
                        else
                                movePrevCell(bv, old_locking_inset != 0);
-                       sel_cell_start = sel_cell_end = actcell;
+                       clearSelection();
                        if (hs)
                                updateLocal(bv, SELECTION, false);
                        if (!the_locking_inset) {
@@ -895,65 +913,96 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        result=DISPATCHED;
        switch (action) {
                // --- Cursor Movements ----------------------------------
-       case LFUN_RIGHTSEL:
-               if (tabular->IsLastCellInRow(actcell))
+       case LFUN_RIGHTSEL: {
+               int const start = hasSelection() ? sel_cell_start : actcell;
+               if (tabular->IsLastCellInRow(actcell)) {
+                       setSelection(start, actcell);
                        break;
-               moveRight(bv, false);
-               sel_cell_end = actcell;
+               }
+               
+               int end = actcell;
+               // if we are starting a selection, only select
+               // the current cell at the beginning
+               if (hasSelection()) {
+                       moveRight(bv, false);
+                       end = actcell;
+               }
+               setSelection(start, end);
                updateLocal(bv, SELECTION, false);
                break;
+       }
        case LFUN_RIGHT:
                result = moveRight(bv);
-               sel_cell_start = sel_cell_end = actcell;
+               clearSelection();
                if (hs)
                        updateLocal(bv, SELECTION, false);
                break;
-       case LFUN_LEFTSEL:
-               if (tabular->IsFirstCellInRow(actcell))
+       case LFUN_LEFTSEL: {
+               int const start = hasSelection() ? sel_cell_start : actcell;
+               if (tabular->IsFirstCellInRow(actcell)) {
+                       setSelection(start, actcell);
                        break;
-               moveLeft(bv, false);
-               sel_cell_end = actcell;
+               }
+               int end = actcell;
+               // if we are starting a selection, only select
+               // the current cell at the beginning
+               if (hasSelection()) { 
+                       moveLeft(bv, false);
+                       end = actcell;
+               }
+               setSelection(start, end);
                updateLocal(bv, SELECTION, false);
                break;
+       }
        case LFUN_LEFT:
                result = moveLeft(bv);
-               sel_cell_start = sel_cell_end = actcell;
+               clearSelection();
                if (hs)
                        updateLocal(bv, SELECTION, false);
                break;
-       case LFUN_DOWNSEL:
-       {
+       case LFUN_DOWNSEL: {
+               int const start = hasSelection() ? sel_cell_start : actcell;
                int const ocell = actcell;
-               moveDown(bv, false);
+               // if we are starting a selection, only select
+               // the current cell at the beginning
+               if (hasSelection()) { 
+                       moveDown(bv, false);
+               }
                if ((ocell == sel_cell_end) ||
                    (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
-                       sel_cell_end = tabular->GetCellBelow(sel_cell_end);
+                       setSelection(start, tabular->GetCellBelow(sel_cell_end));
                else
-                       sel_cell_end = tabular->GetLastCellBelow(sel_cell_end);
+                       setSelection(start, tabular->GetLastCellBelow(sel_cell_end));
                updateLocal(bv, SELECTION, false);
        }
        break;
        case LFUN_DOWN:
                result = moveDown(bv, old_locking_inset != 0);
-               sel_cell_start = sel_cell_end = actcell;
-               if (hs)
+               clearSelection();
+               if (hs) {
                        updateLocal(bv, SELECTION, false);
+               }
                break;
-       case LFUN_UPSEL:
-       {
+       case LFUN_UPSEL: {
+               int const start = hasSelection() ? sel_cell_start : actcell;
                int const ocell = actcell;
-               moveUp(bv, false);
+               // if we are starting a selection, only select
+               // the current cell at the beginning
+               if (hasSelection()) {
+                       moveUp(bv, false);
+               }
                if ((ocell == sel_cell_end) ||
                    (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
-                       sel_cell_end = tabular->GetCellAbove(sel_cell_end);
+                       setSelection(start, tabular->GetCellAbove(sel_cell_end));
                else
-                       sel_cell_end = tabular->GetLastCellAbove(sel_cell_end);
+                       setSelection(start, tabular->GetLastCellAbove(sel_cell_end));
                updateLocal(bv, SELECTION, false);
        }
        break;
        case LFUN_UP:
                result = moveUp(bv, old_locking_inset != 0);
-               sel_cell_start = sel_cell_end = actcell;
+               clearSelection();
                if (hs)
                        updateLocal(bv, SELECTION, false);
                break;
@@ -1575,8 +1624,7 @@ void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall,
                            bool selectall)
 {
        if (selectall) {
-               sel_cell_start = 0;
-               sel_cell_end = tabular->GetNumberOfCells() - 1;
+               setSelection(0, tabular->GetNumberOfCells() - 1);
        }
        if (hasSelection()) {
                setUndo(bv, Undo::EDIT,
@@ -1876,7 +1924,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                }
                tabular->SetMultiColumn(s_start, s_end - s_start + 1);
                actcell = s_start;
-               sel_cell_end = sel_cell_start;
+               clearSelection();
                updateLocal(bv, INIT, true);
                break;
        }
@@ -2480,17 +2528,22 @@ bool InsetTabular::doClearArea() const
 
 void InsetTabular::getSelection(int & srow, int & erow, int & scol, int & ecol) const
 {
-               srow = tabular->row_of_cell(sel_cell_start);
-               erow = tabular->row_of_cell(sel_cell_end);
-               if (srow > erow)
-                       swap(srow, erow);
+       int const start = hasSelection() ? sel_cell_start : actcell;
+       int const end = hasSelection() ? sel_cell_end : actcell;
+       srow = tabular->row_of_cell(start);
+       erow = tabular->row_of_cell(end);
+       if (srow > erow) {
+               swap(srow, erow);
+       }
 
-               scol = tabular->column_of_cell(sel_cell_start);
-               ecol = tabular->column_of_cell(sel_cell_end);
-               if (scol > ecol)
-                       swap(scol, ecol);
-               else
-                       ecol = tabular->right_column_of_cell(sel_cell_end);
+       scol = tabular->column_of_cell(start);
+       ecol = tabular->column_of_cell(end);
+       if (scol > ecol) {
+               swap(scol, ecol);
+       } else {
+               ecol = tabular->right_column_of_cell(end);
+       }
 }
 
 
index ae89b37ca065937c0c81cfeb3c4d68987629aba5..d53d4305d292c863f225163463bd41e4e5beb003 100644 (file)
@@ -269,11 +269,17 @@ private:
        void removeTabularRow();
        ///
        bool hasSelection() const {
-               return sel_cell_start != sel_cell_end;
+               return has_selection;
        }
        ///
        void clearSelection() const {
-       sel_cell_start = sel_cell_end = 0;
+               sel_cell_start = sel_cell_end = 0;
+               has_selection = false;
+       }
+       void setSelection(int start, int end) const {
+               sel_cell_start = start;
+               sel_cell_end = end;
+               has_selection = true;
        }
        ///
        bool activateCellInset(BufferView *, int x = 0, int y = 0,
@@ -316,9 +322,11 @@ private:
        mutable unsigned int inset_x;
        ///
        mutable unsigned int inset_y;
-       ///
+       /// true if a set of cells are selected
+       mutable bool has_selection;
+       /// the starting cell selection nr
        mutable int sel_cell_start;
-       ///
+       /// the ending cell selection nr
        mutable int sel_cell_end;
        ///
        mutable int actcell;
index aff7ff54eaab2ff0a6841fedc1cdcf4b43e1c2ad..1e0a9906fbfc36df01b4c07797c90e1fd64a8cd2 100644 (file)
@@ -780,6 +780,17 @@ void InsetText::insetUnlock(BufferView * bv)
                lt = 0;
 }
 
+void InsetText::lockInset(BufferView * bv, UpdatableInset * inset)
+{
+       the_locking_inset = inset;
+       inset_x = cx(bv) - top_x + drawTextXOffset;
+       inset_y = cy(bv) + drawTextYOffset;
+       inset_pos = cpos(bv);
+       inset_par = cpar(bv);
+       inset_boundary = cboundary(bv);
+       updateLocal(bv, CURSOR, false);
+}
+
 
 bool InsetText::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
 {
@@ -787,15 +798,32 @@ bool InsetText::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
                              << inset << "): ";
        if (!inset)
                return false;
+       if (!the_locking_inset) {
+               Paragraph * p = par;
+               int const id = inset->id();
+               while(p) {
+                       Paragraph::inset_iterator it =
+                               p->inset_iterator_begin();
+                       Paragraph::inset_iterator const end =
+                               p->inset_iterator_end();
+                       for (; it != end; ++it) {
+                               if ((*it) == inset) {
+                                       getLyXText(bv)->setCursorIntern(bv, p, it.getPos());
+                                       lockInset(bv, inset);
+                                       return true;
+                               }
+                               if ((*it)->getInsetFromID(id)) {
+                                       lockInset(bv, static_cast<UpdatableInset *>(*it));
+                                       return the_locking_inset->lockInsetInInset(bv, inset);
+                               }
+                       }
+                       p = p->next();
+               }
+               return false;
+       }
        if (inset == cpar(bv)->getInset(cpos(bv))) {
                lyxerr[Debug::INSETS] << "OK" << endl;
-               the_locking_inset = inset;
-               inset_x = cx(bv) - top_x + drawTextXOffset;
-               inset_y = cy(bv) + drawTextYOffset;
-               inset_pos = cpos(bv);
-               inset_par = cpar(bv);
-               inset_boundary = cboundary(bv);
-               updateLocal(bv, CURSOR, false);
+               lockInset(bv, inset);
                return true;
        } else if (the_locking_inset && (the_locking_inset == inset)) {
                if (cpar(bv) == inset_par && cpos(bv) == inset_pos) {
@@ -2388,19 +2416,11 @@ Paragraph * InsetText::paragraph() const
 
 void InsetText::paragraph(Paragraph * p)
 {
-       // first we have to delete the old contents otherwise we'll have a
-       // memory leak! But there check that we don't delete the paragraphs
-       // the new par is refering to (could happen in LyXText::EmptyParagrapM...)
-       // well don't do deletes at all if we come from there. Really stupid
-       // thing! (Jug 20011205)
-       if (par->next() != p) {
-               the_locking_inset = 0;
-               while (par && par != p) {
-                       Paragraph * tmp = par->next();
-                       delete par;
-                       par = tmp;
-               }
-       }
+       // GENERAL COMMENT: We don't have to free the old paragraphs as the
+       // caller of this function has to take care of it. This IS important
+       // as we could have to insert a paragraph before this one and just
+       // link the actual to a new ones next and set it with this function
+       // and are done!
        par = p;
        // set ourself as owner for all the paragraphs inserted!
        Paragraph * np = par;
index 9f862e4c0409372ffb3db5254860792c2b2bca12..5ffc127287731675f3d9041ad0e19a4d9726b309 100644 (file)
@@ -250,6 +250,8 @@ protected:
        ///
        void updateLocal(BufferView *, int what, bool mark_dirty) const;
        ///
+       void lockInset(BufferView *, UpdatableInset *);
+       ///
        mutable int drawTextXOffset;
        ///
        mutable int drawTextYOffset;
index be9d47813609ac85993cc0f393f4a33b1947c81f..8253912947af2f37060692733803c597a3da0b41 100644 (file)
@@ -813,50 +813,10 @@ string const LyXFunc::dispatch(int ac,
                        }
                        // Undo/Redo is a bit tricky for insets.
                        if (action == LFUN_UNDO) {
-#ifdef RETHINK_THIS_FOR_NOW_WE_LEAVE_ALL_UNLOCKED
-                               int slx;
-                               int sly;
-                               UpdatableInset * inset = 
-                                       owner->view()->theLockingInset()->getLockingInset();
-                               int inset_id = inset->id();
-                               inset->getCursorPos(owner->view(), slx, sly);
-                               owner->view()->unlockInset(inset);
-#else
-                               owner->view()->unlockInset(owner->view()->theLockingInset());
-#endif
                                owner->view()->menuUndo();
-#ifdef RETHINK_THIS_FOR_NOW_WE_LEAVE_ALL_UNLOCKED
-#if 0
-                               if (TEXT()->cursor.par()->
-                                   isInset(TEXT()->cursor.pos())) {
-                                       inset = static_cast<UpdatableInset*>(
-                                               TEXT()->cursor.par()->
-                                               getInset(TEXT()->
-                                                        cursor.pos()));
-                               } else {
-                                       inset = 0;
-                               }
-#else
-                               inset = static_cast<UpdatableInset *>(owner->view()->buffer()->getInsetFromID(inset_id));
-#endif
-                               if (inset)
-                                       inset->edit(owner->view(),slx,sly,0);
-#endif
                                return string();
                        } else if (action == LFUN_REDO) {
-                               int slx;
-                               int sly;
-                               UpdatableInset * inset = owner->view()->
-                                       theLockingInset();
-                               inset->getCursorPos(owner->view(), slx, sly);
-                               owner->view()->unlockInset(inset);
                                owner->view()->menuRedo();
-                               inset = static_cast<UpdatableInset*>(
-                                       TEXT()->cursor.par()->
-                                       getInset(TEXT()->
-                                                cursor.pos()));
-                               if (inset)
-                                       inset->edit(owner->view(),slx,sly,0); 
                                return string();
                        } else if (((result=owner->view()->theLockingInset()->
                                     localDispatch(owner->view(), action, argument)) ==
index 3207fcd63d7e6120f2cc814da22de5402860c87a..e9cca2e3a463784721779308542890fbe4ccf2c5 100644 (file)
@@ -862,8 +862,9 @@ void LyXText::redoParagraphs(BufferView * bview, LyXCursor const & cur,
 
        if (!tmprow->previous()) {
                // a trick/hack for UNDO
-               // Can somebody please tell me _why_ this solves
-               // anything. (Lgb)
+               // This is needed because in an UNDO/REDO we could have changed
+               // the firstParagrah() so the paragraph inside the row is NOT
+               // my really first par anymore. Got it Lars ;) (Jug 20011206)
                first_phys_par = firstParagraph();
        } else {
                first_phys_par = tmprow->par();
@@ -886,7 +887,7 @@ void LyXText::redoParagraphs(BufferView * bview, LyXCursor const & cur,
                tmppar = tmprow->next()->par();
        else
                tmppar = 0;
-       while (tmppar != endpar) {
+       while (tmprow->next() && tmppar != endpar) {
                removeRow(tmprow->next());
                if (tmprow->next()) {
                        tmppar = tmprow->next()->par();
@@ -2185,8 +2186,7 @@ void LyXText::setCursor(BufferView *bview, LyXCursor & cur, Paragraph * par,
 
 
 void LyXText::setCursorIntern(BufferView * bview, Paragraph * par,
-                             pos_type pos,
-                             bool setfont, bool boundary) const
+                              pos_type pos, bool setfont, bool boundary) const
 {
        InsetText * it = static_cast<InsetText *>(par->inInset());
        if (it) {
@@ -2205,8 +2205,7 @@ void LyXText::setCursorIntern(BufferView * bview, Paragraph * par,
                        // I moved the lyxerr stuff in here so we can see if
                        // this is actually really needed and where!
                        // (Jug)
-                       it->getLyXText(bview)->setCursorIntern(bview, par, pos, setfont,
-                                                              boundary);
+                       // it->getLyXText(bview)->setCursorIntern(bview, par, pos, setfont, boundary);
                        return;
                }
        }
index dd064886687e56994423e06da8290ace1d35d978..d8b76866fc884b1fd22e3413474c69227eb7e84d 100644 (file)
@@ -36,16 +36,25 @@ bool textUndo(BufferView * bv)
                finishUndo();
                if (!undo_frozen) {
                        Paragraph * first = bv->buffer()->getParFromID(undo->number_of_before_par);
-                       if (!first)
+                       if (first && first->next())
+                               first = first->next();
+                       else if (!first)
                                first = firstUndoParagraph(bv, undo->number_of_inset_id);
                        if (first) {
                                bv->buffer()->redostack.push(
                                        createUndo(bv, undo->kind, first,
-                                                  bv->buffer()->getParFromID(undo->number_of_behind_par)));
+                                                  bv->buffer()->getParFromID(undo->number_of_behind_par)));
                        }
                }
        }
-       return textHandleUndo(bv, undo);
+       // now we can unlock the inset for saftey because the inset pointer could
+       // be changed during the undo-function. Anyway if needed we have to lock
+       // the right inset/position if this is requested.
+       freezeUndo();
+       bv->unlockInset(bv->theLockingInset());
+       bool ret = textHandleUndo(bv, undo);
+       unFreezeUndo();
+       return ret;
 }
 
 
@@ -58,7 +67,9 @@ bool textRedo(BufferView * bv)
                finishUndo();
                if (!undo_frozen) {
                        Paragraph * first = bv->buffer()->getParFromID(undo->number_of_before_par);
-                       if (!first)
+                       if (first && first->next())
+                               first = first->next();
+                       else if (!first)
                                first = firstUndoParagraph(bv, undo->number_of_inset_id);
                        if (first) {
                                bv->buffer()->undostack.push(
@@ -67,7 +78,14 @@ bool textRedo(BufferView * bv)
                        }
                }
        }
-       return textHandleUndo(bv, undo);
+       // now we can unlock the inset for saftey because the inset pointer could
+       // be changed during the undo-function. Anyway if needed we have to lock
+       // the right inset/position if this is requested.
+       freezeUndo();
+       bv->unlockInset(bv->theLockingInset());
+       bool ret = textHandleUndo(bv, undo);
+       unFreezeUndo();
+       return ret;
 }
 
 
@@ -82,7 +100,6 @@ bool textHandleUndo(BufferView * bv, Undo * undo)
                        bv->buffer()->getParFromID(undo->number_of_behind_par); 
                Paragraph * tmppar;
                Paragraph * tmppar2;
-               Paragraph * endpar;
                Paragraph * tmppar5;
 
                // if there's no before take the beginning
@@ -159,38 +176,51 @@ bool textHandleUndo(BufferView * bv, Undo * undo)
     
                // Set the cursor for redoing
                if (before) {
-                       bv->text->setCursorIntern(bv, before, 0);
+                       Inset * it = before->inInset();
+                       if (it)
+                               it->getLyXText(bv)->setCursorIntern(bv, before, 0);
+                       else
+                               bv->text->setCursorIntern(bv, before, 0);
                }
 
+               Paragraph * endpar = 0;
                // calculate the endpar for redoing the paragraphs.
-               if (behind) {
-                               endpar = behind->next();
-               } else
-                       endpar = behind;
+               if (behind)
+                       endpar = behind->next();
     
                tmppar = bv->buffer()->getParFromID(undo->number_of_cursor_par);
                UpdatableInset* it = static_cast<UpdatableInset*>(tmppar3->inInset());
                if (it) {
                        it->getLyXText(bv)->redoParagraphs(bv, it->getLyXText(bv)->cursor,
                                                           endpar);
+                       LyXFont font;
+                       it->update(bv, font, false);
+                       // we now would have to rebreak the whole paragraph the undo-par
+                       // was in. How we do it here is not really true. We would have to
+                       // save this information in the undo-struct and then we could do
+                       // the right rebreak. Here we only handle the case where this
+                       // was in the actual paragraph, which not always is true.
+                       bv->text->redoParagraphs(bv, bv->text->cursor,
+                                                                        bv->text->cursor.par());
                        if (tmppar){
+                               it = static_cast<UpdatableInset*>(tmppar->inInset());
+                               it->edit(bv);
                                it->getLyXText(bv)->setCursorIntern(bv, tmppar, undo->cursor_pos);
                                it->getLyXText(bv)->updateCounters(bv, it->getLyXText(bv)->cursor.row());
                        }
-                       LyXFont font;
-                       it->update(bv, font, false);
-#ifdef THIS_DOES_NOT_WORK
-                       // we need this anyway as also if the undo was
-                       // inside an inset we have to redo the
-                       // paragraph breaking
-                       bv->text->redoParagraphs(bv, bv->text->cursor,
-                                                bv->text->cursor.par());
-#endif
+                       bv->text->setCursorIntern(bv, bv->text->cursor.par(),
+                                                                         bv->text->cursor.pos());
                } else {
                        bv->text->redoParagraphs(bv, bv->text->cursor, endpar);
                        if (tmppar) {
-                               bv->text->setCursorIntern(bv, tmppar, undo->cursor_pos);
-                               bv->text->updateCounters(bv, bv->text->cursor.row());
+                               LyXText * t;
+                               Inset * it = tmppar->inInset();
+                               if (it)
+                                       t = it->getLyXText(bv);
+                               else
+                                       t = bv->text;
+                               t->setCursorIntern(bv, tmppar, undo->cursor_pos);
+                               t->updateCounters(bv, t->cursor.row());
                        }
                }
                result = true;
@@ -226,9 +256,10 @@ void unFreezeUndo()
 void setUndo(BufferView * bv, Undo::undo_kind kind,
              Paragraph const * first, Paragraph const * behind)
 {
-       if (!undo_frozen)
+       if (!undo_frozen) {
                bv->buffer()->undostack.push(createUndo(bv, kind, first, behind));
-       bv->buffer()->redostack.clear();
+               bv->buffer()->redostack.clear();
+       }
 }
 
 
@@ -287,10 +318,10 @@ Undo * createUndo(BufferView * bv, Undo::undo_kind kind,
        }
        if (start && end && (start != end->next()) &&
            ((before_number != behind_number) ||
-                ((before_number < 0) && (behind_number < 0)))) {
+                ((before_number < 0) && (behind_number < 0))))
+       {
                Paragraph * tmppar = start;
                Paragraph * tmppar2 = new Paragraph(*tmppar, true);
-               tmppar2->id(tmppar->id());
                
                // a memory optimization: Just store the layout information
                // when only edit
@@ -302,8 +333,7 @@ Undo * createUndo(BufferView * bv, Undo::undo_kind kind,
   
                while (tmppar != end && tmppar->next()) {
                        tmppar = tmppar->next();
-                       tmppar2->next(new Paragraph(*tmppar, false));
-                       tmppar2->next()->id(tmppar->id());
+                       tmppar2->next(new Paragraph(*tmppar, true));
                        // a memory optimization: Just store the layout
                        // information when only edit
                        if (kind == Undo::EDIT) {
@@ -330,9 +360,8 @@ Undo * createUndo(BufferView * bv, Undo::undo_kind kind,
 
 void setCursorParUndo(BufferView * bv)
 {
-       setUndo(bv, Undo::FINISH,
-               bv->text->cursor.par(),
-                       bv->text->cursor.par()->next());
+       setUndo(bv, Undo::FINISH, bv->text->cursor.par(),
+               bv->text->cursor.par()->next());
 }
 
 
@@ -340,7 +369,7 @@ Paragraph * firstUndoParagraph(BufferView * bv, int inset_id)
 {
        Inset * inset = bv->buffer()->getInsetFromID(inset_id);
        if (inset) {
-               Paragraph * result = inset->firstParagraph();
+               Paragraph * result = inset->getFirstParagraph(0);
                if (result)
                        return result;
        }