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 <caol...@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; } }
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits