1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
11 #include <test/unoapixml_test.hxx>
12 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
13 #include <vcl/scheduler.hxx>
14 #include <vcl/keycodes.hxx>
15 #include <comphelper/processfactory.hxx>
16 #include <comphelper/propertyvalue.hxx>
17 #include <comphelper/servicehelper.hxx>
18 #include <svx/svdoole2.hxx>
19 #include <svx/svdpage.hxx>
22 #include <defaultsoptions.hxx>
24 #include <viewdata.hxx>
25 #include <tabvwsh.hxx>
26 #include <com/sun/star/frame/Desktop.hpp>
29 using namespace ::com::sun::star
;
30 using namespace ::com::sun::star::uno
;
32 /* Tests for sheets larger than 1024 columns and/or 1048576 rows. */
34 class ScJumboSheetsTest
: public UnoApiXmlTest
39 virtual void setUp() override
;
40 virtual void tearDown() override
;
42 void testRoundtripColumn2000Ods();
43 void testRoundtripColumn2000Xlsx();
44 void testRoundtripColumnRangeOds();
45 void testRoundtripColumnRangeXlsx();
46 void testRoundtripNamedRangesOds();
47 void testRoundtripNamedRangesXlsx();
48 void testNamedRangeNameConflict();
55 CPPUNIT_TEST_SUITE(ScJumboSheetsTest
);
57 CPPUNIT_TEST(testRoundtripColumn2000Ods
);
58 CPPUNIT_TEST(testRoundtripColumn2000Xlsx
);
59 CPPUNIT_TEST(testRoundtripColumnRangeOds
);
60 CPPUNIT_TEST(testRoundtripColumnRangeXlsx
);
61 CPPUNIT_TEST(testRoundtripNamedRangesOds
);
62 CPPUNIT_TEST(testRoundtripNamedRangesXlsx
);
63 CPPUNIT_TEST(testNamedRangeNameConflict
);
64 CPPUNIT_TEST(testTdf134553
);
65 CPPUNIT_TEST(testTdf134392
);
66 CPPUNIT_TEST(testTdf147509
);
67 CPPUNIT_TEST(testTdf133033
);
68 CPPUNIT_TEST(testTdf109061
);
70 CPPUNIT_TEST_SUITE_END();
73 void testRoundtripColumn2000(std::u16string_view name
, const char* format
);
74 void testRoundtripNamedRanges(std::u16string_view name
, const char* format
);
77 void ScJumboSheetsTest::testRoundtripColumn2000Ods()
79 testRoundtripColumn2000(u
"ods/value-in-column-2000.ods", "calc8");
82 void ScJumboSheetsTest::testRoundtripColumn2000Xlsx()
84 testRoundtripColumn2000(u
"xlsx/value-in-column-2000.xlsx", "Calc Office Open XML");
87 void ScJumboSheetsTest::testRoundtripColumn2000(std::u16string_view name
, const char* format
)
91 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
92 CPPUNIT_ASSERT(pModelObj
);
93 ScDocument
* pDoc
= pModelObj
->GetDocument();
94 // Check the value at BXX1 (2000th column).
95 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc
->GetValue(1999, 0, 0));
96 // Check the formula referencing the value.
97 CPPUNIT_ASSERT_EQUAL(OUString("=BXX1"), pDoc
->GetFormula(0, 0, 0));
98 // Recalc and check value in the reference.
100 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc
->GetValue(0, 0, 0));
103 saveAndReload(OUString::createFromAscii(format
));
105 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
106 CPPUNIT_ASSERT(pModelObj
);
108 ScDocument
* pDoc
= pModelObj
->GetDocument();
110 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc
->GetValue(1999, 0, 0));
111 CPPUNIT_ASSERT_EQUAL(OUString("=BXX1"), pDoc
->GetFormula(0, 0, 0));
113 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc
->GetValue(0, 0, 0));
117 void ScJumboSheetsTest::testRoundtripColumnRangeOds()
119 loadFromFile(u
"ods/sum-whole-column-row.ods");
121 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
122 CPPUNIT_ASSERT(pModelObj
);
123 ScDocument
* pDoc
= pModelObj
->GetDocument();
124 // Check the formula referencing the whole-row range.
125 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(2:2)"), pDoc
->GetFormula(0, 0, 0));
126 // Check the formula referencing the whole-column range.
127 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(C:C)"), pDoc
->GetFormula(1, 0, 0));
130 saveAndReload("calc8");
132 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
133 CPPUNIT_ASSERT(pModelObj
);
135 ScDocument
* pDoc
= pModelObj
->GetDocument();
136 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(2:2)"), pDoc
->GetFormula(0, 0, 0));
137 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(C:C)"), pDoc
->GetFormula(1, 0, 0));
138 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
139 CPPUNIT_ASSERT(pXmlDoc
);
141 "/office:document-content/office:body/office:spreadsheet/table:table/"
142 "table:table-row[1]/table:table-cell[1]"_ostr
,
143 "formula"_ostr
, "of:=SUM([.2:.2])");
145 "/office:document-content/office:body/office:spreadsheet/table:table/"
146 "table:table-row[1]/table:table-cell[2]"_ostr
,
147 "formula"_ostr
, "of:=SUM([.C:.C])");
151 void ScJumboSheetsTest::testRoundtripColumnRangeXlsx()
153 loadFromFile(u
"ods/sum-whole-column-row.ods");
154 saveAndReload("Calc Office Open XML");
156 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
157 CPPUNIT_ASSERT(pModelObj
);
159 ScDocument
* pDoc
= pModelObj
->GetDocument();
160 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(2:2)"), pDoc
->GetFormula(0, 0, 0));
161 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(C:C)"), pDoc
->GetFormula(1, 0, 0));
162 xmlDocUniquePtr pXmlDoc
= parseExport("xl/worksheets/sheet1.xml");
163 CPPUNIT_ASSERT(pXmlDoc
);
164 assertXPathContent(pXmlDoc
, "/x:worksheet/x:sheetData/x:row[1]/x:c[1]/x:f"_ostr
,
166 assertXPathContent(pXmlDoc
, "/x:worksheet/x:sheetData/x:row[1]/x:c[2]/x:f"_ostr
,
171 void ScJumboSheetsTest::testRoundtripNamedRanges(std::u16string_view name
, const char* format
)
175 std::pair
<OUString
, OUString
> ranges
[] = { { "CELLBXX1", "$Sheet1.$BXX$1" },
176 { "CELLSA4_AMJ4", "$Sheet1.$A$4:$AMJ$4" },
177 { "CELLSBXX1_BXX10", "$Sheet1.$BXX$1:$BXX$10" },
178 { "CELLSBXX1_BXX10_RELATIVE", "$Sheet1.BXX1:BXX10" },
179 { "CELLSE1_E1024", "$Sheet1.$E$1:$E$1024" },
180 { "CELLSE1_E2000000", "$Sheet1.$E$1:$E$2000000" },
181 { "COLUMN_E", "$Sheet1.$E:$E" },
182 { "ROW_4", "$Sheet1.$4:$4" } };
184 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
185 CPPUNIT_ASSERT(pModelObj
);
186 ScDocument
* pDoc
= pModelObj
->GetDocument();
187 for (const auto& range
: ranges
)
189 ScRangeData
* rangeData
= pDoc
->GetRangeName()->findByUpperName(range
.first
);
190 CPPUNIT_ASSERT(rangeData
);
191 CPPUNIT_ASSERT_EQUAL(range
.second
, rangeData
->GetSymbol());
195 saveAndReload(OUString::createFromAscii(format
));
197 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
198 CPPUNIT_ASSERT(pModelObj
);
199 ScDocument
* pDoc
= pModelObj
->GetDocument();
200 for (const auto& range
: ranges
)
202 ScRangeData
* rangeData
= pDoc
->GetRangeName()->findByUpperName(range
.first
);
203 CPPUNIT_ASSERT(rangeData
);
204 CPPUNIT_ASSERT_EQUAL(range
.second
, rangeData
->GetSymbol());
209 void ScJumboSheetsTest::testRoundtripNamedRangesOds()
211 testRoundtripNamedRanges(u
"ods/ranges-column-2000.ods", "calc8");
214 void ScJumboSheetsTest::testRoundtripNamedRangesXlsx()
216 testRoundtripNamedRanges(u
"ods/ranges-column-2000.ods", "Calc Office Open XML");
219 void ScJumboSheetsTest::testNamedRangeNameConflict()
221 // The document contains named ranges named 'num1' and 'num2', that should be still treated
222 // as named references even though with 16k columns those are normally NUM1 and NUM2 cells.
223 loadFromFile(u
"ods/named-range-conflict.ods");
225 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
226 CPPUNIT_ASSERT(pModelObj
);
227 ScDocument
* pDoc
= pModelObj
->GetDocument();
229 CPPUNIT_ASSERT_EQUAL(0.0, pDoc
->GetValue(10022, 0, 0)); // NUM1
230 CPPUNIT_ASSERT_EQUAL(0.0, pDoc
->GetValue(10022, 1, 0)); // NUM2
231 CPPUNIT_ASSERT_EQUAL(2.0, pDoc
->GetValue(0, 0, 0)); // = num1
232 CPPUNIT_ASSERT_EQUAL(3.0, pDoc
->GetValue(0, 1, 0)); // = sheet2.num2
233 CPPUNIT_ASSERT_EQUAL(0.0, pDoc
->GetValue(0, 2, 0)); // = SUM(NUM1:NUM2) (not named ranges)
234 pDoc
->SetValue(10022, 0, 0, 100); // NUM1
235 pDoc
->SetValue(10022, 1, 0, 200); // NUM2
237 // First two are the same, the sum changes.
238 CPPUNIT_ASSERT_EQUAL(2.0, pDoc
->GetValue(0, 0, 0));
239 CPPUNIT_ASSERT_EQUAL(3.0, pDoc
->GetValue(0, 1, 0));
240 CPPUNIT_ASSERT_EQUAL(300.0, pDoc
->GetValue(0, 2, 0));
243 void ScJumboSheetsTest::testTdf134553()
245 loadFromFile(u
"xlsx/tdf134553.xlsx");
247 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
248 CPPUNIT_ASSERT(pModelObj
);
249 ScDocument
* pDoc
= pModelObj
->GetDocument();
251 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
252 const SdrPage
* pPage
= pDrawLayer
->GetPage(0);
253 const SdrObject
* pOleObj
= pPage
->GetObj(0);
255 // Without the fix in place, this test would have failed here
256 CPPUNIT_ASSERT(pOleObj
);
258 // Sorry, the charts so severely suffer from DPI dependency, that I can't find motivation
259 // to add huge tolerances (around 350!) here to make it pass on non-default DPI, with no
260 // guarantee that the test would have any value after that. So just skip it.
261 // FIXME: the DPI check should be removed when either (1) the test is fixed to work with
262 // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin.
266 CPPUNIT_ASSERT_EQUAL(tools::Long(12741), pOleObj
->GetLogicRect().getOpenWidth());
267 CPPUNIT_ASSERT_EQUAL(tools::Long(7620), pOleObj
->GetLogicRect().getOpenHeight());
268 CPPUNIT_ASSERT_EQUAL(tools::Long(4574), pOleObj
->GetLogicRect().getX());
269 CPPUNIT_ASSERT_EQUAL(tools::Long(437), pOleObj
->GetLogicRect().getY());
271 ScTabViewShell
* pViewShell
= ScDocShell::GetViewData()->GetViewShell();
272 pViewShell
->SelectObject(u
"Diagram 1");
274 dispatchCommand(mxComponent
, ".uno:Cut", {});
276 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pPage
->GetObjCount());
278 dispatchCommand(mxComponent
, ".uno:Paste", {});
280 pOleObj
= pPage
->GetObj(0);
281 CPPUNIT_ASSERT(pOleObj
);
283 CPPUNIT_ASSERT_EQUAL(tools::Long(12741), pOleObj
->GetLogicRect().getOpenWidth());
284 CPPUNIT_ASSERT_EQUAL(tools::Long(7620), pOleObj
->GetLogicRect().getOpenHeight());
285 CPPUNIT_ASSERT_EQUAL(tools::Long(1700), pOleObj
->GetLogicRect().getX());
286 // tdf#147458: Without the fix in place, this test would have failed with
289 CPPUNIT_ASSERT_EQUAL(tools::Long(2117), pOleObj
->GetLogicRect().getY());
292 void ScJumboSheetsTest::testTdf134392()
294 // Without the fix in place, the file would have crashed
295 loadFromFile(u
"xlsx/tdf134392.xlsx");
297 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
298 CPPUNIT_ASSERT(pModelObj
);
299 ScDocument
* pDoc
= pModelObj
->GetDocument();
300 pDoc
->CalcAll(); // perform hard re-calculation.
303 void ScJumboSheetsTest::testTdf147509()
305 mxComponent
= loadFromDesktop("private:factory/scalc");
306 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
307 CPPUNIT_ASSERT(pModelObj
);
309 ScDocument
* pDoc
= pModelObj
->GetDocument();
311 pDoc
->SetString(0, 0, 0, "A");
312 pDoc
->SetString(1, 0, 0, "B");
314 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), ScDocShell::GetViewData()->GetCurX());
315 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), ScDocShell::GetViewData()->GetCurY());
317 dispatchCommand(mxComponent
, ".uno:SelectColumn", {});
319 dispatchCommand(mxComponent
, ".uno:InsertColumnsAfter", {});
321 CPPUNIT_ASSERT_EQUAL(OUString("A"), pDoc
->GetString(ScAddress(0, 0, 0)));
323 // Without the fix in place, this test would have failed with
326 CPPUNIT_ASSERT_EQUAL(OUString(""), pDoc
->GetString(ScAddress(1, 0, 0)));
327 CPPUNIT_ASSERT_EQUAL(OUString("B"), pDoc
->GetString(ScAddress(2, 0, 0)));
330 void ScJumboSheetsTest::testTdf133033()
332 mxComponent
= loadFromDesktop("private:factory/scalc");
333 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
334 CPPUNIT_ASSERT(pModelObj
);
336 pModelObj
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_DOWN
| KEY_MOD1
);
337 Scheduler::ProcessEventsToIdle();
339 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), ScDocShell::GetViewData()->GetCurX());
340 CPPUNIT_ASSERT_EQUAL(sal_Int32(16777215), ScDocShell::GetViewData()->GetCurY());
343 void ScJumboSheetsTest::testTdf109061()
345 // Without the fix in place, the file would have crashed
346 loadFromFile(u
"xlsx/tdf109061.xlsx");
348 ScModelObj
* pModelObj
= comphelper::getFromUnoTunnel
<ScModelObj
>(mxComponent
);
349 CPPUNIT_ASSERT(pModelObj
);
350 ScDocument
* pDoc
= pModelObj
->GetDocument();
351 pDoc
->CalcAll(); // perform hard re-calculation.
353 CPPUNIT_ASSERT_EQUAL(6.0, pDoc
->GetValue(1, 3, 0));
356 ScJumboSheetsTest::ScJumboSheetsTest()
357 : UnoApiXmlTest("/sc/qa/unit/data/")
361 void ScJumboSheetsTest::setUp()
363 UnoApiXmlTest::setUp();
365 //Init before GetDefaultsOptions
368 ScDefaultsOptions aDefaultsOption
= SC_MOD()->GetDefaultsOptions();
369 aDefaultsOption
.SetInitJumboSheets(true);
370 SC_MOD()->SetDefaultsOptions(aDefaultsOption
);
373 void ScJumboSheetsTest::tearDown()
375 ScDefaultsOptions aDefaultsOption
= SC_MOD()->GetDefaultsOptions();
376 aDefaultsOption
.SetInitJumboSheets(false);
377 SC_MOD()->SetDefaultsOptions(aDefaultsOption
);
379 UnoApiXmlTest::tearDown();
382 CPPUNIT_TEST_SUITE_REGISTRATION(ScJumboSheetsTest
);
384 CPPUNIT_PLUGIN_IMPLEMENT();
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */