[Libreoffice-commits] core.git: include/svl svl/source sw/inc sw/source

Oliver-Rainer Wittmann orw at apache.org
Wed Jun 26 08:22:59 PDT 2013


 include/svl/undo.hxx               |    2 +
 svl/source/undo/undo.cxx           |   21 ++++++++++++
 sw/inc/IDocumentUndoRedo.hxx       |    6 ++-
 sw/source/core/edit/edundo.cxx     |   15 +++++++--
 sw/source/core/inc/UndoManager.hxx |    6 +--
 sw/source/core/layout/trvlfrm.cxx  |   61 +++++++++++++++++++------------------
 sw/source/core/undo/docundo.cxx    |   21 ++++++++++--
 sw/source/ui/shells/textsh1.cxx    |    5 +++
 8 files changed, 95 insertions(+), 42 deletions(-)

New commits:
commit 25d84e2826de81d1e7a55ff0fdab7845b7a78e74
Author: Oliver-Rainer Wittmann <orw at apache.org>
Date:   Wed Jun 26 12:15:55 2013 +0000

    Resolves: #i121751# restore cursor/selection on Undo/Redo language...
    
    change for all text
    
    - group intrinsic actions of language change for all text into one Undo action
    - secure <SwRootFrm::CalcRects(..)> - catch NULL pointer
    - correct <CursorGuard> - really restore the cursor
    
    (cherry picked from commit 4207db473430e02a65a5f4d57db6e46a8db29a19)
    
    Conflicts:
    	svl/inc/svl/undo.hxx
    	svl/source/undo/undo.cxx
    	sw/inc/IDocumentUndoRedo.hxx
    	sw/source/core/edit/edundo.cxx
    	sw/source/core/inc/UndoManager.hxx
    	sw/source/core/layout/trvlfrm.cxx
    	sw/source/core/undo/docundo.cxx
    
    Change-Id: I972988bbc21a519e0956ff196aa93a46287b9a2e

diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx
index c1054a6..3e59baa 100644
--- a/include/svl/undo.hxx
+++ b/include/svl/undo.hxx
@@ -240,6 +240,7 @@ namespace svl
 
         virtual size_t          GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
         virtual OUString        GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
+        virtual SfxUndoAction*  GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
 
         virtual sal_Bool        Undo() = 0;
         virtual sal_Bool        Redo() = 0;
@@ -358,6 +359,7 @@ public:
     virtual SfxUndoAction*  GetUndoAction( size_t nNo=0 ) const;
     virtual size_t          GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const;
     virtual OUString        GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
+    virtual SfxUndoAction*  GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
     virtual sal_Bool        Undo();
     virtual sal_Bool        Redo();
     virtual void            Clear();
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index dac5dc3..d27de22 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -830,11 +830,30 @@ size_t SfxUndoManager::ImplGetRedoActionCount_Lock( bool const i_currentLevel )
 
 //------------------------------------------------------------------------
 
+SfxUndoAction* SfxUndoManager::GetRedoAction( size_t nNo, bool const i_currentLevel ) const
+{
+    UndoManagerGuard aGuard( *m_pData );
+
+    const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
+    if ( (pUndoArray->nCurUndoAction + nNo) > pUndoArray->aUndoActions.size() )
+    {
+        return NULL;
+    }
+    return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction;
+}
+
+//------------------------------------------------------------------------
+
 OUString SfxUndoManager::GetRedoActionComment( size_t nNo, bool const i_currentLevel ) const
 {
+    String sComment;
     UndoManagerGuard aGuard( *m_pData );
     const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
-    return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction->GetComment();
+    if ( (pUndoArray->nCurUndoAction + nNo) < pUndoArray->aUndoActions.size() )
+    {
+        sComment = pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction->GetComment();
+    }
+    return sComment;
 }
 
 //------------------------------------------------------------------------
diff --git a/sw/inc/IDocumentUndoRedo.hxx b/sw/inc/IDocumentUndoRedo.hxx
index 26e76f0..a50a4f0 100644
--- a/sw/inc/IDocumentUndoRedo.hxx
+++ b/sw/inc/IDocumentUndoRedo.hxx
@@ -156,11 +156,13 @@ public:
     */
     virtual sal_Bool Redo() = 0;
 
-    /** Get comment of first Redo action.
+    /** Get Id and comment of first Redo action.
         @param o_pStr       if not 0, receives comment of first Redo action.
+        @param o_pId        if not 0, receives Id of first Redo action.
         @return     true if there is a Redo action, false if none
     */
-    virtual bool GetFirstRedoInfo(OUString *const o_pStr) const = 0;
+    virtual bool GetFirstRedoInfo(OUString *const o_pStr,
+                                  SwUndoId *const o_pId = 0) const = 0;
 
     /** Get comments of Redo actions.
         @return     comments of all top-level Redo actions.
diff --git a/sw/source/core/edit/edundo.cxx b/sw/source/core/edit/edundo.cxx
index bd27446..4fa0cee 100644
--- a/sw/source/core/edit/edundo.cxx
+++ b/sw/source/core/edit/edundo.cxx
@@ -111,9 +111,11 @@ bool SwEditShell::Undo(sal_uInt16 const nCount)
         // Keep Cursor - so that we're able to set it at
         // the same position for autoformat or autocorrection
         SwUndoId nLastUndoId(UNDO_EMPTY);
-        GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId);
-        bool bRestoreCrsr = 1 == nCount && (UNDO_AUTOFORMAT == nLastUndoId ||
-                                           UNDO_AUTOCORRECT == nLastUndoId );
+        GetLastUndoInfo(0, & nLastUndoId);
+        const bool bRestoreCrsr = nCount == 1
+                                  && ( UNDO_AUTOFORMAT == nLastUndoId
+                                       || UNDO_AUTOCORRECT == nLastUndoId
+                                       || UNDO_SETDEFTATTR == nLastUndoId );
         Push();
 
         // Destroy stored TableBoxPtr. A dection is only permitted for the new "Box"!
@@ -168,6 +170,11 @@ bool SwEditShell::Redo(sal_uInt16 const nCount)
         SetMark();          // Bound1 and Bound2 in the same Node
         ClearMark();
 
+        SwUndoId nFirstRedoId(UNDO_EMPTY);
+        GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(0, & nFirstRedoId);
+        const bool bRestoreCrsr = nCount == 1 && UNDO_SETDEFTATTR == nFirstRedoId;
+        Push();
+
         // Destroy stored TableBoxPtr. A dection is only permitted for the new "Box"!
         ClearTblBoxCntnt();
 
@@ -185,6 +192,8 @@ bool SwEditShell::Redo(sal_uInt16 const nCount)
                     .getStr());
         }
 
+        Pop( !bRestoreCrsr );
+
         GetDoc()->SetRedlineMode( eOld );
         GetDoc()->CompressRedlines();
 
diff --git a/sw/source/core/inc/UndoManager.hxx b/sw/source/core/inc/UndoManager.hxx
index 0db1826..3b7d113 100644
--- a/sw/source/core/inc/UndoManager.hxx
+++ b/sw/source/core/inc/UndoManager.hxx
@@ -59,10 +59,10 @@ public:
                 SwRewriter const*const pRewriter);
     virtual void DelAllUndoObj();
     virtual bool GetLastUndoInfo(OUString *const o_pStr,
-                SwUndoId *const o_pId) const;
+                                 SwUndoId *const o_pId) const;
     virtual SwUndoComments_t GetUndoComments() const;
-
-    virtual bool GetFirstRedoInfo(OUString *const o_pStr) const;
+    virtual bool GetFirstRedoInfo(OUString *const o_pStr,
+                                  SwUndoId *const o_pId = 0) const;
     virtual SwUndoComments_t GetRedoComments() const;
     virtual bool Repeat(::sw::RepeatContext & rContext,
                 sal_uInt16 const nRepeatCnt);
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 1a2bb5c..e431850 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -2097,8 +2097,7 @@ inline void Sub( SwRegionRects& rRegion, const SwRect& rRect )
 void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
 {
     SwPosition *pStartPos = rCrsr.Start(),
-               *pEndPos   = rCrsr.GetPoint() == pStartPos ?
-                            rCrsr.GetMark() : rCrsr.GetPoint();
+               *pEndPos   = rCrsr.GetPoint() == pStartPos ? rCrsr.GetMark() : rCrsr.GetPoint();
 
     ViewShell *pSh = GetCurrShell();
 
@@ -2134,8 +2133,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
         OSL_ENSURE( pObj, "No Start Object." );
         if (pObj) aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) );
         const SwAnchoredObject* pObj2 = pEndFrm->FindFlyFrm();
-        OSL_ENSURE( pObj2, "No Start Object." );
-        if (pObj2) aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) );
+        OSL_ENSURE( pObj2, "SwRootFrm::CalcFrmRects(..) - FlyFrame missing - looks like an invalid selection" );
+        if ( pObj2 != NULL && pObj2 != pObj )
+        {
+            aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) );
+        }
     }
 
     //Fall 4: Tabellenselection
@@ -2170,7 +2172,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                 break;
 
             OSL_ENSURE( pEndLFrm->GetType() == pSttLFrm->GetType(),
-                    "Selection ueber unterschiedliche Inhalte" );
+                "Selection ueber unterschiedliche Inhalte" );
             switch( pSttLFrm->GetType() )
             {
             case FRM_HEADER:
@@ -2193,11 +2195,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                 {
                     const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm;
                     if( ( pTabFrm->GetFollow() ||
-                          ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
+                        ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
                         pTabFrm->GetTable()->GetRowsToRepeat() > 0 &&
                         pTabFrm->GetLower() != ((SwTabFrm*)pEndLFrm)->GetLower() &&
                         ( lcl_IsInRepeatedHeadline( pStartFrm ) ||
-                          lcl_IsInRepeatedHeadline( pEndFrm ) ) )
+                        lcl_IsInRepeatedHeadline( pEndFrm ) ) )
                     {
                         // End- auf den Start-CntntFrame setzen
                         if( pStartPos == rCrsr.GetPoint() )
@@ -2227,10 +2229,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
 
         SwRect aStFrm ( pStartFrm->UnionFrm( sal_True ) );
         aStFrm.Intersection( pStartFrm->PaintArea() );
-        SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm :
-                                               pEndFrm->UnionFrm( sal_True ) );
+        SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm : pEndFrm->UnionFrm( sal_True ) );
         if( pStartFrm != pEndFrm )
+        {
             aEndFrm.Intersection( pEndFrm->PaintArea() );
+        }
         SWRECTFN( pStartFrm )
         const sal_Bool bR2L = pStartFrm->IsRightToLeft();
         const sal_Bool bEndR2L = pEndFrm->IsRightToLeft();
@@ -2251,8 +2254,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
 
                 // BiDi-Portions are swimming against the current.
                 const sal_Bool bPorR2L = ( MT_BIDI == pSt2Pos->nMultiType ) ?
-                                           ! bR2L :
-                                             bR2L;
+                    ! bR2L :
+                bR2L;
 
                 if( MT_BIDI == pSt2Pos->nMultiType &&
                     (pSt2Pos->aPortion2.*fnRect->fnGetWidth)() )
@@ -2502,9 +2505,9 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                 {
                     OutputDevice* pOut = pSh->GetOut();
                     long nCrsrWidth = pOut->GetSettings().GetStyleSettings().
-                                        GetCursorSize();
+                        GetCursorSize();
                     (aTmp.*fnRect->fnSetWidth)( pOut->PixelToLogic(
-                                              Size( nCrsrWidth, 0 ) ).Width() );
+                        Size( nCrsrWidth, 0 ) ).Width() );
                 }
                 aTmp.Intersection( aStFrm );
                 Sub( aRegion, aTmp );
@@ -2521,9 +2524,9 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                 else
                 {
                     lLeft = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
-                            (pStartFrm->Prt().*fnRect->fnGetLeft)();
+                        (pStartFrm->Prt().*fnRect->fnGetLeft)();
                     lRight = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
-                             (pStartFrm->Prt().*fnRect->fnGetRight)();
+                        (pStartFrm->Prt().*fnRect->fnGetRight)();
                 }
                 if( lLeft < (aStFrm.*fnRect->fnGetLeft)() )
                     lLeft = (aStFrm.*fnRect->fnGetLeft)();
@@ -2579,15 +2582,12 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
             //Now the frames between, if there are any
             bool const bBody = pStartFrm->IsInDocBody();
             const SwTableBox* pCellBox = pStartFrm->GetUpper()->IsCellFrm() ?
-                                         ((SwCellFrm*)pStartFrm->GetUpper())->GetTabBox() : 0;
+                ((SwCellFrm*)pStartFrm->GetUpper())->GetTabBox() : 0;
             const SwCntntFrm *pCntnt = pStartFrm->GetNextCntntFrm();
             SwRect aPrvRect;
 
-            // #123908# - introduce robust code
-            // The stacktrace issue reveals that <pCntnt> could be NULL.
-            // One root cause found by AMA - see #130650#
             OSL_ENSURE( pCntnt,
-                    "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
+                "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
             while ( pCntnt && pCntnt != pEndFrm )
             {
                 if ( pCntnt->IsInFly() )
@@ -2600,7 +2600,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                 // If pStartFrm is inside a SwCellFrm, consider only frames which are inside the
                 // same cell frame (or its follow cell)
                 const SwTableBox* pTmpCellBox = pCntnt->GetUpper()->IsCellFrm() ?
-                                                ((SwCellFrm*)pCntnt->GetUpper())->GetTabBox() : 0;
+                    ((SwCellFrm*)pCntnt->GetUpper())->GetTabBox() : 0;
                 if ( bBody == pCntnt->IsInDocBody() &&
                     ( !pCellBox || pCellBox == pTmpCellBox ) )
                 {
@@ -2625,9 +2625,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                     }
                 }
                 pCntnt = pCntnt->GetNextCntntFrm();
-                // #123908#
                 OSL_ENSURE( pCntnt,
-                        "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
+                    "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
             }
             if ( aPrvRect.HasArea() )
                 Sub( aRegion, aPrvRect );
@@ -2637,7 +2636,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
             bRev = pEndFrm->IsReverse();
             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
             fnRect = bVert ? ( bRev ? fnRectVL2R : ( pEndFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) ) :
-                             ( bRev ? fnRectB2T : fnRectHori );
+                ( bRev ? fnRectB2T : fnRectHori );
             nTmpTwips = (aEndRect.*fnRect->fnGetTop)();
             if( (aEndFrm.*fnRect->fnGetTop)() != nTmpTwips )
             {
@@ -2653,7 +2652,6 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
             Sub( aRegion, aSubRect );
         }
 
-//      aRegion.Compress( sal_False );
         aRegion.Invert();
         delete pSt2Pos;
         delete pEnd2Pos;
@@ -2681,8 +2679,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                 const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj();
                 const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
                 if ( !pFly->IsAnLower( pStartFrm ) &&
-                     (rSur.GetSurround() != SURROUND_THROUGHT &&
-                      !rSur.IsContour()) )
+                    (rSur.GetSurround() != SURROUND_THROUGHT &&
+                    !rSur.IsContour()) )
                 {
                     if ( aSortObjs.Contains( *pAnchoredObj ) )
                         continue;
@@ -2692,13 +2690,18 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
                     for ( sal_uInt16 k = 0; bSub && k < aSortObjs.Count(); ++k )
                     {
                         OSL_ENSURE( aSortObjs[k]->ISA(SwFlyFrm),
-                                "<SwRootFrm::CalcFrmRects(..)> - object in <aSortObjs> of unexcepted type" );
+                            "<SwRootFrm::CalcFrmRects(..)> - object in <aSortObjs> of unexcepted type" );
                         const SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(aSortObjs[k]);
                         do
-                        {   if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
+                        {
+                            if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
+                            {
                                 bSub = sal_False;
+                            }
                             else
+                            {
                                 pTmp = pTmp->GetAnchorFrm()->FindFlyFrm();
+                            }
                         } while ( bSub && pTmp );
                     }
                     if ( bSub )
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
index 79ad862..fff78e4d 100644
--- a/sw/source/core/undo/docundo.cxx
+++ b/sw/source/core/undo/docundo.cxx
@@ -332,16 +332,29 @@ SwUndoComments_t UndoManager::GetUndoComments() const
 
 
 /**************** REDO ******************/
-bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr) const
+
+bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr,
+                                   SwUndoId *const o_pId) const
 {
     if (!SdrUndoManager::GetRedoActionCount(CurrentLevel))
     {
         return false;
     }
 
+    SfxUndoAction *const pAction( SdrUndoManager::GetRedoAction(0, CurrentLevel) );
+    if ( pAction == NULL )
+    {
+        return false;
+    }
+
     if (o_pStr)
     {
-        *o_pStr = SdrUndoManager::GetRedoActionComment(0, CurrentLevel);
+        *o_pStr = pAction->GetComment();
+    }
+    if (o_pId)
+    {
+        sal_uInt16 const nId(pAction->GetId());
+        *o_pId = static_cast<SwUndoId>(nId);
     }
 
     return true;
@@ -443,7 +456,7 @@ public:
     {
         if (m_bSaveCursor)
         {
-            m_rShell.Pop();
+            m_rShell.Pop( sal_False );
         }
     }
 private:
@@ -468,7 +481,7 @@ bool UndoManager::impl_DoUndoRedo(UndoOrRedo_t const undoOrRedo)
     // in case the model has controllers locked, the Undo should not
     // change the view cursors!
     bool const bSaveCursors(pEditShell->CursorsLocked());
-    CursorGuard(*pEditShell, bSaveCursors);
+    CursorGuard aCursorGuard(*pEditShell, bSaveCursors);
     if (!bSaveCursors)
     {
         // (in case Undo was called via API) clear the cursors:
diff --git a/sw/source/ui/shells/textsh1.cxx b/sw/source/ui/shells/textsh1.cxx
index 340e938..2ac65fd 100644
--- a/sw/source/ui/shells/textsh1.cxx
+++ b/sw/source/ui/shells/textsh1.cxx
@@ -328,6 +328,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
                 rWrtSh.StartAction();
                 // prevent view from jumping because of (temporary) selection changes
                 rWrtSh.LockView( sal_True );
+
                 // save selection for later restoration
                 rWrtSh.Push();
 
@@ -377,12 +378,16 @@ void SwTextShell::Execute(SfxRequest &rReq)
                         rWrtSh.SelAll();
                         rWrtSh.ExtendedSelectAll();
                     }
+
+                    rWrtSh.StartUndo( ( !bForParagraph && !bForSelection ) ? UNDO_SETDEFTATTR : UNDO_EMPTY );
                     if (aNewLangTxt == aStrNone)
                         SwLangHelper::SetLanguage_None( rWrtSh, bForSelection, aCoreSet );
                     else if (aNewLangTxt == aStrResetLangs)
                         SwLangHelper::ResetLanguages( rWrtSh, bForSelection );
                     else
                         SwLangHelper::SetLanguage( rWrtSh, aNewLangTxt, bForSelection, aCoreSet );
+                    rWrtSh.EndUndo();
+
                 }
 
                 // restore selection...


More information about the Libreoffice-commits mailing list