summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2014-10-17 15:03:34 +0100
committerAndras Timar <andras.timar@collabora.com>2014-10-18 10:34:08 +0200
commit9b8cc24d5e6a6a216582c5ddbe80bcbd53d337b0 (patch)
tree7ab713925186fd9d3c869cba0c0ea133c2bd208f
parentc357fb2dbdc54d9ee8471ce4e9f9381e74a6deed (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.cxx18
-rw-r--r--filter/source/svg/svgfilter.hxx1
-rw-r--r--include/svx/svdmodel.hxx2
-rw-r--r--svx/source/inc/svdoutlinercache.hxx7
-rw-r--r--svx/source/svdraw/svdmodel.cxx11
-rw-r--r--svx/source/svdraw/svdoutlinercache.cxx2
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;
}
}