From 0bb29affae83d0410f745f46267527e10777fcd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Fri, 17 Oct 2014 15:03:34 +0100 Subject: [PATCH] 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. (cherry picked from commit 5bdfa8c12472eb9ff6ca054c2ada7150b1869fff) Change-Id: I064a154ece488c9a4c3467b753451df7e73ae883 Reviewed-on: https://gerrit.libreoffice.org/12009 Reviewed-by: Michael Stahl Tested-by: Michael Stahl --- 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(-) diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx index 07cf0a4..7dc2419 100644 --- a/filter/source/svg/svgexport.cxx +++ b/filter/source/svg/svgexport.cxx @@ -602,7 +602,8 @@ 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(); @@ -615,7 +616,20 @@ 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 aOutliners(mpSdrModel->GetActiveOutliners()); + for (std::vector::iterator 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 7b68c2b..0c6371f 100644 --- a/filter/source/svg/svgfilter.hxx +++ b/filter/source/svg/svgfilter.hxx @@ -265,6 +265,7 @@ private: XDrawPageSequence mMasterPageTargets; Link maOldFieldHdl; + Link maNewFieldHdl; bool implImport( const Sequence< PropertyValue >& rDescriptor ) throw (RuntimeException); diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx index e982cb5..5aeeb70 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 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 +#include class SdrModel; class SdrOutliner; @@ -33,12 +34,18 @@ private: SdrOutliner* mpModeOutline; SdrOutliner* mpModeText; + + std::vector maActiveOutliners; public: SdrOutlinerCache( SdrModel* pModel ); ~SdrOutlinerCache(); SdrOutliner* createOutliner( sal_uInt16 nOutlinerMode ); void disposeOutliner( SdrOutliner* pOutliner ); + std::vector GetActiveOutliners() const + { + return maActiveOutliners; + } }; #endif diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx index f3fc337..0735d14 100644 --- a/svx/source/svdraw/svdmodel.cxx +++ b/svx/source/svdraw/svdmodel.cxx @@ -1929,6 +1929,17 @@ SdrOutliner* SdrModel::createOutliner( sal_uInt16 nOutlinerMode ) return mpOutlinerCache->createOutliner( nOutlinerMode ); } +std::vector SdrModel::GetActiveOutliners() const +{ + std::vector aRet(mpOutlinerCache ? + mpOutlinerCache->GetActiveOutliners() : std::vector()); + + 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; } } -- 1.9.3