diff options
author | Caolán McNamara <caolanm@redhat.com> | 2014-10-17 15:03:34 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2014-10-18 10:34:08 +0200 |
commit | 9b8cc24d5e6a6a216582c5ddbe80bcbd53d337b0 (patch) | |
tree | 7ab713925186fd9d3c869cba0c0ea133c2bd208f | |
parent | c357fb2dbdc54d9ee8471ce4e9f9381e74a6deed (diff) |
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
-rw-r--r-- | filter/source/svg/svgexport.cxx | 18 | ||||
-rw-r--r-- | filter/source/svg/svgfilter.hxx | 1 | ||||
-rw-r--r-- | include/svx/svdmodel.hxx | 2 | ||||
-rw-r--r-- | svx/source/inc/svdoutlinercache.hxx | 7 | ||||
-rw-r--r-- | svx/source/svdraw/svdmodel.cxx | 11 | ||||
-rw-r--r-- | svx/source/svdraw/svdoutlinercache.cxx | 2 |
6 files changed, 39 insertions, 2 deletions
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx index a9cfc013e062..4265f358bcd7 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 85fab2b4c63a..09c41d299ced 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 81df0c4a9dcb..fa7f18a0c845 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 6dbf7286c817..03572fc29389 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 b0cf71e213e1..82dfa4cd007f 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 8f9eba82e52a..810034a55e20 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; } } |