diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-08-18 23:13:05 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-08-19 06:41:04 +0200 |
commit | 420e834007ca654db9803030726edb32c3ba5710 (patch) | |
tree | 859599fcff2232b4d718ee69608b85a01ef627b7 /sc/source | |
parent | f58f35b2c8ca1efbacec642a8f3de5b0c499bc6b (diff) |
tdf#142264: make sure to load potentially unloaded objects when saving
Commit 574eec9036c5f185b3572ba1e0ca9d111eb361dc happened to reveal
a pre-existing problem that XLSX export only saved those OLE objects
that were kept loaded in the OLE object cache, subject to thevalue of
org.openoffice.Office.Common/Cache/DrawingEngine/OLE_Objects.
Before that change, the imported charts were marked modified on load,
and that prevented them from unloading in OLEObjCache::UnloadCheckHdl,
because SdrOle2Obj::CanUnloadRunningObj returned false.
After the mentioned change, the charts started to load without the
wrong "modified" state, which allowed them to be properly managed by
the cache, and the export filter implementation error surfaced. It's
likely that commit 692878e3bb83c0fc104c5cca946c25ccf2d84ab2 tried to
workaround the same underlying problem for charts that for some reason
/ at some point in time didn't get marked modified on load, and that
commit converted an error shown in Excel into silently missing charts.
This change makes sure that whenever a reference to chart document
is requested from XclExpChartObj, it is actually loaded and ready
for reading data.
Possibly something could be done on the level of old reference that
becomes non-functional (although valid) as the result of unloading,
so that it would automatically reload on following use. That would
make operating on the references robust. I didn't find an obvious
way to do that.
It is interesting to investigate, it the heizenbug related to images
disappearing from documents, as users keep reporting without robust
reproducers, might possibly be caused by a similar problem.
Change-Id: I45fcdc98254157d805c7519340b5265526f27166
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120688
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/filter/excel/xeescher.cxx | 16 | ||||
-rw-r--r-- | sc/source/filter/inc/xeescher.hxx | 3 |
2 files changed, 10 insertions, 9 deletions
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index f81f35b13f78..28ddc36e6b2b 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -1549,13 +1549,10 @@ XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape // create the chart substream object ScfPropertySet aShapeProp( xShape ); - Reference< XModel > xModel; - aShapeProp.GetProperty( xModel, "Model" ); - mxChartDoc.set( xModel,UNO_QUERY ); css::awt::Rectangle aBoundRect; aShapeProp.GetProperty( aBoundRect, "BoundRect" ); tools::Rectangle aChartRect( Point( aBoundRect.X, aBoundRect.Y ), Size( aBoundRect.Width, aBoundRect.Height ) ); - mxChart = std::make_shared<XclExpChart>( GetRoot(), xModel, aChartRect ); + mxChart = std::make_shared<XclExpChart>(GetRoot(), GetChartDoc(), aChartRect); } XclExpChartObj::~XclExpChartObj() @@ -1581,7 +1578,7 @@ void XclExpChartObj::SaveXml( XclExpXmlStream& rStrm ) if (xPropSet.is()) { XclObjAny::WriteFromTo( rStrm, mxShape, GetTab() ); - ChartExport aChartExport(XML_xdr, pDrawing, mxChartDoc, &rStrm, drawingml::DOCUMENT_XLSX); + ChartExport aChartExport(XML_xdr, pDrawing, GetChartDoc(), &rStrm, drawingml::DOCUMENT_XLSX); auto pURLTransformer = std::make_shared<ScURLTransformer>(*mpDoc); aChartExport.SetURLTranslator(pURLTransformer); static sal_Int32 nChartCount = 0; @@ -1598,9 +1595,14 @@ void XclExpChartObj::SaveXml( XclExpXmlStream& rStrm ) pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) ); } -const css::uno::Reference<css::chart::XChartDocument>& XclExpChartObj::GetChartDoc() const +css::uno::Reference<css::chart::XChartDocument> XclExpChartObj::GetChartDoc() const { - return mxChartDoc; + SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape); + if (!pObj || pObj->GetObjIdentifier() != OBJ_OLE2) + return {}; + // May load here - makes sure that we are working with actually loaded OLE object + return css::uno::Reference<css::chart::XChartDocument>( + static_cast<SdrOle2Obj*>(pObj)->getXModel(), css::uno::UNO_QUERY); } XclExpNote::XclExpNote(const XclExpRoot& rRoot, const ScAddress& rScPos, diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx index f0be1425d76e..00d4057671e2 100644 --- a/sc/source/filter/inc/xeescher.hxx +++ b/sc/source/filter/inc/xeescher.hxx @@ -321,13 +321,12 @@ public: virtual void Save( XclExpStream& rStrm ) override; virtual void SaveXml( XclExpXmlStream& rStrm ) override; - const css::uno::Reference<css::chart::XChartDocument>& GetChartDoc() const; + css::uno::Reference<css::chart::XChartDocument> GetChartDoc() const; private: typedef std::shared_ptr< XclExpChart > XclExpChartRef; XclExpChartRef mxChart; /// The chart itself (BOF/EOF substream data). css::uno::Reference< css::drawing::XShape > mxShape; - css::uno::Reference< css::chart::XChartDocument > mxChartDoc; ScDocument* mpDoc; }; |