summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2014-10-17 15:03:34 +0100
committerCaolán McNamara <caolanm@redhat.com>2014-10-17 15:20:00 +0100
commit5bdfa8c12472eb9ff6ca054c2ada7150b1869fff (patch)
tree216653598067193c86a15daeb41fea0c053ab624
parent0c1e9111d02649e77513a1d108146c9c055adb3a (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 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;
}
}