diff options
author | Caolán McNamara <caolanm@redhat.com> | 2014-10-17 15:03:34 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2014-10-17 15:20:00 +0100 |
commit | 5bdfa8c12472eb9ff6ca054c2ada7150b1869fff (patch) | |
tree | 216653598067193c86a15daeb41fea0c053ab624 | |
parent | 0c1e9111d02649e77513a1d108146c9c055adb3a (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 02c3136e5e87..7a1f4e8712e0 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<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 4288472b9e3d..c0df48b51567 100644 --- a/filter/source/svg/svgfilter.hxx +++ b/filter/source/svg/svgfilter.hxx @@ -247,6 +247,7 @@ private: XDrawPageSequence mMasterPageTargets; Link maOldFieldHdl; + Link maNewFieldHdl; bool implImport( const Sequence< PropertyValue >& rDescriptor ) throw (RuntimeException, std::exception); diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx index 3be9defa600f..35ab20f87d79 100644 --- a/include/svx/svdmodel.hxx +++ b/include/svx/svdmodel.hxx @@ -232,6 +232,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 8a46865dbbe0..409f5c9bc14d 100644 --- a/svx/source/svdraw/svdmodel.cxx +++ b/svx/source/svdraw/svdmodel.cxx @@ -1918,6 +1918,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 e9697988e043..c85266837534 100644 --- a/svx/source/svdraw/svdoutlinercache.cxx +++ b/svx/source/svdraw/svdoutlinercache.cxx @@ -48,6 +48,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; @@ -94,6 +95,7 @@ void SdrOutlinerCache::disposeOutliner( SdrOutliner* pOutliner ) } else { + maActiveOutliners.erase(std::remove(maActiveOutliners.begin(), maActiveOutliners.end(), pOutliner), maActiveOutliners.end()); delete pOutliner; } } |