[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.2' - filter/source include/svx svx/source

Caolán McNamara caolanm at redhat.com
Sat Oct 18 01:28:23 PDT 2014


 filter/source/svg/svgexport.cxx        |   18 ++++++++++++++++--
 filter/source/svg/svgfilter.hxx        |    1 +
 include/svx/svdmodel.hxx               |    2 ++
 svx/source/inc/svdoutlinercache.hxx    |    7 +++++++
 svx/source/svdraw/svdmodel.cxx         |   11 +++++++++++
 svx/source/svdraw/svdoutlinercache.cxx |    2 ++
 6 files changed, 39 insertions(+), 2 deletions(-)

New commits:
commit 9b8cc24d5e6a6a216582c5ddbe80bcbd53d337b0
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Oct 17 15:03:34 2014 +0100

    Resolves: fdo#62682 crash on second export of svg
    
    because the first export has left "dangling" CalcFieldValueHdl Links in
    Outliners that got created based on the Drawing Outliner while it had a
    temporary CalcFieldValueHdl installed, and didn't get the old CalcFieldValueHdl
    installed when the old Drawing Outliner one was re-installed.
    
    Change-Id: I064a154ece488c9a4c3467b753451df7e73ae883

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index a9cfc01..4265f35 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -598,7 +598,8 @@ sal_Bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
                                     SdrOutliner& rOutl = mpSdrModel->GetDrawOutliner(NULL);
 
                                     maOldFieldHdl = rOutl.GetCalcFieldValueHdl();
-                                    rOutl.SetCalcFieldValueHdl( LINK( this, SVGFilter, CalcFieldHdl) );
+                                    maNewFieldHdl = LINK(this, SVGFilter, CalcFieldHdl);
+                                    rOutl.SetCalcFieldValueHdl(maNewFieldHdl);
                                 }
                             }
                             bRet = implExportDocument();
@@ -611,7 +612,20 @@ sal_Bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
                     }
 
                     if( mpSdrModel )
-                        mpSdrModel->GetDrawOutliner( NULL ).SetCalcFieldValueHdl( maOldFieldHdl );
+                    {
+                        //fdo#62682 The maNewFieldHdl can end up getting copied
+                        //into various other outliners which live past this
+                        //method, so get the full list of outliners and restore
+                        //the maOldFieldHdl for all that have ended up using
+                        //maNewFieldHdl
+                        std::vector<SdrOutliner*> aOutliners(mpSdrModel->GetActiveOutliners());
+                        for (auto aIter = aOutliners.begin(); aIter != aOutliners.end(); ++aIter)
+                        {
+                            SdrOutliner* pOutliner = *aIter;
+                            if (maNewFieldHdl == pOutliner->GetCalcFieldValueHdl())
+                                pOutliner->SetCalcFieldValueHdl(maOldFieldHdl);
+                        }
+                    }
 
                     delete mpSVGWriter, mpSVGWriter = NULL;
                     mpSVGExport = NULL; // pointed object is released by xSVGExport dtor at the end of this scope
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 85fab2b..09c41d2 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -263,6 +263,7 @@ private:
     XDrawPageSequence                   mMasterPageTargets;
 
     Link                                maOldFieldHdl;
+    Link                                maNewFieldHdl;
 
     sal_Bool                            implImport( const Sequence< PropertyValue >& rDescriptor ) throw (RuntimeException);
 
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 81df0c4..fa7f18a 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -233,6 +233,8 @@ public:
     sal_uIntPtr         nSwapGraphicsMode;
 
     SdrOutlinerCache* mpOutlinerCache;
+    //get a vector of all the SdrOutliner belonging to the model
+    std::vector<SdrOutliner*> GetActiveOutliners() const;
     SdrModelImpl*   mpImpl;
     sal_uInt16          mnCharCompressType;
     sal_uInt16          mnHandoutPageCount;
diff --git a/svx/source/inc/svdoutlinercache.hxx b/svx/source/inc/svdoutlinercache.hxx
index 6dbf728..03572fc 100644
--- a/svx/source/inc/svdoutlinercache.hxx
+++ b/svx/source/inc/svdoutlinercache.hxx
@@ -21,6 +21,7 @@
 #define INCLUDED_SVX_SOURCE_INC_SVDOUTLINERCACHE_HXX
 
 #include <sal/types.h>
+#include <vector>
 
 class SdrModel;
 class SdrOutliner;
@@ -33,12 +34,18 @@ private:
 
     SdrOutliner*    mpModeOutline;
     SdrOutliner*    mpModeText;
+
+    std::vector<SdrOutliner*> maActiveOutliners;
 public:
     SdrOutlinerCache( SdrModel* pModel );
     ~SdrOutlinerCache();
 
     SdrOutliner* createOutliner( sal_uInt16 nOutlinerMode );
     void disposeOutliner( SdrOutliner* pOutliner );
+    std::vector<SdrOutliner*> GetActiveOutliners() const
+    {
+        return maActiveOutliners;
+    }
 };
 
 #endif
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index b0cf71e..82dfa4c 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -1952,6 +1952,17 @@ SdrOutliner* SdrModel::createOutliner( sal_uInt16 nOutlinerMode )
     return mpOutlinerCache->createOutliner( nOutlinerMode );
 }
 
+std::vector<SdrOutliner*> SdrModel::GetActiveOutliners() const
+{
+    std::vector<SdrOutliner*> aRet(mpOutlinerCache ?
+        mpOutlinerCache->GetActiveOutliners() : std::vector<SdrOutliner*>());
+
+    aRet.push_back(pDrawOutliner);
+    aRet.push_back(pHitTestOutliner);
+
+    return aRet;
+}
+
 void SdrModel::disposeOutliner( SdrOutliner* pOutliner )
 {
     if( mpOutlinerCache )
diff --git a/svx/source/svdraw/svdoutlinercache.cxx b/svx/source/svdraw/svdoutlinercache.cxx
index 8f9eba8..810034a 100644
--- a/svx/source/svdraw/svdoutlinercache.cxx
+++ b/svx/source/svdraw/svdoutlinercache.cxx
@@ -49,6 +49,7 @@ SdrOutliner* SdrOutlinerCache::createOutliner( sal_uInt16 nOutlinerMode )
         pOutliner = SdrMakeOutliner( nOutlinerMode, mpModel );
         Outliner& aDrawOutliner = mpModel->GetDrawOutliner();
         pOutliner->SetCalcFieldValueHdl( aDrawOutliner.GetCalcFieldValueHdl() );
+        maActiveOutliners.push_back(pOutliner);
     }
 
     return pOutliner;
@@ -95,6 +96,7 @@ void SdrOutlinerCache::disposeOutliner( SdrOutliner* pOutliner )
         }
         else
         {
+            maActiveOutliners.erase(std::remove(maActiveOutliners.begin(), maActiveOutliners.end(), pOutliner), maActiveOutliners.end());
             delete pOutliner;
         }
     }


More information about the Libreoffice-commits mailing list