[Libreoffice-commits] core.git: editeng/source include/svl sc/source sd/source svl/source

Armin Le Grand alg at apache.org
Mon Jun 24 08:08:38 PDT 2013


 editeng/source/editeng/impedit2.cxx                     |   44 +++++++++---
 include/svl/undo.hxx                                    |   13 ++-
 sc/source/ui/inc/undobase.hxx                           |    4 -
 sc/source/ui/inc/undodraw.hxx                           |    4 -
 sc/source/ui/undo/undobase.cxx                          |   12 ---
 sc/source/ui/undo/undodraw.cxx                          |   12 ---
 sd/source/ui/slidesorter/controller/SlsPageSelector.cxx |    6 +
 svl/source/undo/undo.cxx                                |   57 +++++++---------
 8 files changed, 88 insertions(+), 64 deletions(-)

New commits:
commit 91b8728108193706e142c25903c0dcd4ea8b0b21
Author: Armin Le Grand <alg at apache.org>
Date:   Sun Jun 23 11:25:32 2013 +0000

    Resolves: #i120020# corrected paragraph merge...
    
    corresponding undo and ownership of linked undo actions
    
    (cherry picked from commit e58fe7afee5163833479b76a474416a77d95f075)
    
    Conflicts:
    	editeng/source/editeng/impedit2.cxx
    	sc/source/ui/undo/undobase.cxx
    	sc/source/ui/undo/undodraw.cxx
    	svl/inc/svl/undo.hxx
    
    Change-Id: I6672990558a496dfc692554437897d013e258f40

diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 4bc6d70..d6e1de5 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -2185,6 +2185,16 @@ EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* pLeft, ContentNode* pR
     OSL_ENSURE( aEditDoc.GetPos( pLeft ) != EE_PARA_NOT_FOUND, "Inserted node not found (1)" );
     OSL_ENSURE( aEditDoc.GetPos( pRight ) != EE_PARA_NOT_FOUND, "Inserted node not found (2)" );
 
+    // #i120020# it is possible that left and right are *not* in the desired order (left/right)
+    // so correct it. This correction is needed, else an invalid SfxLinkUndoAction will be
+    // created from ConnectParagraphs below. Assert this situation, it should be corrected by the
+    // caller.
+    if(aEditDoc.GetPos( pLeft ) > aEditDoc.GetPos( pRight ))
+    {
+        OSL_ENSURE(false, "ImpConnectParagraphs wit wrong order of pLeft/pRight nodes (!)");
+        std::swap(pLeft, pRight);
+    }
+
     sal_Int32 nParagraphTobeDeleted = aEditDoc.GetPos( pRight );
     DeletedNodeInfo* pInf = new DeletedNodeInfo( (sal_uIntPtr)pRight, nParagraphTobeDeleted );
     aDeletedNodes.push_back(pInf);
@@ -2301,18 +2311,34 @@ EditPaM ImpEditEngine::DeleteLeftOrRight( const EditSelection& rSel, sal_uInt8 n
         else if ( nDelMode == DELMODE_RESTOFWORD )
         {
             aDelEnd = EndOfWord( aCurPos );
+
             if (aDelEnd.GetIndex() == aCurPos.GetIndex())
             {
-                xub_StrLen nLen = aCurPos.GetNode()->Len();
-                // end of para?
-                if (aDelEnd.GetIndex() == nLen)
-                    aDelEnd = WordLeft( aCurPos );
-                else // there's still sth to delete on the right
+                const xub_StrLen nLen(aCurPos.GetNode()->Len());
+
+                // #i120020# when 0 == nLen, aDelStart needs to be adapted, not
+                // aDelEnd. This would (and did) lead to a wrong order in the
+                // ImpConnectParagraphs call later.
+                if(nLen)
+                {
+                    // end of para?
+                    if (aDelEnd.GetIndex() == nLen)
+                    {
+                        aDelEnd = WordLeft( aCurPos );
+                    }
+                    else // there's still sth to delete on the right
+                    {
+                        aDelEnd = EndOfWord( WordRight( aCurPos ) );
+                        // if there'n no next word...
+                        if (aDelEnd.GetIndex() == nLen )
+                        {
+                            aDelEnd.SetIndex( nLen );
+                        }
+                    }
+                }
+                else
                 {
-                    aDelEnd = EndOfWord( WordRight( aCurPos ) );
-                    // if there'n no next word...
-                    if (aDelEnd.GetIndex() == nLen )
-                        aDelEnd.SetIndex( nLen );
+                    aDelStart = WordLeft(aCurPos);
                 }
             }
         }
diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx
index f36cd81..c1054a6 100644
--- a/include/svl/undo.hxx
+++ b/include/svl/undo.hxx
@@ -46,17 +46,20 @@ public:
 };
 
 //====================================================================
+class SfxLinkUndoAction;
 
 class SVL_DLLPUBLIC SfxUndoAction
 {
-    sal_Bool bLinked;
+private:
+    SfxLinkUndoAction*      mpSfxLinkUndoAction;
+
 public:
                             TYPEINFO();
                             SfxUndoAction();
     virtual                 ~SfxUndoAction();
 
-    virtual sal_Bool            IsLinked();
-    virtual void            SetLinked( sal_Bool bIsLinked = sal_True );
+    virtual void SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction);
+
     virtual void            Undo();
     virtual void            UndoWithContext( SfxUndoContext& i_context );
     virtual void            Redo();
@@ -446,6 +449,10 @@ class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction
 */
 
 {
+private:
+    friend class SfxUndoAction;
+    void LinkedSfxUndoActionDestructed(const SfxUndoAction& rCandidate);
+
 public:
                             TYPEINFO();
                             SfxLinkUndoAction(::svl::IUndoManager *pManager);
diff --git a/sc/source/ui/inc/undobase.hxx b/sc/source/ui/inc/undobase.hxx
index c6e6b95..6943408 100644
--- a/sc/source/ui/inc/undobase.hxx
+++ b/sc/source/ui/inc/undobase.hxx
@@ -175,8 +175,8 @@ public:
     SfxUndoAction*          GetWrappedUndo()        { return pWrappedUndo; }
     void                    ForgetWrappedUndo();
 
-    virtual sal_Bool            IsLinked();
-    virtual void            SetLinked( sal_Bool bIsLinked );
+    virtual void SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction);
+
     virtual void            Undo();
     virtual void            Redo();
     virtual void            Repeat(SfxRepeatTarget& rTarget);
diff --git a/sc/source/ui/inc/undodraw.hxx b/sc/source/ui/inc/undodraw.hxx
index 3db6dab..97c1c00 100644
--- a/sc/source/ui/inc/undodraw.hxx
+++ b/sc/source/ui/inc/undodraw.hxx
@@ -39,8 +39,8 @@ public:
     SfxUndoAction*          GetDrawUndo()       { return pDrawUndo; }
     void                    ForgetDrawUndo();
 
-    virtual sal_Bool            IsLinked();
-    virtual void            SetLinked( sal_Bool bIsLinked );
+    virtual void SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction);
+
     virtual void            Undo();
     virtual void            Redo();
     virtual void            Repeat(SfxRepeatTarget& rTarget);
diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx
index 299d1a7..4acff49 100644
--- a/sc/source/ui/undo/undobase.cxx
+++ b/sc/source/ui/undo/undobase.cxx
@@ -561,18 +561,12 @@ sal_uInt16 ScUndoWrapper::GetId() const
         return 0;
 }
 
-sal_Bool ScUndoWrapper::IsLinked()
+void ScUndoWrapper::SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction)
 {
     if (pWrappedUndo)
-        return pWrappedUndo->IsLinked();
+        pWrappedUndo->SetLinkToSfxLinkUndoAction(pSfxLinkUndoAction);
     else
-        return false;
-}
-
-void ScUndoWrapper::SetLinked( sal_Bool bIsLinked )
-{
-    if (pWrappedUndo)
-        pWrappedUndo->SetLinked(bIsLinked);
+        SetLinkToSfxLinkUndoAction(pSfxLinkUndoAction);
 }
 
 sal_Bool ScUndoWrapper::Merge( SfxUndoAction* pNextAction )
diff --git a/sc/source/ui/undo/undodraw.cxx b/sc/source/ui/undo/undodraw.cxx
index fc047c1..2f42a79 100644
--- a/sc/source/ui/undo/undodraw.cxx
+++ b/sc/source/ui/undo/undodraw.cxx
@@ -63,18 +63,12 @@ sal_uInt16 ScUndoDraw::GetId() const
         return 0;
 }
 
-sal_Bool ScUndoDraw::IsLinked()
+void ScUndoDraw::SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction)
 {
     if (pDrawUndo)
-        return pDrawUndo->IsLinked();
+        pDrawUndo->SetLinkToSfxLinkUndoAction(pSfxLinkUndoAction);
     else
-        return false;
-}
-
-void ScUndoDraw::SetLinked( sal_Bool bIsLinked )
-{
-    if (pDrawUndo)
-        pDrawUndo->SetLinked(bIsLinked);
+        SetLinkToSfxLinkUndoAction(pSfxLinkUndoAction);
 }
 
 sal_Bool  ScUndoDraw::Merge( SfxUndoAction* pNextAction )
diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
index 79663a8..4121add 100644
--- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
@@ -244,7 +244,11 @@ void PageSelector::CheckConsistency (void) const
     }
     if (nSelectionCount!=mnSelectedPageCount)
     {
-        assert(nSelectionCount==mnSelectedPageCount);
+        // #i120020# The former call to assert(..) internally calls
+        // SlideSorterModel::GetPageDescriptor which will crash in this situation
+        // (only in non-pro code). All what is wanted there is to assert it (the
+        // error is already detected), so do this directly.
+        OSL_ENSURE(false, "PageSelector: Consistency error (!)");
     }
 }
 
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index 72929b7..dac5dc3 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -57,16 +57,9 @@ SfxUndoContext::~SfxUndoContext()
 
 //------------------------------------------------------------------------
 
-sal_Bool SfxUndoAction::IsLinked()
+void SfxUndoAction::SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction)
 {
-    return bLinked;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::SetLinked( sal_Bool bIsLinked )
-{
-    bLinked = bIsLinked;
+    mpSfxLinkUndoAction = pSfxLinkUndoAction;
 }
 
 //------------------------------------------------------------------------
@@ -74,14 +67,19 @@ void SfxUndoAction::SetLinked( sal_Bool bIsLinked )
 SfxUndoAction::~SfxUndoAction()
 {
     DBG_DTOR(SfxUndoAction, 0);
-    DBG_ASSERT( !IsLinked(), "Gelinkte Action geloescht" );
+
+    if(mpSfxLinkUndoAction)
+    {
+        mpSfxLinkUndoAction->LinkedSfxUndoActionDestructed(*this);
+        mpSfxLinkUndoAction = 0;
+    }
 }
 
 
 SfxUndoAction::SfxUndoAction()
+:   mpSfxLinkUndoAction(0)
 {
     DBG_CTOR(SfxUndoAction, 0);
-    SetLinked( sal_False );
 }
 
 //------------------------------------------------------------------------
@@ -449,24 +447,18 @@ void SfxUndoManager::SetMaxUndoActionCount( size_t nMaxUndoActionCount )
         if ( nPos > m_pData->pActUndoArray->nCurUndoAction )
         {
             SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[nPos-1].pAction;
-            if ( !pAction->IsLinked() )
-            {
-                aGuard.markForDeletion( pAction );
-                m_pData->pActUndoArray->aUndoActions.Remove( nPos-1 );
-                --nNumToDelete;
-            }
+            aGuard.markForDeletion( pAction );
+            m_pData->pActUndoArray->aUndoActions.Remove( nPos-1 );
+            --nNumToDelete;
         }
 
         if ( nNumToDelete > 0 && m_pData->pActUndoArray->nCurUndoAction > 0 )
         {
             SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[0].pAction;
-            if ( !pAction->IsLinked() )
-            {
-                aGuard.markForDeletion( pAction );
-                m_pData->pActUndoArray->aUndoActions.Remove(0);
-                --m_pData->pActUndoArray->nCurUndoAction;
-                --nNumToDelete;
-            }
+            aGuard.markForDeletion( pAction );
+            m_pData->pActUndoArray->aUndoActions.Remove(0);
+            --m_pData->pActUndoArray->nCurUndoAction;
+            --nNumToDelete;
         }
 
         if ( nPos == m_pData->pActUndoArray->aUndoActions.size() )
@@ -638,9 +630,7 @@ bool SfxUndoManager::ImplAddUndoAction_NoNotify( SfxUndoAction *pAction, bool bT
     // respect max number
     if( m_pData->pActUndoArray == m_pData->pUndoArray )
     {
-        while( m_pData->pActUndoArray->aUndoActions.size() >=
-               m_pData->pActUndoArray->nMaxUndoActions &&
-               !m_pData->pActUndoArray->aUndoActions[0].pAction->IsLinked() )
+        while(m_pData->pActUndoArray->aUndoActions.size() >= m_pData->pActUndoArray->nMaxUndoActions)
         {
             i_guard.markForDeletion( m_pData->pActUndoArray->aUndoActions[0].pAction );
             m_pData->pActUndoArray->aUndoActions.Remove(0);
@@ -1399,7 +1389,7 @@ SfxLinkUndoAction::SfxLinkUndoAction(::svl::IUndoManager *pManager)
     {
         size_t nPos = pManager->GetUndoActionCount()-1;
         pAction = pUndoManagerImplementation->m_pData->pActUndoArray->aUndoActions[nPos].pAction;
-        pAction->SetLinked();
+        pAction->SetLinkToSfxLinkUndoAction(this);
     }
     else
         pAction = 0;
@@ -1464,9 +1454,18 @@ OUString SfxLinkUndoAction::GetRepeatComment(SfxRepeatTarget&r) const
 SfxLinkUndoAction::~SfxLinkUndoAction()
 {
     if( pAction )
-        pAction->SetLinked( sal_False );
+        pAction->SetLinkToSfxLinkUndoAction(0);
 }
 
+//------------------------------------------------------------------------
+
+void SfxLinkUndoAction::LinkedSfxUndoActionDestructed(const SfxUndoAction& rCandidate)
+{
+    OSL_ENSURE(0 != pAction, "OOps, we have no linked SfxUndoAction (!)");
+    OSL_ENSURE(pAction == &rCandidate, "OOps, the destroyed and linked UndoActions differ (!)");
+    (void)rCandidate;
+    pAction = 0;
+}
 
 //------------------------------------------------------------------------
 


More information about the Libreoffice-commits mailing list