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 <officecfg/Office/Common.hxx>
11 #include <sal/config.h>
12 #include <rtl/strbuf.hxx>
13 #include <osl/file.hxx>
15 #include <sfx2/app.hxx>
16 #include <sfx2/docfile.hxx>
17 #include <sfx2/frame.hxx>
18 #include <sfx2/sfxmodelfactory.hxx>
19 #include <svl/stritem.hxx>
21 #include "helper/qahelper.hxx"
22 #include "helper/xpath.hxx"
23 #include "helper/shared_test_impl.hxx"
25 #include "userdat.hxx"
27 #include "patattr.hxx"
28 #include "scitems.hxx"
29 #include "document.hxx"
30 #include "cellform.hxx"
31 #include "formulacell.hxx"
32 #include "tokenarray.hxx"
33 #include "editutil.hxx"
34 #include "scopetools.hxx"
35 #include "cellvalue.hxx"
36 #include "docfunc.hxx"
38 #include <tokenstringcontext.hxx>
39 #include <chgtrack.hxx>
40 #include <dpcache.hxx>
41 #include <dpobject.hxx>
45 #include <svx/svdoole2.hxx>
46 #include <svx/svdpage.hxx>
47 #include <svx/svdograf.hxx>
48 #include "tabprotection.hxx"
49 #include <editeng/wghtitem.hxx>
50 #include <editeng/postitem.hxx>
51 #include <editeng/editdata.hxx>
52 #include <editeng/eeitem.hxx>
53 #include <editeng/editobj.hxx>
54 #include <editeng/section.hxx>
55 #include <editeng/crossedoutitem.hxx>
56 #include <editeng/borderline.hxx>
57 #include <editeng/fontitem.hxx>
58 #include <editeng/udlnitem.hxx>
59 #include <formula/grammar.hxx>
60 #include <unotools/useroptions.hxx>
61 #include <tools/datetime.hxx>
63 #include <test/xmltesttools.hxx>
64 #include <comphelper/processfactory.hxx>
65 #include <com/sun/star/table/BorderLineStyle.hpp>
66 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
67 #include <com/sun/star/sheet/GeneralFunction.hpp>
68 #include <com/sun/star/drawing/XDrawPage.hpp>
69 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
70 #include <com/sun/star/awt/XBitmap.hpp>
71 #include <com/sun/star/graphic/XGraphic.hpp>
73 using namespace ::com::sun::star
;
74 using namespace ::com::sun::star::uno
;
76 class ScExportTest
: public ScBootstrapFixture
, XmlTestTools
79 virtual void registerNamespaces(xmlXPathContextPtr
& pXmlXPathCtx
) SAL_OVERRIDE
;
83 virtual void setUp() SAL_OVERRIDE
;
84 virtual void tearDown() SAL_OVERRIDE
;
86 #if !defined MACOSX && !defined DRAGONFLY
87 ScDocShellRef
saveAndReloadPassword( ScDocShell
*, const OUString
&, const OUString
&, const OUString
&, SfxFilterFlags
);
91 #if !defined MACOSX && !defined DRAGONFLY
92 void testPasswordExport();
94 void testConditionalFormatExportODS();
95 void testConditionalFormatExportXLSX();
96 void testColorScaleExportODS();
97 void testColorScaleExportXLSX();
98 void testDataBarExportODS();
99 void testDataBarExportXLSX();
100 void testMiscRowHeightExport();
101 void testNamedRangeBugfdo62729();
102 void testRichTextExportODS();
103 void testFormulaRefSheetNameODS();
105 void testCellValuesExportODS();
106 void testCellNoteExportODS();
107 void testCellNoteExportXLS();
108 void testFormatExportODS();
110 void testInlineArrayXLS();
111 void testEmbeddedChartXLS();
112 void testFormulaReferenceXLS();
113 void testSheetProtectionXLSX();
115 void testCellBordersXLS();
116 void testCellBordersXLSX();
117 void testTrackChangesSimpleXLSX();
118 void testSheetTabColorsXLSX();
120 void testSharedFormulaExportXLS();
121 void testSharedFormulaExportXLSX();
122 void testSharedFormulaStringResultExportXLSX();
124 void testFunctionsExcel2010( sal_uLong nFormatType
);
125 void testFunctionsExcel2010XLSX();
126 void testFunctionsExcel2010XLS();
127 void testFunctionsExcel2010ODS();
129 void testRelativePaths();
130 void testSheetProtection();
132 void testPivotTableXLSX();
133 void testPivotTableTwoDataFieldsXLSX();
135 void testSwappedOutImageExport();
136 void testLinkedGraphicRT();
137 void testImageWithSpecialID();
139 void testSupBookVirtualPath();
140 void testSheetLocalRangeNameXLS();
141 void testSheetTextBoxHyperlink();
143 void testSheetCharacterKerningSpace();
144 void testSheetCondensedCharacterSpace();
145 void testTextUnderlineColor();
146 void testSheetRunParagraphProperty();
147 void testHiddenShape();
148 void testMoveCellAnchoredShapes();
149 void testHeaderImage();
150 void testMatrixMultiplication();
151 void testRefStringXLSX();
152 void testRefStringConfigXLSX();
153 void testRefStringUnspecified();
155 CPPUNIT_TEST_SUITE(ScExportTest
);
157 #if !defined(MACOSX) && !defined(DRAGONFLY)
158 CPPUNIT_TEST(testPasswordExport
);
160 CPPUNIT_TEST(testConditionalFormatExportODS
);
161 CPPUNIT_TEST(testConditionalFormatExportXLSX
);
162 CPPUNIT_TEST(testColorScaleExportODS
);
163 CPPUNIT_TEST(testColorScaleExportXLSX
);
164 CPPUNIT_TEST(testDataBarExportODS
);
165 CPPUNIT_TEST(testDataBarExportXLSX
);
166 CPPUNIT_TEST(testMiscRowHeightExport
);
167 CPPUNIT_TEST(testNamedRangeBugfdo62729
);
168 CPPUNIT_TEST(testRichTextExportODS
);
169 CPPUNIT_TEST(testFormulaRefSheetNameODS
);
170 CPPUNIT_TEST(testCellValuesExportODS
);
171 CPPUNIT_TEST(testCellNoteExportODS
);
172 CPPUNIT_TEST(testCellNoteExportXLS
);
173 CPPUNIT_TEST(testFormatExportODS
);
174 CPPUNIT_TEST(testInlineArrayXLS
);
175 CPPUNIT_TEST(testEmbeddedChartXLS
);
176 CPPUNIT_TEST(testFormulaReferenceXLS
);
177 CPPUNIT_TEST(testSheetProtectionXLSX
);
178 CPPUNIT_TEST(testCellBordersXLS
);
179 CPPUNIT_TEST(testCellBordersXLSX
);
180 CPPUNIT_TEST(testTrackChangesSimpleXLSX
);
181 CPPUNIT_TEST(testSheetTabColorsXLSX
);
182 CPPUNIT_TEST(testSharedFormulaExportXLS
);
183 CPPUNIT_TEST(testSharedFormulaExportXLSX
);
184 CPPUNIT_TEST(testSharedFormulaStringResultExportXLSX
);
185 CPPUNIT_TEST(testFunctionsExcel2010XLSX
);
186 CPPUNIT_TEST(testFunctionsExcel2010XLS
);
188 CPPUNIT_TEST(testRelativePaths
);
190 CPPUNIT_TEST(testSheetProtection
);
191 CPPUNIT_TEST(testPivotTableXLSX
);
192 CPPUNIT_TEST(testPivotTableTwoDataFieldsXLSX
);
193 CPPUNIT_TEST(testFunctionsExcel2010ODS
);
195 CPPUNIT_TEST(testSupBookVirtualPath
);
197 CPPUNIT_TEST(testSwappedOutImageExport
);
198 CPPUNIT_TEST(testLinkedGraphicRT
);
199 CPPUNIT_TEST(testImageWithSpecialID
);
200 CPPUNIT_TEST(testSheetLocalRangeNameXLS
);
201 CPPUNIT_TEST(testSheetTextBoxHyperlink
);
202 CPPUNIT_TEST(testFontSize
);
203 CPPUNIT_TEST(testSheetCharacterKerningSpace
);
204 CPPUNIT_TEST(testSheetCondensedCharacterSpace
);
205 CPPUNIT_TEST(testTextUnderlineColor
);
206 CPPUNIT_TEST(testSheetRunParagraphProperty
);
207 CPPUNIT_TEST(testHiddenShape
);
208 CPPUNIT_TEST(testMoveCellAnchoredShapes
);
209 CPPUNIT_TEST(testHeaderImage
);
210 CPPUNIT_TEST(testMatrixMultiplication
);
211 CPPUNIT_TEST(testRefStringXLSX
);
212 CPPUNIT_TEST(testRefStringConfigXLSX
);
213 CPPUNIT_TEST(testRefStringUnspecified
);
215 CPPUNIT_TEST_SUITE_END();
218 void testExcelCellBorders( sal_uLong nFormatType
);
220 uno::Reference
<uno::XInterface
> m_xCalcComponent
;
224 void ScExportTest::registerNamespaces(xmlXPathContextPtr
& pXmlXPathCtx
)
226 struct { xmlChar
* pPrefix
; xmlChar
* pURI
; } aNamespaces
[] =
228 { BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main") },
229 { BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml") },
230 { BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart") },
231 { BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main") },
232 { BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006") },
233 { BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape") },
234 { BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup") },
235 { BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") },
236 { BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0") },
237 { BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0") },
238 { BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0") },
239 { BAD_CAST("xlink"), BAD_CAST("http://www.w3c.org/1999/xlink") },
240 { BAD_CAST("xdr"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing") },
241 { BAD_CAST("x"), BAD_CAST("http://schemas.openxmlformats.org/spreadsheetml/2006/main") }
243 for(size_t i
= 0; i
< SAL_N_ELEMENTS(aNamespaces
); ++i
)
245 xmlXPathRegisterNs(pXmlXPathCtx
, aNamespaces
[i
].pPrefix
, aNamespaces
[i
].pURI
);
249 #if !defined MACOSX && !defined DRAGONFLY
250 ScDocShellRef
ScExportTest::saveAndReloadPassword(ScDocShell
* pShell
, const OUString
&rFilter
,
251 const OUString
&rUserData
, const OUString
& rTypeName
, SfxFilterFlags nFormatType
)
253 utl::TempFile aTempFile
;
254 aTempFile
.EnableKillingFile();
255 SfxMedium
aStoreMedium( aTempFile
.GetURL(), STREAM_STD_WRITE
);
256 SotClipboardFormatId nExportFormat
= SotClipboardFormatId::NONE
;
257 if (nFormatType
== ODS_FORMAT_TYPE
)
258 nExportFormat
= SotClipboardFormatId::STARCHART_8
;
259 SfxFilter
* pExportFilter
= new SfxFilter(
261 OUString(), nFormatType
, nExportFormat
, rTypeName
, 0, OUString(),
262 rUserData
, OUString("private:factory/scalc*") );
263 pExportFilter
->SetVersion(SOFFICE_FILEFORMAT_CURRENT
);
264 aStoreMedium
.SetFilter(pExportFilter
);
265 SfxItemSet
* pExportSet
= aStoreMedium
.GetItemSet();
266 uno::Sequence
< beans::NamedValue
> aEncryptionData
= comphelper::OStorageHelper::CreatePackageEncryptionData( OUString("test") );
267 uno::Any xEncryptionData
;
268 xEncryptionData
<<= aEncryptionData
;
269 pExportSet
->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA
, xEncryptionData
));
271 uno::Reference
< embed::XStorage
> xMedStorage
= aStoreMedium
.GetStorage();
272 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xMedStorage
, aEncryptionData
);
274 pShell
->DoSaveAs( aStoreMedium
);
277 //std::cout << "File: " << aTempFile.GetURL() << std::endl;
279 SotClipboardFormatId nFormat
= SotClipboardFormatId::NONE
;
280 if (nFormatType
== ODS_FORMAT_TYPE
)
281 nFormat
= SotClipboardFormatId::STARCALC_8
;
283 OUString
aPass("test");
284 return load(aTempFile
.GetURL(), rFilter
, rUserData
, rTypeName
, nFormatType
, nFormat
, SOFFICE_FILEFORMAT_CURRENT
, &aPass
);
288 void ScExportTest::test()
290 ScDocShell
* pShell
= new ScDocShell(
291 SfxModelFlags::EMBEDDED_OBJECT
|
292 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
|
293 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
);
296 ScDocument
& rDoc
= pShell
->GetDocument();
298 rDoc
.SetValue(0,0,0, 1.0);
300 ScDocShellRef xDocSh
= saveAndReload( pShell
, ODS
);
302 CPPUNIT_ASSERT(xDocSh
.Is());
303 ScDocument
& rLoadedDoc
= xDocSh
->GetDocument();
304 double aVal
= rLoadedDoc
.GetValue(0,0,0);
305 ASSERT_DOUBLES_EQUAL(aVal
, 1.0);
309 #if !defined MACOSX && !defined DRAGONFLY
310 void ScExportTest::testPasswordExport()
312 ScDocShell
* pShell
= new ScDocShell(
313 SfxModelFlags::EMBEDDED_OBJECT
|
314 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
|
315 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
);
318 ScDocument
& rDoc
= pShell
->GetDocument();
320 rDoc
.SetValue(0,0,0, 1.0);
322 sal_Int32 nFormat
= ODS
;
323 OUString
aFilterName(getFileFormats()[nFormat
].pFilterName
, strlen(getFileFormats()[nFormat
].pFilterName
), RTL_TEXTENCODING_UTF8
) ;
324 OUString
aFilterType(getFileFormats()[nFormat
].pTypeName
, strlen(getFileFormats()[nFormat
].pTypeName
), RTL_TEXTENCODING_UTF8
);
325 ScDocShellRef xDocSh
= saveAndReloadPassword(pShell
, aFilterName
, OUString(), aFilterType
, getFileFormats()[nFormat
].nFormatType
);
327 CPPUNIT_ASSERT(xDocSh
.Is());
328 ScDocument
& rLoadedDoc
= xDocSh
->GetDocument();
329 double aVal
= rLoadedDoc
.GetValue(0,0,0);
330 ASSERT_DOUBLES_EQUAL(aVal
, 1.0);
336 void ScExportTest::testConditionalFormatExportODS()
338 ScDocShellRef xShell
= loadDoc("new_cond_format_test.", ODS
);
339 CPPUNIT_ASSERT(xShell
.Is());
341 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), ODS
);
342 CPPUNIT_ASSERT(xDocSh
.Is());
343 ScDocument
& rDoc
= xDocSh
->GetDocument();
344 OUString
aCSVFile("new_cond_format_test.");
346 createCSVPath( aCSVFile
, aCSVPath
);
347 testCondFile(aCSVPath
, &rDoc
, 0);
352 void ScExportTest::testConditionalFormatExportXLSX()
354 ScDocShellRef xShell
= loadDoc("new_cond_format_test.", XLSX
);
355 CPPUNIT_ASSERT(xShell
.Is());
357 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), XLSX
);
358 CPPUNIT_ASSERT(xDocSh
.Is());
359 ScDocument
& rDoc
= xDocSh
->GetDocument();
361 OUString
aCSVFile("new_cond_format_test.");
363 createCSVPath( aCSVFile
, aCSVPath
);
364 testCondFile(aCSVPath
, &rDoc
, 0);
367 OUString
aCSVFile("new_cond_format_test_sheet2.");
369 createCSVPath( aCSVFile
, aCSVPath
);
370 testCondFile(aCSVPath
, &rDoc
, 1);
376 void ScExportTest::testColorScaleExportODS()
378 ScDocShellRef xShell
= loadDoc("colorscale.", ODS
);
379 CPPUNIT_ASSERT(xShell
.Is());
381 ScDocShellRef xDocSh
= saveAndReload(xShell
, ODS
);
382 CPPUNIT_ASSERT(xDocSh
.Is());
384 ScDocument
& rDoc
= xDocSh
->GetDocument();
386 testColorScale2Entry_Impl(rDoc
);
387 testColorScale3Entry_Impl(rDoc
);
392 void ScExportTest::testColorScaleExportXLSX()
394 ScDocShellRef xShell
= loadDoc("colorscale.", XLSX
);
395 CPPUNIT_ASSERT(xShell
.Is());
397 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLSX
);
398 CPPUNIT_ASSERT(xDocSh
.Is());
400 ScDocument
& rDoc
= xDocSh
->GetDocument();
402 testColorScale2Entry_Impl(rDoc
);
403 testColorScale3Entry_Impl(rDoc
);
408 void ScExportTest::testDataBarExportODS()
410 ScDocShellRef xShell
= loadDoc("databar.", ODS
);
411 CPPUNIT_ASSERT(xShell
.Is());
413 ScDocShellRef xDocSh
= saveAndReload(xShell
, ODS
);
414 CPPUNIT_ASSERT(xDocSh
.Is());
416 ScDocument
& rDoc
= xDocSh
->GetDocument();
418 testDataBar_Impl(rDoc
);
423 void ScExportTest::testFormatExportODS()
425 ScDocShellRef xShell
= loadDoc("formats.", ODS
);
426 CPPUNIT_ASSERT(xShell
.Is());
428 ScDocShellRef xDocSh
= saveAndReload(xShell
, ODS
);
429 CPPUNIT_ASSERT(xDocSh
.Is());
431 ScDocument
& rDoc
= xDocSh
->GetDocument();
433 testFormats(this, &rDoc
, ODS
);
438 void ScExportTest::testDataBarExportXLSX()
440 ScDocShellRef xShell
= loadDoc("databar.", XLSX
);
441 CPPUNIT_ASSERT(xShell
.Is());
443 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLSX
);
444 CPPUNIT_ASSERT(xDocSh
.Is());
446 ScDocument
& rDoc
= xDocSh
->GetDocument();
448 testDataBar_Impl(rDoc
);
453 void ScExportTest::testMiscRowHeightExport()
455 TestParam::RowData DfltRowData
[] =
457 { 0, 4, 0, 529, 0, false },
458 { 5, 10, 0, 1058, 0, false },
459 { 17, 20, 0, 1767, 0, false },
460 // check last couple of row in document to ensure
461 // they are 5.29mm ( effective default row xlsx height )
462 { 1048573, 1048575, 0, 529, 0, false },
465 TestParam::RowData EmptyRepeatRowData
[] =
467 // rows 0-4, 5-10, 17-20 are all set at various
468 // heights, there is no content in the rows, there
469 // was a bug where only the first row ( of repeated rows )
470 // was set after export
471 { 0, 4, 0, 529, 0, false },
472 { 5, 10, 0, 1058, 0, false },
473 { 17, 20, 0, 1767, 0, false },
476 TestParam aTestValues
[] =
478 // Checks that some distributed ( non-empty ) heights remain set after export (roundtrip)
479 // additionally there is effectively a default row height ( 5.29 mm ). So we test the
480 // unset rows at the end of the document to ensure the effective xlsx default height
482 { "miscrowheights.", XLSX
, XLSX
, SAL_N_ELEMENTS(DfltRowData
), DfltRowData
},
483 // Checks that some distributed ( non-empty ) heights remain set after export (to xls)
484 { "miscrowheights.", XLSX
, XLS
, SAL_N_ELEMENTS(DfltRowData
), DfltRowData
},
485 // Checks that repreated rows ( of various heights ) remain set after export ( to xlsx )
486 { "miscemptyrepeatedrowheights.", ODS
, XLSX
, SAL_N_ELEMENTS(EmptyRepeatRowData
), EmptyRepeatRowData
},
487 // Checks that repreated rows ( of various heights ) remain set after export ( to xls )
488 { "miscemptyrepeatedrowheights.", ODS
, XLS
, SAL_N_ELEMENTS(EmptyRepeatRowData
), EmptyRepeatRowData
},
490 miscRowHeightsTest( aTestValues
, SAL_N_ELEMENTS(aTestValues
) );
495 void setAttribute( ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
, sal_uInt16 nType
)
498 aSel
.nStartPara
= aSel
.nEndPara
= nPara
;
499 aSel
.nStartPos
= nStart
;
502 SfxItemSet aItemSet
= rEE
.GetEmptyItemSet();
507 SvxWeightItem
aWeight(WEIGHT_BOLD
, nType
);
508 aItemSet
.Put(aWeight
);
509 rEE
.QuickSetAttribs(aItemSet
, aSel
);
514 SvxPostureItem
aItalic(ITALIC_NORMAL
, nType
);
515 aItemSet
.Put(aItalic
);
516 rEE
.QuickSetAttribs(aItemSet
, aSel
);
519 case EE_CHAR_STRIKEOUT
:
521 SvxCrossedOutItem
aCrossOut(STRIKEOUT_SINGLE
, nType
);
522 aItemSet
.Put(aCrossOut
);
523 rEE
.QuickSetAttribs(aItemSet
, aSel
);
526 case EE_CHAR_OVERLINE
:
528 SvxOverlineItem
aItem(UNDERLINE_DOUBLE
, nType
);
530 rEE
.QuickSetAttribs(aItemSet
, aSel
);
533 case EE_CHAR_UNDERLINE
:
535 SvxUnderlineItem
aItem(UNDERLINE_DOUBLE
, nType
);
537 rEE
.QuickSetAttribs(aItemSet
, aSel
);
545 void setFont( ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
, const OUString
& rFontName
)
548 aSel
.nStartPara
= aSel
.nEndPara
= nPara
;
549 aSel
.nStartPos
= nStart
;
552 SfxItemSet aItemSet
= rEE
.GetEmptyItemSet();
553 SvxFontItem
aItem(FAMILY_MODERN
, rFontName
, "", PITCH_VARIABLE
, RTL_TEXTENCODING_UTF8
, EE_CHAR_FONTINFO
);
555 rEE
.QuickSetAttribs(aItemSet
, aSel
);
560 void ScExportTest::testNamedRangeBugfdo62729()
562 ScDocShellRef xShell
= loadDoc("fdo62729.", ODS
);
563 CPPUNIT_ASSERT(xShell
.Is());
564 ScDocument
& rDoc
= xShell
->GetDocument();
566 ScRangeName
* pNames
= rDoc
.GetRangeName();
567 //should be just a single named range
568 CPPUNIT_ASSERT(pNames
->size() == 1 );
570 //should be still a single named range
571 CPPUNIT_ASSERT(pNames
->size() == 1 );
572 ScDocShellRef xDocSh
= saveAndReload(xShell
, ODS
);
575 CPPUNIT_ASSERT(xDocSh
.Is());
576 ScDocument
& rDoc2
= xDocSh
->GetDocument();
578 pNames
= rDoc2
.GetRangeName();
579 //after reload should still have a named range
580 CPPUNIT_ASSERT(pNames
->size() == 1 );
585 void ScExportTest::testRichTextExportODS()
589 static bool isBold(const editeng::Section
& rAttr
)
591 if (rAttr
.maAttributes
.empty())
594 std::vector
<const SfxPoolItem
*>::const_iterator it
= rAttr
.maAttributes
.begin(), itEnd
= rAttr
.maAttributes
.end();
595 for (; it
!= itEnd
; ++it
)
597 const SfxPoolItem
* p
= *it
;
598 if (p
->Which() != EE_CHAR_WEIGHT
)
601 return static_cast<const SvxWeightItem
*>(p
)->GetWeight() == WEIGHT_BOLD
;
606 static bool isItalic(const editeng::Section
& rAttr
)
608 if (rAttr
.maAttributes
.empty())
611 std::vector
<const SfxPoolItem
*>::const_iterator it
= rAttr
.maAttributes
.begin(), itEnd
= rAttr
.maAttributes
.end();
612 for (; it
!= itEnd
; ++it
)
614 const SfxPoolItem
* p
= *it
;
615 if (p
->Which() != EE_CHAR_ITALIC
)
618 return static_cast<const SvxPostureItem
*>(p
)->GetPosture() == ITALIC_NORMAL
;
623 static bool isStrikeOut(const editeng::Section
& rAttr
)
625 if (rAttr
.maAttributes
.empty())
628 std::vector
<const SfxPoolItem
*>::const_iterator it
= rAttr
.maAttributes
.begin(), itEnd
= rAttr
.maAttributes
.end();
629 for (; it
!= itEnd
; ++it
)
631 const SfxPoolItem
* p
= *it
;
632 if (p
->Which() != EE_CHAR_STRIKEOUT
)
635 return static_cast<const SvxCrossedOutItem
*>(p
)->GetStrikeout() == STRIKEOUT_SINGLE
;
640 static bool isOverline(const editeng::Section
& rAttr
, FontUnderline eStyle
)
642 if (rAttr
.maAttributes
.empty())
645 std::vector
<const SfxPoolItem
*>::const_iterator it
= rAttr
.maAttributes
.begin(), itEnd
= rAttr
.maAttributes
.end();
646 for (; it
!= itEnd
; ++it
)
648 const SfxPoolItem
* p
= *it
;
649 if (p
->Which() != EE_CHAR_OVERLINE
)
652 return static_cast<const SvxOverlineItem
*>(p
)->GetLineStyle() == eStyle
;
657 static bool isUnderline(const editeng::Section
& rAttr
, FontUnderline eStyle
)
659 if (rAttr
.maAttributes
.empty())
662 std::vector
<const SfxPoolItem
*>::const_iterator it
= rAttr
.maAttributes
.begin(), itEnd
= rAttr
.maAttributes
.end();
663 for (; it
!= itEnd
; ++it
)
665 const SfxPoolItem
* p
= *it
;
666 if (p
->Which() != EE_CHAR_UNDERLINE
)
669 return static_cast<const SvxUnderlineItem
*>(p
)->GetLineStyle() == eStyle
;
674 static bool isFont(const editeng::Section
& rAttr
, const OUString
& rFontName
)
676 if (rAttr
.maAttributes
.empty())
679 std::vector
<const SfxPoolItem
*>::const_iterator it
= rAttr
.maAttributes
.begin(), itEnd
= rAttr
.maAttributes
.end();
680 for (; it
!= itEnd
; ++it
)
682 const SfxPoolItem
* p
= *it
;
683 if (p
->Which() != EE_CHAR_FONTINFO
)
686 return static_cast<const SvxFontItem
*>(p
)->GetFamilyName() == rFontName
;
691 bool checkB2(const EditTextObject
* pText
) const
696 if (pText
->GetParagraphCount() != 1)
699 if (pText
->GetText(0) != "Bold and Italic")
702 std::vector
<editeng::Section
> aSecAttrs
;
703 pText
->GetAllSections(aSecAttrs
);
704 if (aSecAttrs
.size() != 3)
707 // Check the first bold section.
708 const editeng::Section
* pAttr
= &aSecAttrs
[0];
709 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 4)
712 if (pAttr
->maAttributes
.size() != 1 || !isBold(*pAttr
))
715 // The middle section should be unformatted.
716 pAttr
= &aSecAttrs
[1];
717 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 4 || pAttr
->mnEnd
!= 9)
720 if (!pAttr
->maAttributes
.empty())
723 // The last section should be italic.
724 pAttr
= &aSecAttrs
[2];
725 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 9 || pAttr
->mnEnd
!= 15)
728 if (pAttr
->maAttributes
.size() != 1 || !isItalic(*pAttr
))
734 bool checkB4(const EditTextObject
* pText
) const
739 if (pText
->GetParagraphCount() != 3)
742 if (pText
->GetText(0) != "One")
745 if (pText
->GetText(1) != "Two")
748 if (pText
->GetText(2) != "Three")
754 bool checkB5(const EditTextObject
* pText
) const
759 if (pText
->GetParagraphCount() != 6)
762 if (!pText
->GetText(0).isEmpty())
765 if (pText
->GetText(1) != "Two")
768 if (pText
->GetText(2) != "Three")
771 if (!pText
->GetText(3).isEmpty())
774 if (pText
->GetText(4) != "Five")
777 if (!pText
->GetText(5).isEmpty())
783 bool checkB6(const EditTextObject
* pText
) const
788 if (pText
->GetParagraphCount() != 1)
791 if (pText
->GetText(0) != "Strike Me")
794 std::vector
<editeng::Section
> aSecAttrs
;
795 pText
->GetAllSections(aSecAttrs
);
796 if (aSecAttrs
.size() != 2)
799 // Check the first strike-out section.
800 const editeng::Section
* pAttr
= &aSecAttrs
[0];
801 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 6)
804 if (pAttr
->maAttributes
.size() != 1 || !isStrikeOut(*pAttr
))
807 // The last section should be unformatted.
808 pAttr
= &aSecAttrs
[1];
809 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 6 || pAttr
->mnEnd
!= 9)
815 bool checkB7(const EditTextObject
* pText
) const
820 if (pText
->GetParagraphCount() != 1)
823 if (pText
->GetText(0) != "Font1 and Font2")
826 std::vector
<editeng::Section
> aSecAttrs
;
827 pText
->GetAllSections(aSecAttrs
);
828 if (aSecAttrs
.size() != 3)
831 // First section should have "Courier" font applied.
832 const editeng::Section
* pAttr
= &aSecAttrs
[0];
833 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 5)
836 if (pAttr
->maAttributes
.size() != 1 || !isFont(*pAttr
, "Courier"))
839 // Last section should have "Luxi Mono" applied.
840 pAttr
= &aSecAttrs
[2];
841 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 10 || pAttr
->mnEnd
!= 15)
844 if (pAttr
->maAttributes
.size() != 1 || !isFont(*pAttr
, "Luxi Mono"))
850 bool checkB8(const EditTextObject
* pText
) const
855 if (pText
->GetParagraphCount() != 1)
858 if (pText
->GetText(0) != "Over and Under")
861 std::vector
<editeng::Section
> aSecAttrs
;
862 pText
->GetAllSections(aSecAttrs
);
863 if (aSecAttrs
.size() != 3)
866 // First section shoul have overline applied.
867 const editeng::Section
* pAttr
= &aSecAttrs
[0];
868 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 4)
871 if (pAttr
->maAttributes
.size() != 1 || !isOverline(*pAttr
, UNDERLINE_DOUBLE
))
874 // Last section should have underline applied.
875 pAttr
= &aSecAttrs
[2];
876 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 9 || pAttr
->mnEnd
!= 14)
879 if (pAttr
->maAttributes
.size() != 1 || !isUnderline(*pAttr
, UNDERLINE_DOUBLE
))
887 // Start with an empty document, put one edit text cell, and make sure it
888 // survives the save and reload.
889 ScDocShellRef xOrigDocSh
= loadDoc("empty.", ODS
, true);
890 const EditTextObject
* pEditText
;
892 ScDocument
& rDoc
= xOrigDocSh
->GetDocument();
893 CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", rDoc
.GetTableCount() > 0);
895 // Insert an edit text cell.
896 ScFieldEditEngine
* pEE
= &rDoc
.GetEditEngine();
897 pEE
->SetText("Bold and Italic");
898 // Set the 'Bold' part bold.
899 setAttribute(*pEE
, 0, 0, 4, EE_CHAR_WEIGHT
);
900 // Set the 'Italic' part italic.
901 setAttribute(*pEE
, 0, 9, 15, EE_CHAR_ITALIC
);
903 aSel
.nStartPara
= aSel
.nEndPara
= 0;
905 // Set this edit text to cell B2.
906 rDoc
.SetEditText(ScAddress(1,1,0), pEE
->CreateTextObject());
907 pEditText
= rDoc
.GetEditText(ScAddress(1,1,0));
908 CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc
.checkB2(pEditText
));
911 // Now, save and reload this document.
912 ScDocShellRef xNewDocSh
= saveAndReload(xOrigDocSh
, ODS
);
914 xOrigDocSh
->DoClose();
915 CPPUNIT_ASSERT(xNewDocSh
.Is());
916 ScDocument
& rDoc2
= xNewDocSh
->GetDocument();
917 CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", rDoc2
.GetTableCount() > 0);
918 ScFieldEditEngine
* pEE
= &rDoc2
.GetEditEngine();
920 // Make sure the content of B2 is still intact.
921 CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc
.checkB2(pEditText
));
923 // Insert a multi-line content to B4.
925 pEE
->SetText("One\nTwo\nThree");
926 rDoc2
.SetEditText(ScAddress(1,3,0), pEE
->CreateTextObject());
927 pEditText
= rDoc2
.GetEditText(ScAddress(1,3,0));
928 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc
.checkB4(pEditText
));
931 // Reload the doc again, and check the content of B2 and B4.
932 ScDocShellRef xNewDocSh2
= saveAndReload(xNewDocSh
, ODS
);
934 ScDocument
& rDoc3
= xNewDocSh2
->GetDocument();
935 ScFieldEditEngine
* pEE
= &rDoc3
.GetEditEngine();
936 xNewDocSh
->DoClose();
938 pEditText
= rDoc3
.GetEditText(ScAddress(1,1,0));
939 CPPUNIT_ASSERT_MESSAGE("B2 should be an edit text.", pEditText
);
940 pEditText
= rDoc3
.GetEditText(ScAddress(1,3,0));
941 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc
.checkB4(pEditText
));
943 // Insert a multi-line content to B5, but this time, set some empty paragraphs.
945 pEE
->SetText("\nTwo\nThree\n\nFive\n");
946 rDoc3
.SetEditText(ScAddress(1,4,0), pEE
->CreateTextObject());
947 pEditText
= rDoc3
.GetEditText(ScAddress(1,4,0));
948 CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value.", aCheckFunc
.checkB5(pEditText
));
950 // Insert a text with strikethrough in B6.
952 pEE
->SetText("Strike Me");
953 // Set the 'Strike' part strikethrough.
954 setAttribute(*pEE
, 0, 0, 6, EE_CHAR_STRIKEOUT
);
955 rDoc3
.SetEditText(ScAddress(1,5,0), pEE
->CreateTextObject());
956 pEditText
= rDoc3
.GetEditText(ScAddress(1,5,0));
957 CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value.", aCheckFunc
.checkB6(pEditText
));
959 // Insert a text with different font segments in B7.
961 pEE
->SetText("Font1 and Font2");
962 setFont(*pEE
, 0, 0, 5, "Courier");
963 setFont(*pEE
, 0, 10, 15, "Luxi Mono");
964 rDoc3
.SetEditText(ScAddress(1,6,0), pEE
->CreateTextObject());
965 pEditText
= rDoc3
.GetEditText(ScAddress(1,6,0));
966 CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value.", aCheckFunc
.checkB7(pEditText
));
968 // Insert a text with overline and underline in B8.
970 pEE
->SetText("Over and Under");
971 setAttribute(*pEE
, 0, 0, 4, EE_CHAR_OVERLINE
);
972 setAttribute(*pEE
, 0, 9, 14, EE_CHAR_UNDERLINE
);
973 rDoc3
.SetEditText(ScAddress(1,7,0), pEE
->CreateTextObject());
974 pEditText
= rDoc3
.GetEditText(ScAddress(1,7,0));
975 CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value.", aCheckFunc
.checkB8(pEditText
));
978 // Reload the doc again, and check the content of B2, B4, B6 and B7.
979 ScDocShellRef xNewDocSh3
= saveAndReload(xNewDocSh2
, ODS
);
980 ScDocument
& rDoc4
= xNewDocSh3
->GetDocument();
981 xNewDocSh2
->DoClose();
983 pEditText
= rDoc4
.GetEditText(ScAddress(1,1,0));
984 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value after save and reload.", aCheckFunc
.checkB2(pEditText
));
985 pEditText
= rDoc4
.GetEditText(ScAddress(1,3,0));
986 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value after save and reload.", aCheckFunc
.checkB4(pEditText
));
987 pEditText
= rDoc4
.GetEditText(ScAddress(1,4,0));
988 CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value after save and reload.", aCheckFunc
.checkB5(pEditText
));
989 pEditText
= rDoc4
.GetEditText(ScAddress(1,5,0));
990 CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value after save and reload.", aCheckFunc
.checkB6(pEditText
));
991 pEditText
= rDoc4
.GetEditText(ScAddress(1,6,0));
992 CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value after save and reload.", aCheckFunc
.checkB7(pEditText
));
993 pEditText
= rDoc4
.GetEditText(ScAddress(1,7,0));
994 CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value after save and reload.", aCheckFunc
.checkB8(pEditText
));
996 xNewDocSh3
->DoClose();
999 void ScExportTest::testFormulaRefSheetNameODS()
1001 ScDocShellRef xDocSh
= loadDoc("formula-quote-in-sheet-name.", ODS
, true);
1003 ScDocument
& rDoc
= xDocSh
->GetDocument();
1005 sc::AutoCalcSwitch
aACSwitch(rDoc
, true); // turn on auto calc.
1006 rDoc
.SetString(ScAddress(1,1,0), "='90''s Data'.B2");
1007 CPPUNIT_ASSERT_EQUAL(1.1, rDoc
.GetValue(ScAddress(1,1,0)));
1008 if (!checkFormula(rDoc
, ScAddress(1,1,0), "'90''s Data'.B2"))
1009 CPPUNIT_FAIL("Wrong formula");
1011 // Now, save and reload this document.
1012 ScDocShellRef xNewDocSh
= saveAndReload(xDocSh
, ODS
);
1015 ScDocument
& rDoc
= xNewDocSh
->GetDocument();
1017 CPPUNIT_ASSERT_EQUAL(1.1, rDoc
.GetValue(ScAddress(1,1,0)));
1018 if (!checkFormula(rDoc
, ScAddress(1,1,0), "'90''s Data'.B2"))
1019 CPPUNIT_FAIL("Wrong formula");
1021 xNewDocSh
->DoClose();
1024 void ScExportTest::testCellValuesExportODS()
1026 // Start with an empty document
1027 ScDocShellRef xOrigDocSh
= loadDoc("empty.", ODS
);
1029 ScDocument
& rDoc
= xOrigDocSh
->GetDocument();
1030 CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", rDoc
.GetTableCount() > 0);
1032 // set a value double
1033 rDoc
.SetValue(ScAddress(0,0,0), 2.0); // A1
1036 rDoc
.SetValue(ScAddress(2,0,0), 3.0); // C1
1037 rDoc
.SetValue(ScAddress(3,0,0), 3); // D1
1038 rDoc
.SetString(ScAddress(4,0,0), "=10*C1/4"); // E1
1039 rDoc
.SetValue(ScAddress(5,0,0), 3.0); // F1
1040 rDoc
.SetString(ScAddress(7,0,0), "=SUM(C1:F1)"); //H1
1043 rDoc
.SetString(ScAddress(0,2,0), "a simple line"); //A3
1045 // set a digit string
1046 rDoc
.SetString(ScAddress(0,4,0), "'12"); //A5
1047 // set a contiguous value
1048 rDoc
.SetValue(ScAddress(0,5,0), 12.0); //A6
1049 // set acontiguous string
1050 rDoc
.SetString(ScAddress(0,6,0), "a string"); //A7
1051 // set a contiguous formula
1052 rDoc
.SetString(ScAddress(0,7,0), "=$A$6"); //A8
1055 ScDocShellRef xNewDocSh
= saveAndReload(xOrigDocSh
, ODS
);
1056 xOrigDocSh
->DoClose();
1057 CPPUNIT_ASSERT(xNewDocSh
.Is());
1058 ScDocument
& rDoc
= xNewDocSh
->GetDocument();
1059 CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", rDoc
.GetTableCount() > 0);
1062 CPPUNIT_ASSERT_EQUAL(2.0, rDoc
.GetValue(0,0,0));
1063 CPPUNIT_ASSERT_EQUAL(3.0, rDoc
.GetValue(2,0,0));
1064 CPPUNIT_ASSERT_EQUAL(3.0, rDoc
.GetValue(3,0,0));
1065 CPPUNIT_ASSERT_EQUAL(7.5, rDoc
.GetValue(4,0,0));
1066 CPPUNIT_ASSERT_EQUAL(3.0, rDoc
.GetValue(5,0,0));
1069 if (!checkFormula(rDoc
, ScAddress(4,0,0), "10*C1/4"))
1070 CPPUNIT_FAIL("Wrong formula =10*C1/4");
1071 if (!checkFormula(rDoc
, ScAddress(7,0,0), "SUM(C1:F1)"))
1072 CPPUNIT_FAIL("Wrong formula =SUM(C1:F1)");
1073 CPPUNIT_ASSERT_EQUAL(16.5, rDoc
.GetValue(7,0,0));
1076 ScRefCellValue aCell
;
1077 aCell
.assign(rDoc
, ScAddress(0,2,0));
1078 CPPUNIT_ASSERT_EQUAL( CELLTYPE_STRING
, aCell
.meType
);
1080 // check for an empty cell
1081 aCell
.assign(rDoc
, ScAddress(0,3,0));
1082 CPPUNIT_ASSERT_EQUAL( CELLTYPE_NONE
, aCell
.meType
);
1084 // check a digit string
1085 aCell
.assign(rDoc
, ScAddress(0,4,0));
1086 CPPUNIT_ASSERT_EQUAL( CELLTYPE_STRING
, aCell
.meType
);
1088 //check contiguous values
1089 CPPUNIT_ASSERT_EQUAL( 12.0, rDoc
.GetValue(0,5,0) );
1090 CPPUNIT_ASSERT_EQUAL( OUString("a string"), rDoc
.GetString(0,6,0) );
1091 if (!checkFormula(rDoc
, ScAddress(0,7,0), "$A$6"))
1092 CPPUNIT_FAIL("Wrong formula =$A$6");
1093 CPPUNIT_ASSERT_EQUAL( rDoc
.GetValue(0,5,0), rDoc
.GetValue(0,7,0) );
1095 xNewDocSh
->DoClose();
1098 void ScExportTest::testCellNoteExportODS()
1100 ScDocShellRef xOrigDocSh
= loadDoc("single-note.", ODS
);
1101 ScAddress
aPos(0,0,0); // Start with A1.
1103 ScDocument
& rDoc
= xOrigDocSh
->GetDocument();
1105 CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", rDoc
.HasNote(aPos
));
1107 aPos
.IncRow(); // Move to A2.
1108 ScPostIt
* pNote
= rDoc
.GetOrCreateNote(aPos
);
1109 pNote
->SetText(aPos
, "Note One");
1110 pNote
->SetAuthor("Author One");
1111 CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", rDoc
.HasNote(aPos
));
1114 ScDocShellRef xNewDocSh
= saveAndReload(xOrigDocSh
, ODS
);
1115 xOrigDocSh
->DoClose();
1116 CPPUNIT_ASSERT(xNewDocSh
.Is());
1117 ScDocument
& rDoc
= xNewDocSh
->GetDocument();
1119 aPos
.SetRow(0); // Move back to A1.
1120 CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", rDoc
.HasNote(aPos
));
1121 aPos
.IncRow(); // Move to A2.
1122 CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", rDoc
.HasNote(aPos
));
1124 xNewDocSh
->DoClose();
1127 void ScExportTest::testCellNoteExportXLS()
1129 // Start with an empty document.s
1130 ScDocShellRef xOrigDocSh
= loadDoc("notes-on-3-sheets.", ODS
);
1132 ScDocument
& rDoc
= xOrigDocSh
->GetDocument();
1133 CPPUNIT_ASSERT_MESSAGE("This document should have 3 sheets.", rDoc
.GetTableCount() == 3);
1135 // Check note's presence.
1136 CPPUNIT_ASSERT( rDoc
.HasNote(ScAddress(0,0,0)));
1137 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,1,0)));
1138 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,2,0)));
1140 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,0,1)));
1141 CPPUNIT_ASSERT( rDoc
.HasNote(ScAddress(0,1,1)));
1142 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,2,1)));
1144 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,0,2)));
1145 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,1,2)));
1146 CPPUNIT_ASSERT( rDoc
.HasNote(ScAddress(0,2,2)));
1148 // save and reload as XLS.
1149 ScDocShellRef xNewDocSh
= saveAndReload(xOrigDocSh
, XLS
);
1151 xOrigDocSh
->DoClose();
1152 CPPUNIT_ASSERT(xNewDocSh
.Is());
1153 ScDocument
& rDoc
= xNewDocSh
->GetDocument();
1154 CPPUNIT_ASSERT_MESSAGE("This document should have 3 sheets.", rDoc
.GetTableCount() == 3);
1156 // Check note's presence again.
1157 CPPUNIT_ASSERT( rDoc
.HasNote(ScAddress(0,0,0)));
1158 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,1,0)));
1159 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,2,0)));
1161 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,0,1)));
1162 CPPUNIT_ASSERT( rDoc
.HasNote(ScAddress(0,1,1)));
1163 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,2,1)));
1165 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,0,2)));
1166 CPPUNIT_ASSERT(!rDoc
.HasNote(ScAddress(0,1,2)));
1167 CPPUNIT_ASSERT( rDoc
.HasNote(ScAddress(0,2,2)));
1169 xNewDocSh
->DoClose();
1175 void checkMatrixRange(ScDocument
& rDoc
, const ScRange
& rRange
)
1178 ScAddress aMatOrigin
;
1179 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
1181 for (SCROW nRow
= rRange
.aStart
.Row(); nRow
<= rRange
.aEnd
.Row(); ++nRow
)
1183 ScAddress
aPos(nCol
, nRow
, rRange
.aStart
.Tab());
1184 bool bIsMatrix
= rDoc
.GetMatrixFormulaRange(aPos
, aMatRange
);
1185 CPPUNIT_ASSERT_MESSAGE("Matrix expected, but not found.", bIsMatrix
);
1186 CPPUNIT_ASSERT_MESSAGE("Wrong matrix range.", rRange
== aMatRange
);
1187 const ScFormulaCell
* pCell
= rDoc
.GetFormulaCell(aPos
);
1188 CPPUNIT_ASSERT_MESSAGE("This must be a formula cell.", pCell
);
1190 bIsMatrix
= pCell
->GetMatrixOrigin(aMatOrigin
);
1191 CPPUNIT_ASSERT_MESSAGE("Not a part of matrix formula.", bIsMatrix
);
1192 CPPUNIT_ASSERT_MESSAGE("Wrong matrix origin.", aMatOrigin
== aMatRange
.aStart
);
1199 void ScExportTest::testInlineArrayXLS()
1201 ScDocShellRef xShell
= loadDoc("inline-array.", XLS
);
1202 CPPUNIT_ASSERT(xShell
.Is());
1204 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLS
);
1206 CPPUNIT_ASSERT(xDocSh
.Is());
1208 ScDocument
& rDoc
= xDocSh
->GetDocument();
1210 // B2:C3 contains a matrix.
1211 checkMatrixRange(rDoc
, ScRange(1,1,0,2,2,0));
1213 // B5:D6 contains a matrix.
1214 checkMatrixRange(rDoc
, ScRange(1,4,0,3,5,0));
1217 checkMatrixRange(rDoc
, ScRange(1,7,0,2,9,0));
1222 void ScExportTest::testEmbeddedChartXLS()
1224 ScDocShellRef xShell
= loadDoc("embedded-chart.", XLS
);
1225 CPPUNIT_ASSERT(xShell
.Is());
1227 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLS
);
1229 CPPUNIT_ASSERT(xDocSh
.Is());
1231 ScDocument
& rDoc
= xDocSh
->GetDocument();
1233 // Make sure the 2nd sheet is named 'Chart1'.
1235 rDoc
.GetName(1, aName
);
1236 CPPUNIT_ASSERT_EQUAL(OUString("Chart1"), aName
);
1238 const SdrOle2Obj
* pOleObj
= getSingleChartObject(rDoc
, 1);
1239 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj
);
1241 ScRangeList aRanges
= getChartRanges(rDoc
, *pOleObj
);
1242 CPPUNIT_ASSERT_MESSAGE("Label range (B3:B5) not found.", aRanges
.In(ScRange(1,2,1,1,4,1)));
1243 CPPUNIT_ASSERT_MESSAGE("Data label (C2) not found.", aRanges
.In(ScAddress(2,1,1)));
1244 CPPUNIT_ASSERT_MESSAGE("Data range (C3:C5) not found.", aRanges
.In(ScRange(2,2,1,2,4,1)));
1249 void ScExportTest::testFormulaReferenceXLS()
1251 ScDocShellRef xShell
= loadDoc("formula-reference.", XLS
);
1252 CPPUNIT_ASSERT(xShell
.Is());
1254 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLS
);
1256 CPPUNIT_ASSERT(xDocSh
.Is());
1258 ScDocument
& rDoc
= xDocSh
->GetDocument();
1260 if (!checkFormula(rDoc
, ScAddress(3,1,0), "$A$2+$B$2+$C$2"))
1261 CPPUNIT_FAIL("Wrong formula in D2");
1263 if (!checkFormula(rDoc
, ScAddress(3,2,0), "A3+B3+C3"))
1264 CPPUNIT_FAIL("Wrong formula in D3");
1266 if (!checkFormula(rDoc
, ScAddress(3,5,0), "SUM($A$6:$C$6)"))
1267 CPPUNIT_FAIL("Wrong formula in D6");
1269 if (!checkFormula(rDoc
, ScAddress(3,6,0), "SUM(A7:C7)"))
1270 CPPUNIT_FAIL("Wrong formula in D7");
1272 if (!checkFormula(rDoc
, ScAddress(3,9,0), "$Two.$A$2+$Two.$B$2+$Two.$C$2"))
1273 CPPUNIT_FAIL("Wrong formula in D10");
1275 if (!checkFormula(rDoc
, ScAddress(3,10,0), "$Two.A3+$Two.B3+$Two.C3"))
1276 CPPUNIT_FAIL("Wrong formula in D11");
1278 if (!checkFormula(rDoc
, ScAddress(3,13,0), "MIN($Two.$A$2:$C$2)"))
1279 CPPUNIT_FAIL("Wrong formula in D14");
1281 if (!checkFormula(rDoc
, ScAddress(3,14,0), "MAX($Two.A3:C3)"))
1282 CPPUNIT_FAIL("Wrong formula in D15");
1287 void ScExportTest::testSheetProtectionXLSX()
1289 ScDocShellRef xShell
= loadDoc("ProtecteSheet1234Pass.", XLSX
);
1290 CPPUNIT_ASSERT(xShell
.Is());
1292 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLSX
);
1293 CPPUNIT_ASSERT(xDocSh
.Is());
1295 ScDocument
& rDoc
= xDocSh
->GetDocument();
1296 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(0);
1297 CPPUNIT_ASSERT(pTabProtect
);
1300 Sequence
<sal_Int8
> aHash
= pTabProtect
->getPasswordHash(PASSHASH_XL
);
1302 if (aHash
.getLength() >= 2)
1304 CPPUNIT_ASSERT( (sal_uInt8
)aHash
[0] == 204 );
1305 CPPUNIT_ASSERT( (sal_uInt8
)aHash
[1] == 61 );
1307 // we could flesh out this check I guess
1308 CPPUNIT_ASSERT ( !pTabProtect
->isOptionEnabled( ScTableProtection::OBJECTS
) );
1309 CPPUNIT_ASSERT ( !pTabProtect
->isOptionEnabled( ScTableProtection::SCENARIOS
) );
1316 const char* toBorderName( sal_Int16 eStyle
)
1320 case table::BorderLineStyle::SOLID
: return "SOLID";
1321 case table::BorderLineStyle::DOTTED
: return "DOTTED";
1322 case table::BorderLineStyle::DASHED
: return "DASHED";
1323 case table::BorderLineStyle::DASH_DOT
: return "DASH_DOT";
1324 case table::BorderLineStyle::DASH_DOT_DOT
: return "DASH_DOT_DOT";
1325 case table::BorderLineStyle::DOUBLE_THIN
: return "DOUBLE_THIN";
1326 case table::BorderLineStyle::FINE_DASHED
: return "FINE_DASHED";
1336 void ScExportTest::testExcelCellBorders( sal_uLong nFormatType
)
1344 { 1, table::BorderLineStyle::SOLID
, 1L }, // hair
1345 { 3, table::BorderLineStyle::DOTTED
, 15L }, // dotted
1346 { 5, table::BorderLineStyle::DASH_DOT_DOT
, 15L }, // dash dot dot
1347 { 7, table::BorderLineStyle::DASH_DOT
, 15L }, // dash dot
1348 { 9, table::BorderLineStyle::FINE_DASHED
, 15L }, // dashed
1349 { 11, table::BorderLineStyle::SOLID
, 15L }, // thin
1350 { 13, table::BorderLineStyle::DASH_DOT_DOT
, 35L }, // medium dash dot dot
1351 { 17, table::BorderLineStyle::DASH_DOT
, 35L }, // medium dash dot
1352 { 19, table::BorderLineStyle::DASHED
, 35L }, // medium dashed
1353 { 21, table::BorderLineStyle::SOLID
, 35L }, // medium
1354 { 23, table::BorderLineStyle::SOLID
, 50L }, // thick
1355 { 25, table::BorderLineStyle::DOUBLE_THIN
, -1L }, // double (don't check width)
1358 ScDocShellRef xDocSh
= loadDoc("cell-borders.", nFormatType
);
1359 CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh
.Is());
1361 ScDocument
& rDoc
= xDocSh
->GetDocument();
1363 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aChecks
); ++i
)
1365 const editeng::SvxBorderLine
* pLine
= NULL
;
1366 rDoc
.GetBorderLines(2, aChecks
[i
].mnRow
, 0, NULL
, &pLine
, NULL
, NULL
);
1367 CPPUNIT_ASSERT(pLine
);
1368 CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks
[i
].mnStyle
), toBorderName(pLine
->GetBorderLineStyle()));
1369 if (aChecks
[i
].mnWidth
>= 0)
1370 CPPUNIT_ASSERT_EQUAL(aChecks
[i
].mnWidth
, pLine
->GetWidth());
1374 ScDocShellRef xNewDocSh
= saveAndReload(xDocSh
, nFormatType
);
1376 ScDocument
& rDoc
= xNewDocSh
->GetDocument();
1377 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aChecks
); ++i
)
1379 const editeng::SvxBorderLine
* pLine
= NULL
;
1380 rDoc
.GetBorderLines(2, aChecks
[i
].mnRow
, 0, NULL
, &pLine
, NULL
, NULL
);
1381 CPPUNIT_ASSERT(pLine
);
1382 CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks
[i
].mnStyle
), toBorderName(pLine
->GetBorderLineStyle()));
1383 if (aChecks
[i
].mnWidth
>= 0)
1384 CPPUNIT_ASSERT_EQUAL(aChecks
[i
].mnWidth
, pLine
->GetWidth());
1387 xNewDocSh
->DoClose();
1390 void ScExportTest::testCellBordersXLS()
1392 testExcelCellBorders(XLS
);
1395 void ScExportTest::testCellBordersXLSX()
1397 testExcelCellBorders(XLSX
);
1400 OUString
toString( const ScBigRange
& rRange
)
1402 OUStringBuffer aBuf
;
1403 aBuf
.appendAscii("(columns:");
1404 aBuf
.append(rRange
.aStart
.Col());
1406 aBuf
.append(rRange
.aEnd
.Col());
1407 aBuf
.appendAscii(";rows:");
1408 aBuf
.append(rRange
.aStart
.Row());
1410 aBuf
.append(rRange
.aEnd
.Row());
1411 aBuf
.appendAscii(";sheets:");
1412 aBuf
.append(rRange
.aStart
.Tab());
1414 aBuf
.append(rRange
.aEnd
.Tab());
1417 return aBuf
.makeStringAndClear();
1420 void ScExportTest::testTrackChangesSimpleXLSX()
1424 sal_uLong mnActionId
;
1425 ScChangeActionType meType
;
1427 sal_Int32 mnStartCol
;
1428 sal_Int32 mnStartRow
;
1429 sal_Int32 mnStartTab
;
1434 bool mbRowInsertedAtBottom
;
1439 bool checkRange( ScChangeActionType eType
, const ScBigRange
& rExpected
, const ScBigRange
& rActual
)
1441 ScBigRange
aExpected(rExpected
), aActual(rActual
);
1445 case SC_CAT_INSERT_ROWS
:
1448 aExpected
.aStart
.SetCol(0);
1449 aExpected
.aEnd
.SetCol(0);
1450 aActual
.aStart
.SetCol(0);
1451 aActual
.aEnd
.SetCol(0);
1458 return aExpected
== aActual
;
1461 bool check( ScDocument
& rDoc
)
1463 CheckItem aChecks
[] =
1465 { 1, SC_CAT_CONTENT
, 1, 1, 0, 1, 1, 0, false },
1466 { 2, SC_CAT_INSERT_ROWS
, 0, 2, 0, 0, 2, 0, true },
1467 { 3, SC_CAT_CONTENT
, 1, 2, 0, 1, 2, 0, false },
1468 { 4, SC_CAT_INSERT_ROWS
, 0, 3, 0, 0, 3, 0, true },
1469 { 5, SC_CAT_CONTENT
, 1, 3, 0, 1, 3, 0, false },
1470 { 6, SC_CAT_INSERT_ROWS
, 0, 4, 0, 0, 4, 0, true },
1471 { 7, SC_CAT_CONTENT
, 1, 4, 0, 1, 4, 0, false },
1472 { 8, SC_CAT_INSERT_ROWS
, 0, 5, 0, 0, 5, 0, true },
1473 { 9, SC_CAT_CONTENT
, 1, 5, 0, 1, 5, 0, false },
1474 { 10, SC_CAT_INSERT_ROWS
, 0, 6, 0, 0, 6, 0, true },
1475 { 11, SC_CAT_CONTENT
, 1, 6, 0, 1, 6, 0, false },
1476 { 12, SC_CAT_INSERT_ROWS
, 0, 7, 0, 0, 7, 0, true },
1477 { 13, SC_CAT_CONTENT
, 1, 7, 0, 1, 7, 0, false },
1480 ScChangeTrack
* pCT
= rDoc
.GetChangeTrack();
1483 cerr
<< "Change track instance doesn't exist." << endl
;
1487 sal_uLong nActionMax
= pCT
->GetActionMax();
1488 if (nActionMax
!= 13)
1490 cerr
<< "Unexpected highest action ID value." << endl
;
1494 for (size_t i
= 0, n
= SAL_N_ELEMENTS(aChecks
); i
< n
; ++i
)
1496 sal_uInt16 nActId
= aChecks
[i
].mnActionId
;
1497 const ScChangeAction
* pAction
= pCT
->GetAction(nActId
);
1500 cerr
<< "No action for action number " << nActId
<< " found." << endl
;
1504 if (pAction
->GetType() != aChecks
[i
].meType
)
1506 cerr
<< "Unexpected action type for action number " << nActId
<< "." << endl
;
1510 const ScBigRange
& rRange
= pAction
->GetBigRange();
1511 ScBigRange
aCheck(aChecks
[i
].mnStartCol
, aChecks
[i
].mnStartRow
, aChecks
[i
].mnStartTab
,
1512 aChecks
[i
].mnEndCol
, aChecks
[i
].mnEndRow
, aChecks
[i
].mnEndTab
);
1514 if (!checkRange(pAction
->GetType(), aCheck
, rRange
))
1516 cerr
<< "Unexpected range for action number " << nActId
1517 << ": expected=" << toString(aCheck
) << " actual=" << toString(rRange
) << endl
;
1521 switch (pAction
->GetType())
1523 case SC_CAT_INSERT_ROWS
:
1525 const ScChangeActionIns
* p
= static_cast<const ScChangeActionIns
*>(pAction
);
1526 if (p
->IsEndOfList() != aChecks
[i
].mbRowInsertedAtBottom
)
1528 cerr
<< "Unexpected end-of-list flag for action number " << nActId
<< "." << endl
;
1541 bool checkRevisionUserAndTime( ScDocument
& rDoc
, const OUString
& rOwnerName
)
1543 ScChangeTrack
* pCT
= rDoc
.GetChangeTrack();
1546 cerr
<< "Change track instance doesn't exist." << endl
;
1550 ScChangeAction
* pAction
= pCT
->GetLast();
1551 if (pAction
->GetUser() != "Kohei Yoshida")
1553 cerr
<< "Wrong user name." << endl
;
1557 DateTime aDT
= pAction
->GetDateTime();
1558 if (aDT
.GetYear() != 2014 || aDT
.GetMonth() != 7 || aDT
.GetDay() != 11)
1560 cerr
<< "Wrong time stamp." << endl
;
1564 // Insert a new record to make sure the user and date-time are correct.
1565 rDoc
.SetString(ScAddress(1,8,0), "New String");
1567 pCT
->AppendContent(ScAddress(1,8,0), aEmpty
);
1568 pAction
= pCT
->GetLast();
1571 cerr
<< "Failed to retrieve last revision." << endl
;
1575 if (rOwnerName
!= pAction
->GetUser())
1577 cerr
<< "Wrong user name." << endl
;
1581 DateTime aDTNew
= pAction
->GetDateTime();
1584 cerr
<< "Time stamp of the new revision should be more recent than that of the last revision." << endl
;
1593 SvtUserOptions
& rUserOpt
= SC_MOD()->GetUserOptions();
1594 rUserOpt
.SetToken(UserOptToken::FirstName
, "Export");
1595 rUserOpt
.SetToken(UserOptToken::LastName
, "Test");
1597 OUString aOwnerName
= rUserOpt
.GetFirstName() + " " + rUserOpt
.GetLastName();
1599 // First, test the xls variant.
1601 ScDocShellRef xDocSh
= loadDoc("track-changes/simple-cell-changes.", XLS
);
1602 CPPUNIT_ASSERT(xDocSh
.Is());
1603 ScDocument
* pDoc
= &xDocSh
->GetDocument();
1604 bool bGood
= aTest
.check(*pDoc
);
1605 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xls).", bGood
);
1607 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLS
);
1609 pDoc
= &xDocSh2
->GetDocument();
1610 bGood
= aTest
.check(*pDoc
);
1611 CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xls).", bGood
);
1613 // fdo#81445 : Check the blank value string to make sure it's "<empty>".
1614 ScChangeTrack
* pCT
= pDoc
->GetChangeTrack();
1615 CPPUNIT_ASSERT(pCT
);
1616 ScChangeAction
* pAction
= pCT
->GetAction(1);
1617 CPPUNIT_ASSERT(pAction
);
1619 pAction
->GetDescription(aDesc
, pDoc
);
1620 CPPUNIT_ASSERT_EQUAL(OUString("Cell B2 changed from '<empty>' to '1'"), aDesc
);
1622 bGood
= aTest
.checkRevisionUserAndTime(*pDoc
, aOwnerName
);
1623 CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xls).", bGood
);
1627 // Now, test the xlsx variant the same way.
1629 xDocSh
= loadDoc("track-changes/simple-cell-changes.", XLSX
);
1630 CPPUNIT_ASSERT(xDocSh
.Is());
1631 pDoc
= &xDocSh
->GetDocument();
1633 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xlsx).", bGood
);
1635 xDocSh2
= saveAndReload(xDocSh
, XLSX
);
1637 pDoc
= &xDocSh2
->GetDocument();
1638 bGood
= aTest
.check(*pDoc
);
1639 CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xlsx).", bGood
);
1641 bGood
= aTest
.checkRevisionUserAndTime(*pDoc
, aOwnerName
);
1642 CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xlsx).", bGood
);
1647 void ScExportTest::testSheetTabColorsXLSX()
1651 bool checkContent( ScDocument
& rDoc
)
1654 std::vector
<OUString
> aTabNames
= rDoc
.GetAllTableNames();
1656 // green, red, blue, yellow (from left to right).
1657 if (aTabNames
.size() != 4)
1659 cerr
<< "There should be exactly 4 sheets." << endl
;
1663 const char* pNames
[] = { "Green", "Red", "Blue", "Yellow" };
1664 for (size_t i
= 0, n
= SAL_N_ELEMENTS(pNames
); i
< n
; ++i
)
1666 OUString aExpected
= OUString::createFromAscii(pNames
[i
]);
1667 if (aExpected
!= aTabNames
[i
])
1669 cerr
<< "incorrect sheet name: expected='" << aExpected
<<"', actual='" << aTabNames
[i
] << "'" << endl
;
1674 const ColorData aXclColors
[] =
1676 0x0000B050, // green
1679 0x00FFFF00, // yellow
1682 for (size_t i
= 0, n
= SAL_N_ELEMENTS(aXclColors
); i
< n
; ++i
)
1684 if (aXclColors
[i
] != rDoc
.GetTabBgColor(i
).GetColor())
1686 cerr
<< "wrong sheet color for sheet " << i
<< endl
;
1696 ScDocShellRef xDocSh
= loadDoc("sheet-tab-color.", XLSX
);
1698 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh
.Is());
1699 ScDocument
& rDoc
= xDocSh
->GetDocument();
1700 bool bRes
= aTest
.checkContent(rDoc
);
1701 CPPUNIT_ASSERT_MESSAGE("Failed on the initial content check.", bRes
);
1704 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLSX
);
1705 CPPUNIT_ASSERT_MESSAGE("Failed to reload file.", xDocSh2
.Is());
1707 ScDocument
& rDoc
= xDocSh2
->GetDocument();
1708 bool bRes
= aTest
.checkContent(rDoc
);
1709 CPPUNIT_ASSERT_MESSAGE("Failed on the content check after reload.", bRes
);
1714 void ScExportTest::testSharedFormulaExportXLS()
1718 bool checkContent( ScDocument
& rDoc
)
1720 formula::FormulaGrammar::Grammar eGram
= formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1
;
1721 rDoc
.SetGrammar(eGram
);
1722 sc::TokenStringContext
aCxt(&rDoc
, eGram
);
1724 // Check the title row.
1726 OUString aActual
= rDoc
.GetString(0,1,0);
1727 OUString aExpected
= "Response";
1728 if (aActual
!= aExpected
)
1730 cerr
<< "Wrong content in A2: expected='" << aExpected
<< "', actual='" << aActual
<< "'" << endl
;
1734 aActual
= rDoc
.GetString(1,1,0);
1735 aExpected
= "Response";
1736 if (aActual
!= aExpected
)
1738 cerr
<< "Wrong content in B2: expected='" << aExpected
<< "', actual='" << aActual
<< "'" << endl
;
1742 // A3:A12 and B3:B12 are numbers from 1 to 10.
1743 for (SCROW i
= 0; i
<= 9; ++i
)
1745 double fExpected
= i
+ 1.0;
1746 ScAddress
aPos(0,i
+2,0);
1747 double fActual
= rDoc
.GetValue(aPos
);
1748 if (fExpected
!= fActual
)
1750 cerr
<< "Wrong value in A" << (i
+2) << ": expected=" << fExpected
<< ", actual=" << fActual
<< endl
;
1755 ScFormulaCell
* pFC
= rDoc
.GetFormulaCell(aPos
);
1758 cerr
<< "B" << (i
+2) << " should be a formula cell." << endl
;
1762 OUString aFormula
= pFC
->GetCode()->CreateString(aCxt
, aPos
);
1763 aExpected
= "Coefficients!RC[-1]";
1764 if (aFormula
!= aExpected
)
1766 cerr
<< "Wrong formula in B" << (i
+2) << ": expected='" << aExpected
<< "', actual='" << aFormula
<< "'" << endl
;
1770 fActual
= rDoc
.GetValue(aPos
);
1771 if (fExpected
!= fActual
)
1773 cerr
<< "Wrong value in B" << (i
+2) << ": expected=" << fExpected
<< ", actual=" << fActual
<< endl
;
1783 ScDocShellRef xDocSh
= loadDoc("shared-formula/3d-reference.", ODS
);
1785 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh
.Is());
1786 ScDocument
& rDoc
= xDocSh
->GetDocument();
1788 // Check the content of the original.
1789 bool bRes
= aTest
.checkContent(rDoc
);
1790 CPPUNIT_ASSERT_MESSAGE("Content check on the original document failed.", bRes
);
1793 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLS
);
1795 CPPUNIT_ASSERT_MESSAGE("Failed to reload file.", xDocSh2
.Is());
1797 ScDocument
& rDoc
= xDocSh2
->GetDocument();
1799 // Check the content of the reloaded. This should be identical.
1800 bool bRes
= aTest
.checkContent(rDoc
);
1801 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes
);
1806 void ScExportTest::testSharedFormulaExportXLSX()
1810 bool checkContent( ScDocument
& rDoc
)
1812 SCTAB nTabCount
= rDoc
.GetTableCount();
1815 cerr
<< "Document should have exactly 2 sheets. " << nTabCount
<< " found." << endl
;
1819 // Make sure the sheet tab colors are not set.
1820 for (SCROW i
= 0; i
<= 1; ++i
)
1822 Color aTabBgColor
= rDoc
.GetTabBgColor(i
);
1823 if (aTabBgColor
!= Color(COL_AUTO
))
1825 cerr
<< "The tab color of Sheet " << (i
+1) << " should not be explicitly set." << endl
;
1830 // B2:B7 should show 1,2,3,4,5,6.
1831 double fExpected
= 1.0;
1832 for (SCROW i
= 1; i
<= 6; ++i
, ++fExpected
)
1834 ScAddress
aPos(1,i
,0);
1835 double fVal
= rDoc
.GetValue(aPos
);
1836 if (fVal
!= fExpected
)
1838 cerr
<< "Wrong value in B" << (i
+1) << ": expected=" << fExpected
<< ", actual=" << fVal
<< endl
;
1843 // C2:C7 should show 10,20,....,60.
1845 for (SCROW i
= 1; i
<= 6; ++i
, fExpected
+=10.0)
1847 ScAddress
aPos(2,i
,0);
1848 double fVal
= rDoc
.GetValue(aPos
);
1849 if (fVal
!= fExpected
)
1851 cerr
<< "Wrong value in C" << (i
+1) << ": expected=" << fExpected
<< ", actual=" << fVal
<< endl
;
1856 // D2:D7 should show 1,2,...,6.
1858 for (SCROW i
= 1; i
<= 6; ++i
, ++fExpected
)
1860 ScAddress
aPos(3,i
,0);
1861 double fVal
= rDoc
.GetValue(aPos
);
1862 if (fVal
!= fExpected
)
1864 cerr
<< "Wrong value in D" << (i
+1) << ": expected=" << fExpected
<< ", actual=" << fVal
<< endl
;
1874 ScDocShellRef xDocSh
= loadDoc("shared-formula/3d-reference.", XLSX
);
1876 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh
.Is());
1877 ScDocument
& rDoc
= xDocSh
->GetDocument();
1879 bool bRes
= aTest
.checkContent(rDoc
);
1880 CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes
);
1882 rDoc
.CalcAll(); // Recalculate to flush all cached results.
1883 bRes
= aTest
.checkContent(rDoc
);
1884 CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes
);
1887 // Save and reload, and check the content again.
1888 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLSX
);
1891 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh2
.Is());
1892 ScDocument
& rDoc
= xDocSh2
->GetDocument();
1893 rDoc
.CalcAll(); // Recalculate to flush all cached results.
1895 bool bRes
= aTest
.checkContent(rDoc
);
1896 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes
);
1901 void ScExportTest::testSharedFormulaStringResultExportXLSX()
1905 bool checkContent( ScDocument
& rDoc
)
1908 // B2:B7 should show A,B,....,F.
1909 const char* expected
[] = { "A", "B", "C", "D", "E", "F" };
1910 for (SCROW i
= 0; i
<= 5; ++i
)
1912 ScAddress
aPos(1,i
+1,0);
1913 OUString aStr
= rDoc
.GetString(aPos
);
1914 OUString aExpected
= OUString::createFromAscii(expected
[i
]);
1915 if (aStr
!= aExpected
)
1917 cerr
<< "Wrong value in B" << (i
+2) << ": expected='" << aExpected
<< "', actual='" << aStr
<< "'" << endl
;
1924 // C2:C7 should show AA,BB,....,FF.
1925 const char* expected
[] = { "AA", "BB", "CC", "DD", "EE", "FF" };
1926 for (SCROW i
= 0; i
<= 5; ++i
)
1928 ScAddress
aPos(2,i
+1,0);
1929 OUString aStr
= rDoc
.GetString(aPos
);
1930 OUString aExpected
= OUString::createFromAscii(expected
[i
]);
1931 if (aStr
!= aExpected
)
1933 cerr
<< "Wrong value in C" << (i
+2) << ": expected='" << aExpected
<< "', actual='" << aStr
<< "'" << endl
;
1944 ScDocShellRef xDocSh
= loadDoc("shared-formula/text-results.", XLSX
);
1946 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh
.Is());
1947 ScDocument
& rDoc
= xDocSh
->GetDocument();
1949 // Check content without re-calculation, to test cached formula results.
1950 bool bRes
= aTest
.checkContent(rDoc
);
1951 CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes
);
1953 // Now, re-calculate and check the results.
1955 bRes
= aTest
.checkContent(rDoc
);
1956 CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes
);
1958 // Reload and check again.
1959 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLSX
);
1961 CPPUNIT_ASSERT_MESSAGE("Failed to re-load file.", xDocSh2
.Is());
1962 ScDocument
& rDoc
= xDocSh2
->GetDocument();
1964 bool bRes
= aTest
.checkContent(rDoc
);
1965 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes
);
1970 void ScExportTest::testFunctionsExcel2010( sal_uLong nFormatType
)
1972 ScDocShellRef xShell
= loadDoc("functions-excel-2010.", XLSX
);
1973 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xShell
.Is());
1975 ScDocShellRef xDocSh
= saveAndReload(xShell
, nFormatType
);
1976 ScDocument
& rDoc
= xDocSh
->GetDocument();
1977 rDoc
.CalcAll(); // perform hard re-calculation.
1979 testFunctionsExcel2010_Impl(rDoc
);
1984 void ScExportTest::testFunctionsExcel2010XLSX()
1986 testFunctionsExcel2010(XLSX
);
1989 void ScExportTest::testFunctionsExcel2010XLS()
1991 testFunctionsExcel2010(XLS
);
1994 void ScExportTest::testRelativePaths()
1996 ScDocShellRef xDocSh
= loadDoc("fdo79305.", ODS
);
1997 CPPUNIT_ASSERT(xDocSh
.Is());
1999 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "content.xml", ODS
);
2000 CPPUNIT_ASSERT(pDoc
);
2001 OUString aURL
= getXPath(pDoc
,
2002 "/office:document-content/office:body/office:spreadsheet/table:table/table:table-row[2]/table:table-cell[2]/text:p/text:a", "href");
2003 // make sure that the URL is relative
2004 CPPUNIT_ASSERT(aURL
.startsWith(".."));
2009 void testSheetProtection_Impl(ScDocument
& rDoc
)
2011 CPPUNIT_ASSERT(rDoc
.IsTabProtected(0));
2012 ScTableProtection
* pTabProtection
= rDoc
.GetTabProtection(0);
2013 CPPUNIT_ASSERT(pTabProtection
);
2014 CPPUNIT_ASSERT(pTabProtection
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
));
2015 CPPUNIT_ASSERT(!pTabProtection
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
));
2020 void ScExportTest::testSheetProtection()
2022 ScDocShellRef xDocSh
= loadDoc("sheet-protection.", ODS
);
2023 CPPUNIT_ASSERT(xDocSh
.Is());
2026 ScDocument
& rDoc
= xDocSh
->GetDocument();
2027 testSheetProtection_Impl(rDoc
);
2030 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, ODS
);
2032 ScDocument
& rDoc
= xDocSh2
->GetDocument();
2033 testSheetProtection_Impl(rDoc
);
2039 void ScExportTest::testPivotTableXLSX()
2043 bool check( const ScDocument
& rDoc
)
2045 if (!rDoc
.HasPivotTable())
2047 cerr
<< "The document should have pivot table." << endl
;
2051 const ScDPCollection
* pDPs
= rDoc
.GetDPCollection();
2054 cerr
<< "Pivot table container should exist." << endl
;
2058 ScRange
aSrcRange(0,0,0,9,2,0); // A1:J3 on Sheet1.
2059 const ScDPCache
* pCache
= pDPs
->GetSheetCaches().getExistingCache(aSrcRange
);
2062 cerr
<< "The document should have a pivot cache for A1:J3 on Sheet1." << endl
;
2066 // Cache should have fields from F1 through F10.
2068 const char* pNames
[] = {
2069 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"
2072 size_t nCount
= pCache
->GetFieldCount();
2073 if (nCount
!= SAL_N_ELEMENTS(pNames
))
2075 cout
<< "Incorrect number of fields in pivot cache." << endl
;
2079 for (size_t i
= 0; i
< nCount
; ++i
)
2081 OUString aCacheName
= pCache
->GetDimensionName(i
);
2082 if (aCacheName
!= OUString::createFromAscii(pNames
[i
]))
2084 cerr
<< "Field " << i
<< " has label '" << aCacheName
<< "' but expected '" << pNames
[i
] << "'" << endl
;
2089 const ScDPObject
* pDPObj
= rDoc
.GetDPAtCursor(0,10,0); // A11
2092 cerr
<< "A pivot table should exist over A11." << endl
;
2096 // Output range should be A8:D15.
2097 ScRange aOutRange
= pDPObj
->GetOutRange();
2098 if (ScRange(0,7,0,3,14,0) != aOutRange
)
2100 cerr
<< "Incorrect output range." << endl
;
2105 // Column field - F4
2106 // Page fields - F7 and F6
2109 const ScDPSaveData
* pSaveData
= pDPObj
->GetSaveData();
2112 cerr
<< "Save data should exist in each pivot table object." << endl
;
2116 std::vector
<const ScDPSaveDimension
*> aDims
;
2117 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW
, aDims
);
2118 if (aDims
.size() != 1 || aDims
[0]->GetName() != "F1")
2120 cerr
<< "Pivot table should have one row field labeld 'F1'" << endl
;
2124 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN
, aDims
);
2125 if (aDims
.size() != 1 || aDims
[0]->GetName() != "F4")
2127 cerr
<< "Pivot table should have one column field labeld 'F4'" << endl
;
2131 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE
, aDims
);
2132 if (aDims
.size() != 2 || aDims
[0]->GetName() != "F7" || aDims
[1]->GetName() != "F6")
2134 cerr
<< "Pivot table should have two page fields labeld 'F7' and 'F6' in this order." << endl
;
2138 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA
, aDims
);
2139 if (aDims
.size() != 1 || aDims
[0]->GetName() != "F10")
2141 cerr
<< "Pivot table should have one data field labeld 'F10'" << endl
;
2145 const ScDPSaveDimension
* pDim
= aDims
[0];
2146 if (pDim
->GetFunction() != sheet::GeneralFunction_SUM
)
2148 cerr
<< "Data field should have SUM function." << endl
;
2157 ScDocShellRef xDocSh
= loadDoc("pivot-table/many-fields-in-cache.", XLSX
);
2158 CPPUNIT_ASSERT(xDocSh
.Is());
2159 ScDocument
* pDoc
= &xDocSh
->GetDocument();
2162 bool bCheck
= aTest
.check(*pDoc
);
2163 CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bCheck
);
2165 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLSX
);
2167 CPPUNIT_ASSERT(xDocSh2
.Is());
2168 pDoc
= &xDocSh2
->GetDocument();
2171 bCheck
= aTest
.check(*pDoc
);
2172 CPPUNIT_ASSERT_MESSAGE("Reload check failed.", bCheck
);
2177 void ScExportTest::testPivotTableTwoDataFieldsXLSX()
2181 bool check( const ScDocument
& rDoc
)
2183 if (!rDoc
.HasPivotTable())
2185 cerr
<< "The document should have pivot table." << endl
;
2189 const ScDPCollection
* pDPs
= rDoc
.GetDPCollection();
2192 cerr
<< "Pivot table container should exist." << endl
;
2196 ScRange
aSrcRange(1,1,1,2,8,1); // B2:C9 on the 2nd sheet.
2197 const ScDPCache
* pCache
= pDPs
->GetSheetCaches().getExistingCache(aSrcRange
);
2200 cerr
<< "The document should have a pivot cache for B2:C9 on 'Src'." << endl
;
2204 const char* pNames
[] = { "Name", "Value" };
2207 size_t nCount
= pCache
->GetFieldCount();
2208 if (nCount
!= SAL_N_ELEMENTS(pNames
))
2210 cout
<< "Incorrect number of fields in pivot cache." << endl
;
2214 const ScDPObject
* pDPObj
= rDoc
.GetDPAtCursor(0,2,0); // A3
2217 cerr
<< "A pivot table should exist over A3." << endl
;
2221 // Output range should be A3:C12.
2222 ScRange aOutRange
= pDPObj
->GetOutRange();
2223 if (ScRange(0,2,0,2,11,0) != aOutRange
)
2225 cerr
<< "Incorrect output range." << endl
;
2229 const ScDPSaveData
* pSaveData
= pDPObj
->GetSaveData();
2232 cerr
<< "Save data should exist in each pivot table object." << endl
;
2236 std::vector
<const ScDPSaveDimension
*> aDims
;
2237 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW
, aDims
);
2238 if (aDims
.size() != 1 || aDims
[0]->GetName() != "Name")
2240 cerr
<< "Pivot table should have one row field labeld 'Name'" << endl
;
2244 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA
, aDims
);
2245 if (aDims
.size() != 2 ||
2246 ScDPUtil::getSourceDimensionName(aDims
[0]->GetName()) != "Value" ||
2247 ScDPUtil::getSourceDimensionName(aDims
[1]->GetName()) != "Value")
2249 cerr
<< "Pivot table should have two duplicated data fields both of which are named 'Value'." << endl
;
2253 if (aDims
[0]->GetFunction() != sheet::GeneralFunction_SUM
)
2255 cerr
<< "First data field should be SUM." << endl
;
2259 if (aDims
[1]->GetFunction() != sheet::GeneralFunction_COUNT
)
2261 cerr
<< "First data field should be COUNT." << endl
;
2265 pSaveData
->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN
, aDims
);
2266 if (aDims
.size() != 1 || !aDims
[0]->IsDataLayout())
2268 cerr
<< "Pivot table should have one column field which is a data layout field." << endl
;
2277 ScDocShellRef xDocSh
= loadDoc("pivot-table/two-data-fields.", XLSX
);
2278 CPPUNIT_ASSERT(xDocSh
.Is());
2279 ScDocument
* pDoc
= &xDocSh
->GetDocument();
2282 bool bCheck
= aTest
.check(*pDoc
);
2283 CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bCheck
);
2285 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLSX
);
2287 CPPUNIT_ASSERT(xDocSh2
.Is());
2288 pDoc
= &xDocSh2
->GetDocument();
2291 bCheck
= aTest
.check(*pDoc
);
2292 CPPUNIT_ASSERT_MESSAGE("Reload check failed.", bCheck
);
2297 void ScExportTest::testFunctionsExcel2010ODS()
2299 //testFunctionsExcel2010(ODS);
2302 void ScExportTest::testSwappedOutImageExport()
2304 const char* aFilterNames
[] = {
2307 "Calc Office Open XML",
2311 // Set cache size to a very small value to make sure one of the images is swapped out
2312 std::shared_ptr
< comphelper::ConfigurationChanges
> xBatch(comphelper::ConfigurationChanges::create());
2313 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), xBatch
);
2316 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
2318 // Check whether the export code swaps in the image which was swapped out before.
2319 ScDocShellRef xDocSh
= loadDoc("document_with_two_images.", ODS
);
2321 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
2322 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xDocSh
.Is());
2324 // Export the document and import again for a check
2325 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, nFilter
);
2328 // Check whether graphic exported well after it was swapped out
2329 uno::Reference
< frame::XModel
> xModel
= xDocSh2
->GetModel();
2330 uno::Reference
< sheet::XSpreadsheetDocument
> xDoc(xModel
, UNO_QUERY_THROW
);
2331 uno::Reference
< container::XIndexAccess
> xIA(xDoc
->getSheets(), UNO_QUERY_THROW
);
2332 uno::Reference
< drawing::XDrawPageSupplier
> xDrawPageSupplier( xIA
->getByIndex(0), UNO_QUERY_THROW
);
2333 uno::Reference
< container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(), UNO_QUERY_THROW
);
2334 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2), xDraws
->getCount());
2336 uno::Reference
<drawing::XShape
> xImage(xDraws
->getByIndex(0), uno::UNO_QUERY
);
2337 uno::Reference
< beans::XPropertySet
> XPropSet( xImage
, uno::UNO_QUERY_THROW
);
2341 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
2342 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
2346 uno::Reference
<graphic::XGraphic
> xGraphic
;
2347 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
2348 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
2349 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
2350 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(610), xBitmap
->getSize().Width
);
2351 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(381), xBitmap
->getSize().Height
);
2354 xImage
.set(xDraws
->getByIndex(1), uno::UNO_QUERY
);
2355 XPropSet
.set( xImage
, uno::UNO_QUERY_THROW
);
2359 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
2360 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
2364 uno::Reference
<graphic::XGraphic
> xGraphic
;
2365 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
2366 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
2367 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
2368 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(900), xBitmap
->getSize().Width
);
2369 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(600), xBitmap
->getSize().Height
);
2375 ScExportTest::ScExportTest()
2376 : ScBootstrapFixture("/sc/qa/unit/data")
2380 void ScExportTest::setUp()
2382 test::BootstrapFixture::setUp();
2384 // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
2385 // which is a private symbol to us, gets called
2387 getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
2388 CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent
.is());
2391 void ScExportTest::tearDown()
2393 uno::Reference
< lang::XComponent
>( m_xCalcComponent
, UNO_QUERY_THROW
)->dispose();
2394 test::BootstrapFixture::tearDown();
2397 void ScExportTest::testSupBookVirtualPath()
2399 ScDocShellRef xShell
= loadDoc("external-ref.", XLS
);
2400 CPPUNIT_ASSERT(xShell
.Is());
2402 ScDocShellRef xDocSh
= saveAndReload(xShell
, XLS
);
2404 CPPUNIT_ASSERT(xDocSh
.Is());
2406 ScDocument
& rDoc
= xDocSh
->GetDocument();
2408 if (!checkFormula(rDoc
, ScAddress(0,0,0), "'file:///home/timar/Documents/external.xls'#$Sheet1.A1"))
2409 CPPUNIT_FAIL("Wrong SupBook VirtualPath URL");
2414 void ScExportTest::testLinkedGraphicRT()
2416 // Problem was with linked images
2417 const char* aFilterNames
[] = {
2420 "Calc Office Open XML",
2424 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
2426 // Load the original file with one image
2427 ScDocShellRef xDocSh
= loadDoc("document_with_linked_graphic.", ODS
);
2428 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
2430 // Export the document and import again for a check
2431 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, nFilter
);
2434 // Check whether graphic imported well after export
2435 ScDocument
& rDoc
= xDocSh
->GetDocument();
2436 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
2437 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), pDrawLayer
!= NULL
);
2438 const SdrPage
*pPage
= pDrawLayer
->GetPage(0);
2439 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), pPage
!= NULL
);
2440 SdrGrafObj
* pObject
= dynamic_cast<SdrGrafObj
*>(pPage
->GetObj(0));
2441 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), pObject
!= NULL
);
2442 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), pObject
->IsLinkedGraphic() );
2444 const GraphicObject
& rGraphicObj
= pObject
->GetGraphicObject(true);
2445 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), !rGraphicObj
.IsSwappedOut());
2446 CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage
.getStr(), GRAPHIC_BITMAP
, rGraphicObj
.GetGraphic().GetType());
2447 CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage
.getStr(), sal_uLong(864900), rGraphicObj
.GetSizeBytes());
2453 void ScExportTest::testImageWithSpecialID()
2455 const char* aFilterNames
[] = {
2458 "Calc Office Open XML",
2462 // Trigger swap out mechanism to test swapped state factor too.
2463 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
2464 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), batch
);
2467 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
2469 ScDocShellRef xDocSh
= loadDoc("images_with_special_IDs.", ODS
);
2471 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
2472 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xDocSh
.Is());
2474 // Export the document and import again for a check
2475 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, nFilter
);
2478 // Check whether graphic was exported well
2479 uno::Reference
< frame::XModel
> xModel
= xDocSh2
->GetModel();
2480 uno::Reference
< sheet::XSpreadsheetDocument
> xDoc(xModel
, UNO_QUERY_THROW
);
2481 uno::Reference
< container::XIndexAccess
> xIA(xDoc
->getSheets(), UNO_QUERY_THROW
);
2482 uno::Reference
< drawing::XDrawPageSupplier
> xDrawPageSupplier( xIA
->getByIndex(0), UNO_QUERY_THROW
);
2483 uno::Reference
< container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(), UNO_QUERY_THROW
);
2484 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2), xDraws
->getCount());
2486 uno::Reference
<drawing::XShape
> xImage(xDraws
->getByIndex(0), uno::UNO_QUERY
);
2487 uno::Reference
< beans::XPropertySet
> XPropSet( xImage
, uno::UNO_QUERY_THROW
);
2491 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
2492 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
2496 uno::Reference
<graphic::XGraphic
> xGraphic
;
2497 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
2498 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
2499 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
2500 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(610), xBitmap
->getSize().Width
);
2501 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(381), xBitmap
->getSize().Height
);
2504 xImage
.set(xDraws
->getByIndex(1), uno::UNO_QUERY
);
2505 XPropSet
.set( xImage
, uno::UNO_QUERY_THROW
);
2509 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
2510 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
2514 uno::Reference
<graphic::XGraphic
> xGraphic
;
2515 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
2516 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
2517 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
2518 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(900), xBitmap
->getSize().Width
);
2519 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(600), xBitmap
->getSize().Height
);
2525 void ScExportTest::testSheetLocalRangeNameXLS()
2527 ScDocShellRef xDocSh
= loadDoc("named-ranges-local.", XLS
);
2528 xDocSh
->DoHardRecalc(true);
2529 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
, XLS
);
2531 xDocSh2
->DoHardRecalc(true);
2533 ScDocument
& rDoc
= xDocSh2
->GetDocument();
2534 ScRangeName
* pRangeName
= rDoc
.GetRangeName(0);
2535 CPPUNIT_ASSERT(pRangeName
);
2536 CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName
->size());
2539 rDoc
.GetFormula(3, 11, 0, aFormula
);
2540 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula
);
2541 ASSERT_DOUBLES_EQUAL(14.0, rDoc
.GetValue(3, 11, 0));
2543 rDoc
.GetFormula(6, 4, 0, aFormula
);
2544 CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula
);
2549 void ScExportTest::testSheetTextBoxHyperlink()
2551 ScDocShellRef xShell
= loadDoc("textbox-hyperlink.", XLSX
);
2552 CPPUNIT_ASSERT(xShell
.Is());
2554 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), XLSX
);
2555 CPPUNIT_ASSERT(xDocSh
.Is());
2557 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/drawings/drawing1.xml", XLSX
);
2558 CPPUNIT_ASSERT(pDoc
);
2560 assertXPath(pDoc
, "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:nvSpPr[1]/xdr:cNvPr[1]/a:hlinkClick[1]", 1);
2565 void ScExportTest::testFontSize()
2567 ScDocShellRef xDocSh
= loadDoc("fontSize.", XLSX
);
2568 CPPUNIT_ASSERT(xDocSh
.Is());
2570 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/drawings/drawing1.xml", XLSX
);
2571 CPPUNIT_ASSERT(pDoc
);
2572 OUString fontSize
= getXPath(pDoc
,
2573 "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "sz");
2574 // make sure that the font size is 18
2575 CPPUNIT_ASSERT_EQUAL(OUString("1800"), fontSize
);
2578 void ScExportTest::testSheetCharacterKerningSpace()
2580 ScDocShellRef xShell
= loadDoc("textbox-CharKerningSpace.", XLSX
);
2581 CPPUNIT_ASSERT(xShell
.Is());
2583 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), XLSX
);
2584 CPPUNIT_ASSERT(xDocSh
.Is());
2586 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/drawings/drawing1.xml", XLSX
);
2587 CPPUNIT_ASSERT(pDoc
);
2589 OUString CharKerningSpace
= getXPath(pDoc
,
2590 "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]","spc");
2592 // make sure that the CharKerning is 1997.
2593 CPPUNIT_ASSERT_EQUAL(OUString("1997"), CharKerningSpace
);
2598 void ScExportTest::testSheetCondensedCharacterSpace()
2600 ScDocShellRef xShell
= loadDoc("textbox-CondensedCharacterSpace.", XLSX
);
2601 CPPUNIT_ASSERT(xShell
.Is());
2603 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), XLSX
);
2604 CPPUNIT_ASSERT(xDocSh
.Is());
2606 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/drawings/drawing1.xml", XLSX
);
2607 CPPUNIT_ASSERT(pDoc
);
2609 OUString CondensedCharSpace
= getXPath(pDoc
,
2610 "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]","spc");
2612 // make sure that the CondensedCharSpace is -996.
2613 CPPUNIT_ASSERT_EQUAL(OUString("-996"), CondensedCharSpace
);
2618 void ScExportTest::testTextUnderlineColor()
2621 ScDocShellRef xDocSh
= loadDoc("underlineColor.", XLSX
);
2622 CPPUNIT_ASSERT(xDocSh
.Is());
2624 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/drawings/drawing1.xml", XLSX
);
2625 CPPUNIT_ASSERT(pDoc
);
2626 OUString color
= getXPath(pDoc
,
2627 "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill/a:solidFill/a:srgbClr", "val");
2628 // make sure that the underline color is RED
2629 CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), color
);
2632 void ScExportTest::testSheetRunParagraphProperty()
2634 ScDocShellRef xShell
= loadDoc("TextColor.", XLSX
);
2635 CPPUNIT_ASSERT(xShell
.Is());
2637 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), XLSX
);
2638 CPPUNIT_ASSERT(xDocSh
.Is());
2640 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/sharedStrings.xml", XLSX
);
2641 CPPUNIT_ASSERT(pDoc
);
2643 assertXPath(pDoc
, "/x:sst/x:si/x:r[1]/x:rPr[1]", 1);
2648 void ScExportTest::testHiddenShape()
2650 ScDocShellRef xDocSh
= loadDoc("hiddenShape.", XLSX
);
2651 CPPUNIT_ASSERT(xDocSh
.Is());
2653 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/drawings/drawing1.xml", XLSX
);
2654 CPPUNIT_ASSERT(pDoc
);
2655 assertXPath(pDoc
, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:nvSpPr/xdr:cNvPr", "hidden", "1");
2658 void ScExportTest::testMoveCellAnchoredShapes()
2660 ScDocShellRef xDocSh
= loadDoc("move-cell-anchored-shapes.", ODS
);
2661 CPPUNIT_ASSERT_MESSAGE("Failed to load move-cell-anchored-shapes.ods", xDocSh
.Is());
2663 // There are two cell-anchored objects on the first sheet.
2664 ScDocument
& rDoc
= xDocSh
->GetDocument();
2666 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc
.GetTableCount() > 0);
2668 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
2669 SdrPage
* pPage
= pDrawLayer
->GetPage(0);
2670 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
2671 SdrObject
* pObj
= pPage
->GetObj(0);
2672 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
2674 // Check cell anchor state
2675 ScAnchorType oldType
= ScDrawLayer::GetAnchorType(*pObj
);
2676 CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType
== SCA_CELL
);
2679 ScDrawObjData
* pData
= ScDrawLayer::GetObjData(pObj
, false);
2680 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
2681 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData
->maLastRect
.IsEmpty());
2683 ScAddress aDataStart
= pData
->maStart
;
2684 ScAddress aDataEnd
= pData
->maEnd
;
2686 // Get non rotated anchor data
2687 ScDrawObjData
* pNData
= ScDrawLayer::GetNonRotatedObjData( pObj
);
2688 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
2689 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData
->maLastRect
.IsEmpty());
2691 ScAddress aNDataStart
= pNData
->maStart
;
2692 ScAddress aNDataEnd
= pNData
->maEnd
;
2693 CPPUNIT_ASSERT_EQUAL(aDataStart
, aNDataStart
);
2694 CPPUNIT_ASSERT_EQUAL(aDataEnd
, aNDataEnd
);
2697 rDoc
.InsertRow(ScRange( 0, aDataStart
.Row() - 1, 0, MAXCOL
, aDataStart
.Row(), 0));
2700 pData
= ScDrawLayer::GetObjData(pObj
, false);
2701 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
2702 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData
->maLastRect
.IsEmpty());
2704 // Get non rotated anchor data
2705 pNData
= ScDrawLayer::GetNonRotatedObjData( pObj
);
2706 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
2707 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData
->maLastRect
.IsEmpty());
2709 // Check if data has moved to new rows
2710 CPPUNIT_ASSERT_EQUAL( pData
->maStart
.Row(), aDataStart
.Row() + 2 );
2711 CPPUNIT_ASSERT_EQUAL( pData
->maEnd
.Row(), aDataEnd
.Row() + 2 );
2713 CPPUNIT_ASSERT_EQUAL( pNData
->maStart
.Row(), aNDataStart
.Row() + 2 );
2714 CPPUNIT_ASSERT_EQUAL( pNData
->maEnd
.Row(), aNDataEnd
.Row() + 2 );
2716 // Save the anchor data
2717 aDataStart
= pData
->maStart
;
2718 aDataEnd
= pData
->maEnd
;
2719 aNDataStart
= pNData
->maStart
;
2720 aNDataEnd
= pNData
->maEnd
;
2722 // Save the document and load again to check anchor persist
2723 ScDocShellRef xDocSh1
= saveAndReload(&(*xDocSh
), ODS
);
2725 // There are two cell-anchored objects on the first sheet.
2726 ScDocument
& rDoc1
= xDocSh1
->GetDocument();
2728 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc1
.GetTableCount() > 0);
2730 pDrawLayer
= rDoc1
.GetDrawLayer();
2731 pPage
= pDrawLayer
->GetPage(0);
2732 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
2733 pObj
= pPage
->GetObj(0);
2734 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
2736 // Check cell anchor state
2737 oldType
= ScDrawLayer::GetAnchorType(*pObj
);
2738 CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType
== SCA_CELL
);
2741 pData
= ScDrawLayer::GetObjData(pObj
, false);
2742 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
2743 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData
->maLastRect
.IsEmpty());
2745 // Get non rotated anchor data
2746 pNData
= ScDrawLayer::GetNonRotatedObjData( pObj
);
2747 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
2748 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData
->maLastRect
.IsEmpty());
2750 // Check if data after save it
2751 CPPUNIT_ASSERT_EQUAL(pData
->maStart
, aDataStart
);
2752 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
, aDataEnd
);
2754 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
, aNDataStart
);
2755 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
, aNDataEnd
);
2758 rDoc1
.InsertCol(ScRange( aDataStart
.Col(), 0 , 0 , aDataStart
.Col(), MAXROW
, 0 ));
2761 pData
= ScDrawLayer::GetObjData(pObj
, false);
2762 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
2763 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData
->maLastRect
.IsEmpty());
2765 // Get non rotated anchor data
2766 pNData
= ScDrawLayer::GetNonRotatedObjData( pObj
);
2767 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
2768 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData
->maLastRect
.IsEmpty());
2770 // Check if data has moved to new rows
2771 CPPUNIT_ASSERT_EQUAL(pData
->maStart
.Col(), SCCOL(aDataStart
.Col() + 1));
2772 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
.Col() , SCCOL(aDataEnd
.Col() + 1));
2774 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
.Col(), SCCOL(aNDataStart
.Col() + 1));
2775 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
.Col() , SCCOL(aNDataEnd
.Col() + 1));
2777 // Save the anchor data
2778 aDataStart
= pData
->maStart
;
2779 aDataEnd
= pData
->maEnd
;
2780 aNDataStart
= pNData
->maStart
;
2781 aNDataEnd
= pNData
->maEnd
;
2783 // Save the document and load again to check anchor persist
2784 ScDocShellRef xDocSh2
= saveAndReload(&(*xDocSh1
), ODS
);
2786 // There are two cell-anchored objects on the first sheet.
2787 ScDocument
& rDoc2
= xDocSh2
->GetDocument();
2789 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc2
.GetTableCount() > 0);
2791 pDrawLayer
= rDoc2
.GetDrawLayer();
2792 pPage
= pDrawLayer
->GetPage(0);
2793 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
2794 pObj
= pPage
->GetObj(0);
2795 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
2797 // Check cell anchor state
2798 oldType
= ScDrawLayer::GetAnchorType(*pObj
);
2799 CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType
== SCA_CELL
);
2802 pData
= ScDrawLayer::GetObjData(pObj
, false);
2803 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
2804 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData
->maLastRect
.IsEmpty());
2806 // Get non rotated anchor data
2807 pNData
= ScDrawLayer::GetNonRotatedObjData( pObj
);
2808 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
2809 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData
->maLastRect
.IsEmpty());
2811 // Check if data after save it
2812 CPPUNIT_ASSERT_EQUAL(pData
->maStart
, aDataStart
);
2813 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
, aDataEnd
);
2815 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
, aNDataStart
);
2816 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
, aNDataEnd
);
2821 void ScExportTest::testHeaderImage()
2823 // Graphic as header background was lost on export.
2824 ScDocShellRef xShell
= loadDoc("header-image.", ODS
);
2825 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), ODS
);
2826 uno::Reference
<style::XStyleFamiliesSupplier
> xStyleFamiliesSupplier(xDocSh
->GetModel(), uno::UNO_QUERY
);
2827 uno::Reference
<container::XNameAccess
> xStyleFamilies
= xStyleFamiliesSupplier
->getStyleFamilies();
2828 uno::Reference
<container::XNameAccess
> xPageStyles(xStyleFamilies
->getByName("PageStyles"), uno::UNO_QUERY
);
2829 uno::Reference
<beans::XPropertySet
> xStyle(xPageStyles
->getByName("Default"), uno::UNO_QUERY
);
2831 xStyle
->getPropertyValue("HeaderBackGraphicURL") >>= aURL
;
2832 CPPUNIT_ASSERT(aURL
.startsWith("vnd.sun.star.GraphicObject:"));
2835 void ScExportTest::testMatrixMultiplication()
2837 ScDocShellRef xShell
= loadDoc("matrix-multiplication.", XLSX
);
2838 CPPUNIT_ASSERT(xShell
.Is());
2840 ScDocShellRef xDocSh
= saveAndReload(&(*xShell
), XLSX
);
2841 CPPUNIT_ASSERT(xDocSh
.Is());
2843 xmlDocPtr pDoc
= XPathHelper::parseExport(&(*xDocSh
), m_xSFactory
, "xl/worksheets/sheet1.xml", XLSX
);
2844 CPPUNIT_ASSERT(pDoc
);
2846 OUString CellFormulaRange
= getXPath(pDoc
,
2847 "/x:worksheet/x:sheetData/x:row[4]/x:c/x:f","ref");
2849 // make sure that the CellFormulaRange is G5:G6.
2850 CPPUNIT_ASSERT_EQUAL(OUString("G5:G6"), CellFormulaRange
);
2852 OUString CellFormulaType
= getXPath(pDoc
,
2853 "/x:worksheet/x:sheetData/x:row[4]/x:c/x:f","t");
2855 // make sure that the CellFormulaType is array.
2856 CPPUNIT_ASSERT_EQUAL(OUString("array"), CellFormulaType
);
2861 void ScExportTest::testRefStringXLSX()
2863 ScDocShellRef xDocSh
= loadDoc("ref_string.", XLSX
);
2864 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh
.Is());
2866 //make sure ref syntax gets saved for MSO-produced docs
2867 xDocSh
= saveAndReload( &(*xDocSh
), XLSX
);
2868 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh
.Is());
2870 ScDocument
& rDoc
= xDocSh
->GetDocument();
2871 ScCalcConfig aCalcConfig
= rDoc
.GetCalcConfig();
2872 CPPUNIT_ASSERT_EQUAL(formula::FormulaGrammar::CONV_XL_A1
, aCalcConfig
.meStringRefAddressSyntax
);
2877 void ScExportTest::testRefStringConfigXLSX()
2879 // this doc is configured with CalcA1 ref syntax
2880 ScDocShellRef xDocSh
= loadDoc("empty.", XLSX
);
2881 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh
.Is());
2883 xDocSh
= saveAndReload( &(*xDocSh
), XLSX
);
2884 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh
.Is());
2886 ScDocument
& rDoc
= xDocSh
->GetDocument();
2887 ScCalcConfig aConfig
= rDoc
.GetCalcConfig();
2888 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_OOO
,
2889 aConfig
.meStringRefAddressSyntax
);
2891 // this doc has no entry for ref syntax
2892 xDocSh
= loadDoc("empty-noconf.", XLSX
);
2893 CPPUNIT_ASSERT_MESSAGE("Failed to open 2nd doc", xDocSh
.Is());
2895 ScDocument
& rDoc2
= xDocSh
->GetDocument();
2896 aConfig
= rDoc2
.GetCalcConfig();
2897 // therefore after import, ref syntax should be set to CalcA1 | ExcelA1
2898 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_A1_XL_A1
,
2899 aConfig
.meStringRefAddressSyntax
);
2901 //set ref syntax to something else than ExcelA1 (native to xlsx format) ...
2902 aConfig
.meStringRefAddressSyntax
= formula::FormulaGrammar::CONV_XL_R1C1
;
2903 rDoc2
.SetCalcConfig( aConfig
);
2905 ScDocShellRef xNewDocSh
= saveAndReload( &(*xDocSh
), XLSX
);
2906 CPPUNIT_ASSERT_MESSAGE("Failed to reload 2nd doc", xNewDocSh
.Is());
2908 // ... and make sure it got saved
2909 ScDocument
& rDoc3
= xNewDocSh
->GetDocument();
2910 aConfig
= rDoc3
.GetCalcConfig();
2911 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_XL_R1C1
,
2912 aConfig
.meStringRefAddressSyntax
);
2915 xNewDocSh
->DoClose();
2918 void ScExportTest::testRefStringUnspecified()
2920 ScDocShell
* pShell
= new ScDocShell(
2921 SfxModelFlags::EMBEDDED_OBJECT
|
2922 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
|
2923 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
);
2924 pShell
->DoInitNew();
2926 ScDocument
& rDoc
= pShell
->GetDocument();
2927 ScCalcConfig aConfig
= rDoc
.GetCalcConfig();
2928 CPPUNIT_ASSERT_EQUAL_MESSAGE("Default string ref syntax value doesn't match", formula::FormulaGrammar::CONV_UNSPECIFIED
,
2929 aConfig
.meStringRefAddressSyntax
);
2931 // change formula syntax (i.e. not string ref syntax) to ExcelA1
2932 rDoc
.SetGrammar( formula::FormulaGrammar::GRAM_NATIVE_XL_A1
);
2934 ScDocShellRef xDocSh
= saveAndReload( pShell
, ODS
);
2935 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh
.Is());
2937 // with string ref syntax at its default value, we should've saved ExcelA1
2938 ScDocument
& rDoc2
= xDocSh
->GetDocument();
2939 aConfig
= rDoc2
.GetCalcConfig();
2940 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_XL_A1
,
2941 aConfig
.meStringRefAddressSyntax
);
2946 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest
);
2948 CPPUNIT_PLUGIN_IMPLEMENT();
2950 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */