129361a
From 7adf5a76404205e3b2f1dbb4bb01a612d78ea0dc Mon Sep 17 00:00:00 2001
129361a
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
129361a
Date: Tue, 13 Jan 2015 13:55:58 +0000
129361a
Subject: [PATCH] allow comparing documents which only differ by frame contents
129361a
129361a
if two documents have the same number of frames then have an additional stab at
129361a
comparing the contents of those frames
129361a
129361a
Change-Id: Ie7f1a8906d49d720a74620ad8d69fd97c76304e3
129361a
(cherry picked from commit 16916a14a2ce382aa4ff2a25f8e477108aba5a67)
129361a
---
129361a
 sw/source/core/doc/doccomp.cxx | 236 +++++++++++++++++++++++++----------------
129361a
 1 file changed, 144 insertions(+), 92 deletions(-)
129361a
129361a
diff --git a/sw/source/core/doc/doccomp.cxx b/sw/source/core/doc/doccomp.cxx
129361a
index 8634835..043d2d4 100644
129361a
--- a/sw/source/core/doc/doccomp.cxx
129361a
+++ b/sw/source/core/doc/doccomp.cxx
129361a
@@ -38,6 +38,7 @@
129361a
 #include <section.hxx>
129361a
 #include <tox.hxx>
129361a
 #include <docsh.hxx>
129361a
+#include <fmtcntnt.hxx>
129361a
 
129361a
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
129361a
 #include <com/sun/star/document/XDocumentProperties.hpp>
129361a
@@ -65,18 +66,32 @@ public:
129361a
 
129361a
 class CompareData
129361a
 {
129361a
+protected:
129361a
+    SwDoc& rDoc;
129361a
+private:
129361a
     size_t* pIndex;
129361a
     bool* pChangedFlag;
129361a
 
129361a
-protected:
129361a
+    SwPaM *pInsRing, *pDelRing;
129361a
+
129361a
+    sal_uLong PrevIdx( const SwNode* pNd );
129361a
+    sal_uLong NextIdx( const SwNode* pNd );
129361a
+
129361a
     vector< CompareLine* > aLines;
129361a
     sal_uLong nSttLineNum;
129361a
+    bool m_bRecordDiff;
129361a
 
129361a
     // Truncate beginning and end and add all others to the LinesArray
129361a
-    virtual void CheckRanges( CompareData& ) = 0;
129361a
+    void CheckRanges( CompareData& );
129361a
+
129361a
+    virtual const SwNode& GetEndOfContent() = 0;
129361a
 
129361a
 public:
129361a
-    CompareData();
129361a
+    CompareData(SwDoc& rD, bool bRecordDiff)
129361a
+        : rDoc( rD ), pIndex( 0 ), pChangedFlag( 0 ), pInsRing(0), pDelRing(0)
129361a
+        , nSttLineNum( 0 ), m_bRecordDiff(bRecordDiff)
129361a
+    {
129361a
+    }
129361a
     virtual ~CompareData();
129361a
 
129361a
     // Are there differences?
129361a
@@ -89,10 +104,10 @@ public:
129361a
     // Displaying the actually content is to be handled by the subclass!
129361a
     sal_uLong ShowDiffs( const CompareData& rData );
129361a
 
129361a
-    virtual void ShowInsert( sal_uLong nStt, sal_uLong nEnd );
129361a
-    virtual void ShowDelete( const CompareData& rData, sal_uLong nStt,
129361a
+    void ShowInsert( sal_uLong nStt, sal_uLong nEnd );
129361a
+    void ShowDelete( const CompareData& rData, sal_uLong nStt,
129361a
                                 sal_uLong nEnd, sal_uLong nInsPos );
129361a
-    virtual void CheckForChangesInLine( const CompareData& rData,
129361a
+    void CheckForChangesInLine( const CompareData& rData,
129361a
                                     sal_uLong& nStt, sal_uLong& nEnd,
129361a
                                     sal_uLong& nThisStt, sal_uLong& nThisEnd );
129361a
 
129361a
@@ -114,6 +129,38 @@ public:
129361a
             { return aLines[ nLine ]; }
129361a
     void InsertLine( CompareLine* pLine )
129361a
         { aLines.push_back( pLine ); }
129361a
+
129361a
+    void SetRedlinesToDoc( bool bUseDocInfo );
129361a
+};
129361a
+
129361a
+class CompareMainText : public CompareData
129361a
+{
129361a
+public:
129361a
+    CompareMainText(SwDoc &rD, bool bRecordDiff=true)
129361a
+        : CompareData(rD, bRecordDiff)
129361a
+    {
129361a
+    }
129361a
+
129361a
+    virtual const SwNode& GetEndOfContent() SAL_OVERRIDE
129361a
+    {
129361a
+        return rDoc.GetNodes().GetEndOfContent();
129361a
+    }
129361a
+};
129361a
+
129361a
+class CompareFrmFmtText : public CompareData
129361a
+{
129361a
+    const SwNodeIndex &m_rIndex;
129361a
+public:
129361a
+    CompareFrmFmtText(SwDoc &rD, const SwNodeIndex &rIndex, bool bRecordDiff=true)
129361a
+        : CompareData(rD, bRecordDiff)
129361a
+        , m_rIndex(rIndex)
129361a
+    {
129361a
+    }
129361a
+
129361a
+    virtual const SwNode& GetEndOfContent() SAL_OVERRIDE
129361a
+    {
129361a
+        return *m_rIndex.GetNode().EndOfSectionNode();
129361a
+    }
129361a
 };
129361a
 
129361a
 class Hash
129361a
@@ -328,13 +375,21 @@ public:
129361a
 
129361a
 CompareLine::~CompareLine() {}
129361a
 
129361a
-CompareData::CompareData()
129361a
-    : pIndex( 0 ), pChangedFlag( 0 ), nSttLineNum( 0 )
129361a
-{
129361a
-}
129361a
-
129361a
 CompareData::~CompareData()
129361a
 {
129361a
+    if( pDelRing )
129361a
+    {
129361a
+        while( pDelRing->GetNext() != pDelRing )
129361a
+            delete pDelRing->GetNext();
129361a
+        delete pDelRing;
129361a
+    }
129361a
+    if( pInsRing )
129361a
+    {
129361a
+        while( pInsRing->GetNext() != pInsRing )
129361a
+            delete pInsRing->GetNext();
129361a
+        delete pInsRing;
129361a
+    }
129361a
+
129361a
     delete[] pIndex;
129361a
     delete[] pChangedFlag;
129361a
 }
129361a
@@ -393,9 +448,12 @@ sal_uLong CompareData::ShowDiffs( const CompareData& rData )
129361a
             while( nStt1 < nLen1 && rData.GetChanged( nStt1 )) ++nStt1;
129361a
             while( nStt2 < nLen2 && GetChanged( nStt2 )) ++nStt2;
129361a
 
129361a
-            // Check if there are changed lines (only slightly different) and
129361a
-            // compare them in detail.
129361a
-            CheckForChangesInLine( rData, nSav1, nStt1, nSav2, nStt2 );
129361a
+            if (m_bRecordDiff)
129361a
+            {
129361a
+                // Check if there are changed lines (only slightly different) and
129361a
+                // compare them in detail.
129361a
+                CheckForChangesInLine( rData, nSav1, nStt1, nSav2, nStt2 );
129361a
+            }
129361a
 
129361a
             ++nCnt;
129361a
         }
129361a
@@ -422,19 +480,6 @@ bool CompareData::HasDiffs( const CompareData& rData ) const
129361a
     return bRet;
129361a
 }
129361a
 
129361a
-void CompareData::ShowInsert( sal_uLong, sal_uLong )
129361a
-{
129361a
-}
129361a
-
129361a
-void CompareData::ShowDelete( const CompareData&, sal_uLong, sal_uLong, sal_uLong )
129361a
-{
129361a
-}
129361a
-
129361a
-void CompareData::CheckForChangesInLine( const CompareData& ,
129361a
-                                    sal_uLong&, sal_uLong&, sal_uLong&, sal_uLong& )
129361a
-{
129361a
-}
129361a
-
129361a
 Hash::Hash( sal_uLong nSize )
129361a
     : nCount(1)
129361a
 {
129361a
@@ -972,30 +1017,6 @@ public:
129361a
     OUString GetText() const;
129361a
 };
129361a
 
129361a
-class SwCompareData : public CompareData
129361a
-{
129361a
-    SwDoc& rDoc;
129361a
-    SwPaM *pInsRing, *pDelRing;
129361a
-
129361a
-    sal_uLong PrevIdx( const SwNode* pNd );
129361a
-    sal_uLong NextIdx( const SwNode* pNd );
129361a
-
129361a
-    virtual void CheckRanges( CompareData& ) SAL_OVERRIDE;
129361a
-    virtual void ShowInsert( sal_uLong nStt, sal_uLong nEnd ) SAL_OVERRIDE;
129361a
-    virtual void ShowDelete( const CompareData& rData, sal_uLong nStt,
129361a
-                                sal_uLong nEnd, sal_uLong nInsPos ) SAL_OVERRIDE;
129361a
-
129361a
-    virtual void CheckForChangesInLine( const CompareData& rData,
129361a
-                                    sal_uLong& nStt, sal_uLong& nEnd,
129361a
-                                    sal_uLong& nThisStt, sal_uLong& nThisEnd ) SAL_OVERRIDE;
129361a
-
129361a
-public:
129361a
-    SwCompareData( SwDoc& rD ) : rDoc( rD ), pInsRing(0), pDelRing(0) {}
129361a
-    virtual ~SwCompareData();
129361a
-
129361a
-    void SetRedlinesToDoc( bool bUseDocInfo );
129361a
-};
129361a
-
129361a
 SwCompareLine::SwCompareLine( const SwNode& rNd )
129361a
     : rNode( rNd )
129361a
 {
129361a
@@ -1400,23 +1421,7 @@ bool SwCompareLine::ChangesInLine( const SwCompareLine& rLine,
129361a
     return bRet;
129361a
 }
129361a
 
129361a
-SwCompareData::~SwCompareData()
129361a
-{
129361a
-    if( pDelRing )
129361a
-    {
129361a
-        while( pDelRing->GetNext() != pDelRing )
129361a
-            delete pDelRing->GetNext();
129361a
-        delete pDelRing;
129361a
-    }
129361a
-    if( pInsRing )
129361a
-    {
129361a
-        while( pInsRing->GetNext() != pInsRing )
129361a
-            delete pInsRing->GetNext();
129361a
-        delete pInsRing;
129361a
-    }
129361a
-}
129361a
-
129361a
-sal_uLong SwCompareData::NextIdx( const SwNode* pNd )
129361a
+sal_uLong CompareData::NextIdx( const SwNode* pNd )
129361a
 {
129361a
     if( pNd->IsStartNode() )
129361a
     {
129361a
@@ -1430,7 +1435,7 @@ sal_uLong SwCompareData::NextIdx( const SwNode* pNd )
129361a
     return pNd->GetIndex() + 1;
129361a
 }
129361a
 
129361a
-sal_uLong SwCompareData::PrevIdx( const SwNode* pNd )
129361a
+sal_uLong CompareData::PrevIdx( const SwNode* pNd )
129361a
 {
129361a
     if( pNd->IsEndNode() )
129361a
     {
129361a
@@ -1444,13 +1449,13 @@ sal_uLong SwCompareData::PrevIdx( const SwNode* pNd )
129361a
     return pNd->GetIndex() - 1;
129361a
 }
129361a
 
129361a
-void SwCompareData::CheckRanges( CompareData& rData )
129361a
+void CompareData::CheckRanges( CompareData& rData )
129361a
 {
129361a
-    const SwNodes& rSrcNds = static_cast<SwCompareData&>(rData).rDoc.GetNodes();
129361a
+    const SwNodes& rSrcNds = rData.rDoc.GetNodes();
129361a
     const SwNodes& rDstNds = rDoc.GetNodes();
129361a
 
129361a
-    const SwNode& rSrcEndNd = rSrcNds.GetEndOfContent();
129361a
-    const SwNode& rDstEndNd = rDstNds.GetEndOfContent();
129361a
+    const SwNode& rSrcEndNd = rData.GetEndOfContent();
129361a
+    const SwNode& rDstEndNd = GetEndOfContent();
129361a
 
129361a
     sal_uLong nSrcSttIdx = NextIdx( rSrcEndNd.StartOfSectionNode() );
129361a
     sal_uLong nSrcEndIdx = rSrcEndNd.GetIndex();
129361a
@@ -1497,7 +1502,7 @@ void SwCompareData::CheckRanges( CompareData& rData )
129361a
     }
129361a
 }
129361a
 
129361a
-void SwCompareData::ShowInsert( sal_uLong nStt, sal_uLong nEnd )
129361a
+void CompareData::ShowInsert( sal_uLong nStt, sal_uLong nEnd )
129361a
 {
129361a
     SwPaM* pTmp = new SwPaM( static_cast<const SwCompareLine*>(GetLine( nStt ))->GetNode(), 0,
129361a
                              static_cast<const SwCompareLine*>(GetLine( nEnd-1 ))->GetEndNode(), 0,
129361a
@@ -1508,7 +1513,7 @@ void SwCompareData::ShowInsert( sal_uLong nStt, sal_uLong nEnd )
129361a
     // #i65201#: These SwPaMs are calculated smaller than needed, see comment below
129361a
 }
129361a
 
129361a
-void SwCompareData::ShowDelete(
129361a
+void CompareData::ShowDelete(
129361a
     const CompareData& rData,
129361a
     sal_uLong nStt,
129361a
     sal_uLong nEnd,
129361a
@@ -1541,14 +1546,14 @@ void SwCompareData::ShowDelete(
129361a
     }
129361a
     else
129361a
     {
129361a
-        pLineNd = &rDoc.GetNodes().GetEndOfContent();
129361a
+        pLineNd = &GetEndOfContent();
129361a
         nOffset = 0;
129361a
     }
129361a
 
129361a
     SwNodeIndex aInsPos( *pLineNd, nOffset );
129361a
     SwNodeIndex aSavePos( aInsPos, -1 );
129361a
 
129361a
-    static_cast<const SwCompareData&>(rData).rDoc.GetDocumentContentOperationsManager().CopyWithFlyInFly( aRg, 0, aInsPos );
129361a
+    rData.rDoc.GetDocumentContentOperationsManager().CopyWithFlyInFly( aRg, 0, aInsPos );
129361a
     rDoc.getIDocumentState().SetModified();
129361a
     ++aSavePos;
129361a
 
129361a
@@ -1572,7 +1577,7 @@ void SwCompareData::ShowDelete(
129361a
     }
129361a
 }
129361a
 
129361a
-void SwCompareData::CheckForChangesInLine( const CompareData& rData,
129361a
+void CompareData::CheckForChangesInLine( const CompareData& rData,
129361a
                                     sal_uLong& rStt, sal_uLong& rEnd,
129361a
                                     sal_uLong& rThisStt, sal_uLong& rThisEnd )
129361a
 {
129361a
@@ -1625,7 +1630,7 @@ void SwCompareData::CheckForChangesInLine( const CompareData& rData,
129361a
     }
129361a
 }
129361a
 
129361a
-void SwCompareData::SetRedlinesToDoc( bool bUseDocInfo )
129361a
+void CompareData::SetRedlinesToDoc( bool bUseDocInfo )
129361a
 {
129361a
     SwPaM* pTmp = pDelRing;
129361a
 
129361a
@@ -1673,7 +1678,7 @@ void SwCompareData::SetRedlinesToDoc( bool bUseDocInfo )
129361a
             }
129361a
             // #i101009#
129361a
             // prevent redlines that end on structural end node
129361a
-            if (& rDoc.GetNodes().GetEndOfContent() ==
129361a
+            if (& GetEndOfContent() ==
129361a
                 & pTmp->GetPoint()->nNode.GetNode())
129361a
             {
129361a
                 pTmp->GetPoint()->nNode--;
129361a
@@ -1705,7 +1710,7 @@ void SwCompareData::SetRedlinesToDoc( bool bUseDocInfo )
129361a
             }
129361a
             // #i101009#
129361a
             // prevent redlines that end on structural end node
129361a
-            if (& rDoc.GetNodes().GetEndOfContent() ==
129361a
+            if (& GetEndOfContent() ==
129361a
                 & pTmp->GetPoint()->nNode.GetNode())
129361a
             {
129361a
                 pTmp->GetPoint()->nNode--;
129361a
@@ -1760,6 +1765,48 @@ void SwCompareData::SetRedlinesToDoc( bool bUseDocInfo )
129361a
     }
129361a
 }
129361a
 
129361a
+typedef std::shared_ptr<CompareData> CompareDataPtr;
129361a
+typedef std::pair<CompareDataPtr, CompareDataPtr> CompareDataPtrPair;
129361a
+typedef std::vector<CompareDataPtrPair> Comparators;
129361a
+
129361a
+namespace
129361a
+{
129361a
+    Comparators buildComparators(SwDoc &rSrcDoc, SwDoc &rDestDoc)
129361a
+    {
129361a
+        Comparators aComparisons;
129361a
+        //compare main text
129361a
+        aComparisons.push_back(CompareDataPtrPair(CompareDataPtr(new CompareMainText(rSrcDoc)),
129361a
+                                                  CompareDataPtr(new CompareMainText(rDestDoc))));
129361a
+
129361a
+        //if we have the same number of frames then try to compare within them
129361a
+        const SwFrmFmts *pSrcFrmFmts = rSrcDoc.GetSpzFrmFmts();
129361a
+        const SwFrmFmts *pDestFrmFmts = rDestDoc.GetSpzFrmFmts();
129361a
+        if (pSrcFrmFmts->size() == pDestFrmFmts->size())
129361a
+        {
129361a
+            for (size_t i = 0; i < pSrcFrmFmts->size(); ++i)
129361a
+            {
129361a
+                const SwFrmFmt& rSrcFmt = *(*pSrcFrmFmts)[i];
129361a
+                const SwFrmFmt& rDestFmt = *(*pDestFrmFmts)[i];
129361a
+                const SwNodeIndex* pSrcIdx = rSrcFmt.GetCntnt().GetCntntIdx();
129361a
+                const SwNodeIndex* pDestIdx = rDestFmt.GetCntnt().GetCntntIdx();
129361a
+                if (!pSrcIdx && !pDestIdx)
129361a
+                    continue;
129361a
+                if (!pSrcIdx || !pDestIdx)
129361a
+                    break;
129361a
+                const SwNode* pSrcNode = pSrcIdx->GetNode().EndOfSectionNode();
129361a
+                const SwNode* pDestNode = pDestIdx->GetNode().EndOfSectionNode();
129361a
+                if (!pSrcNode && !pDestNode)
129361a
+                    continue;
129361a
+                if (!pSrcNode || !pDestNode)
129361a
+                    break;
129361a
+                aComparisons.push_back(CompareDataPtrPair(CompareDataPtr(new CompareFrmFmtText(rSrcDoc, *pSrcIdx)),
129361a
+                                                          CompareDataPtr(new CompareFrmFmtText(rDestDoc, *pDestIdx))));
129361a
+            }
129361a
+        }
129361a
+        return aComparisons;
129361a
+    }
129361a
+}
129361a
+
129361a
 // Returns (the difference count?) if something is different
129361a
 long SwDoc::CompareDoc( const SwDoc& rDoc )
129361a
 {
129361a
@@ -1800,19 +1847,26 @@ long SwDoc::CompareDoc( const SwDoc& rDoc )
129361a
     rSrcDoc.getIDocumentRedlineAccess().SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_INSERT );
129361a
     getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT));
129361a
 
129361a
-    SwCompareData aD0( rSrcDoc );
129361a
-    SwCompareData aD1( *this );
129361a
-
129361a
-    aD1.CompareLines( aD0 );
129361a
+    Comparators aComparisons(buildComparators(rSrcDoc, *this));
129361a
 
129361a
-    nRet = aD1.ShowDiffs( aD0 );
e262bc1
+    for (auto& a : aComparisons)
129361a
+    {
129361a
+        CompareData& rD0 = *a.first.get();
129361a
+        CompareData& rD1 = *a.second.get();
129361a
+        rD1.CompareLines( rD0 );
129361a
+        nRet |= rD1.ShowDiffs( rD0 );
129361a
+    }
129361a
 
129361a
     if( nRet )
129361a
     {
129361a
-      getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON |
129361a
+        getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON |
129361a
                        nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE));
129361a
 
129361a
-        aD1.SetRedlinesToDoc( !bDocWasModified );
e262bc1
+        for (auto& a : aComparisons)
129361a
+        {
129361a
+            CompareData& rD1 = *a.second.get();
129361a
+            rD1.SetRedlinesToDoc( !bDocWasModified );
129361a
+        }
129361a
         getIDocumentState().SetModified();
129361a
     }
129361a
 
129361a
@@ -2016,11 +2070,9 @@ long SwDoc::MergeDoc( const SwDoc& rDoc )
129361a
     rSrcDoc.getIDocumentRedlineAccess().SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_DELETE );
129361a
     getIDocumentRedlineAccess().SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_DELETE );
129361a
 
129361a
-    SwCompareData aD0( rSrcDoc );
129361a
-    SwCompareData aD1( *this );
129361a
-
129361a
+    CompareMainText aD0(rSrcDoc, false);
129361a
+    CompareMainText aD1(*this, false);
129361a
     aD1.CompareLines( aD0 );
129361a
-
129361a
     if( !aD1.HasDiffs( aD0 ) )
129361a
     {
129361a
         // we want to get all redlines from the SourceDoc
129361a
-- 
129361a
1.9.3
129361a