summaryrefslogtreecommitdiff
path: root/sc/qa/unit
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-08-18 23:13:05 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2021-08-19 06:41:04 +0200
commit420e834007ca654db9803030726edb32c3ba5710 (patch)
tree859599fcff2232b4d718ee69608b85a01ef627b7 /sc/qa/unit
parentf58f35b2c8ca1efbacec642a8f3de5b0c499bc6b (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/qa/unit')
-rw-r--r--sc/qa/unit/data/ods/many_charts.odsbin0 -> 192672 bytes
-rw-r--r--sc/qa/unit/subsequent_export-test2.cxx90
2 files changed, 89 insertions, 1 deletions
diff --git a/sc/qa/unit/data/ods/many_charts.ods b/sc/qa/unit/data/ods/many_charts.ods
new file mode 100644
index 000000000000..31acdf66e1ed
--- /dev/null
+++ b/sc/qa/unit/data/ods/many_charts.ods
Binary files differ
diff --git a/sc/qa/unit/subsequent_export-test2.cxx b/sc/qa/unit/subsequent_export-test2.cxx
index 05f102cd1f38..7b8d294b8ca3 100644
--- a/sc/qa/unit/subsequent_export-test2.cxx
+++ b/sc/qa/unit/subsequent_export-test2.cxx
@@ -73,7 +73,12 @@
#include <svl/zformat.hxx>
#include <test/xmltesttools.hxx>
-#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/graphic/GraphicType.hpp>
@@ -196,6 +201,7 @@ public:
void testTdf142929_filterLessThanXLSX();
void testInvalidNamedRange();
void testTdf143220XLSX();
+ void testTdf142264ManyChartsToXLSX();
CPPUNIT_TEST_SUITE(ScExportTest2);
@@ -299,6 +305,7 @@ public:
CPPUNIT_TEST(testTdf142929_filterLessThanXLSX);
CPPUNIT_TEST(testInvalidNamedRange);
CPPUNIT_TEST(testTdf143220XLSX);
+ CPPUNIT_TEST(testTdf142264ManyChartsToXLSX);
CPPUNIT_TEST_SUITE_END();
@@ -2476,6 +2483,87 @@ void ScExportTest2::testTdf143220XLSX()
xDocSh->DoClose();
}
+void ScExportTest2::testTdf142264ManyChartsToXLSX()
+{
+ // The cache size for the test should be small enough, to make sure that some charts get
+ // unloaded in the process, and then loaded on demand properly (default is currently 20)
+ CPPUNIT_ASSERT_LESS(sal_Int32(40),
+ officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get());
+
+ ScDocShellRef xDocSh = loadDoc(u"many_charts.", FORMAT_ODS);
+ CPPUNIT_ASSERT(xDocSh.is());
+ xDocSh = saveAndReload(xDocSh.get(), FORMAT_XLSX);
+ CPPUNIT_ASSERT(xDocSh.is());
+
+ auto xModel = xDocSh->GetModel();
+ css::uno::Reference<css::drawing::XDrawPagesSupplier> xSupplier(xModel,
+ css::uno::UNO_QUERY_THROW);
+ auto xDrawPages = xSupplier->getDrawPages();
+
+ // No charts (or other objects) on the first sheet, and resp. first draw page
+ css::uno::Reference<css::drawing::XDrawPage> xPage(xDrawPages->getByIndex(0),
+ css::uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xPage->getCount());
+
+ // 20 charts on the second sheet, and resp. second draw page
+ xPage.set(xDrawPages->getByIndex(1), css::uno::UNO_QUERY_THROW);
+ // Without the fix in place, this test would have failed with
+ // - Expected: 20
+ // - Actual : 0
+ // Because only the last 20 charts would get exported, all on the third sheet
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(20), xPage->getCount());
+ for (sal_Int32 i = 0; i < xPage->getCount(); ++i)
+ {
+ css::uno::Reference<css::beans::XPropertySet> xProps(xPage->getByIndex(i),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::chart2::XChartDocument> xChart(xProps->getPropertyValue("Model"),
+ css::uno::UNO_QUERY_THROW);
+ const auto xDiagram = xChart->getFirstDiagram();
+ CPPUNIT_ASSERT(xDiagram);
+
+ css::uno::Reference<css::chart2::XCoordinateSystemContainer> xCooSysContainer(
+ xDiagram, uno::UNO_QUERY_THROW);
+
+ const auto xCooSysSeq = xCooSysContainer->getCoordinateSystems();
+ for (const auto& rCooSys : xCooSysSeq)
+ {
+ css::uno::Reference<css::chart2::XChartTypeContainer> xChartTypeCont(
+ rCooSys, uno::UNO_QUERY_THROW);
+ uno::Sequence<uno::Reference<chart2::XChartType>> xChartTypeSeq
+ = xChartTypeCont->getChartTypes();
+ CPPUNIT_ASSERT(xChartTypeSeq.hasElements());
+ }
+ }
+
+ // 20 charts on the third sheet, and resp. third draw page
+ xPage.set(xDrawPages->getByIndex(2), css::uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(20), xPage->getCount());
+ for (sal_Int32 i = 0; i < xPage->getCount(); ++i)
+ {
+ css::uno::Reference<css::beans::XPropertySet> xProps(xPage->getByIndex(i),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::chart2::XChartDocument> xChart(xProps->getPropertyValue("Model"),
+ css::uno::UNO_QUERY_THROW);
+ const auto xDiagram = xChart->getFirstDiagram();
+ CPPUNIT_ASSERT(xDiagram);
+
+ css::uno::Reference<css::chart2::XCoordinateSystemContainer> xCooSysContainer(
+ xDiagram, uno::UNO_QUERY_THROW);
+
+ const auto xCooSysSeq = xCooSysContainer->getCoordinateSystems();
+ for (const auto& rCooSys : xCooSysSeq)
+ {
+ css::uno::Reference<css::chart2::XChartTypeContainer> xChartTypeCont(
+ rCooSys, uno::UNO_QUERY_THROW);
+ uno::Sequence<uno::Reference<chart2::XChartType>> xChartTypeSeq
+ = xChartTypeCont->getChartTypes();
+ CPPUNIT_ASSERT(xChartTypeSeq.hasElements());
+ }
+ }
+
+ xDocSh->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest2);
CPPUNIT_PLUGIN_IMPLEMENT();