Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 :
10 : #include <test/sheet/xspreadsheets2.hxx>
11 :
12 : #include <com/sun/star/beans/XPropertySet.hpp>
13 : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
14 : #include <com/sun/star/sheet/XSpreadsheet.hpp>
15 : #include <com/sun/star/sheet/XSpreadsheets2.hpp>
16 : #include <com/sun/star/table/XCellRange.hpp>
17 : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
18 : #include <com/sun/star/sheet/XCellRangeReferrer.hpp>
19 : #include <com/sun/star/sheet/XNamedRanges.hpp>
20 : #include <com/sun/star/sheet/XNamedRange.hpp>
21 : #include <com/sun/star/table/XCell.hpp>
22 : #include <com/sun/star/text/XTextRange.hpp>
23 : #include <com/sun/star/container/XIndexAccess.hpp>
24 :
25 : #include <com/sun/star/table/CellAddress.hpp>
26 : #include <com/sun/star/table/CellRangeAddress.hpp>
27 : #include <com/sun/star/sheet/Border.hpp>
28 : #include <com/sun/star/sheet/NamedRangeFlag.hpp>
29 :
30 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
31 : #include <com/sun/star/container/XNameContainer.hpp>
32 : #include <com/sun/star/table/CellVertJustify.hpp>
33 :
34 : #include <rtl/ustring.hxx>
35 : #include "cppunit/extensions/HelperMacros.h"
36 :
37 : using namespace css;
38 : using namespace css::uno;
39 :
40 : namespace apitest {
41 :
42 0 : XSpreadsheets2::XSpreadsheets2():
43 : aSrcSheetName("SheetToCopy"),
44 : aSrcFileName("rangenamessrc.ods"),
45 0 : aDestFileBase("ScNamedRangeObj.ods")
46 : {
47 0 : }
48 :
49 0 : XSpreadsheets2::~XSpreadsheets2()
50 : {
51 0 : }
52 :
53 0 : void XSpreadsheets2::testImportedSheetNameAndIndex()
54 : {
55 : /**
56 : Verfiy that the imported sheet has the correct name and is placed at the right requested index
57 : */
58 :
59 0 : importSheetToCopy();
60 :
61 0 : uno::Reference< container::XNameAccess > xDestSheetNameAccess(xDestDoc->getSheets(), UNO_QUERY_THROW);
62 0 : CPPUNIT_ASSERT_MESSAGE("Wrong sheet name", xDestSheetNameAccess->hasByName(aSrcSheetName));
63 :
64 0 : }
65 :
66 0 : void XSpreadsheets2::testImportString()
67 : {
68 : /**
69 : tests the cell A1 containing a string correctly imported
70 : */
71 0 : importSheetToCopy();
72 :
73 0 : uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(0,0);
74 0 : uno::Reference< text::XTextRange > xSrcTextRange(xSrcCell, UNO_QUERY_THROW);
75 0 : OUString aSrcString = xSrcTextRange->getString();
76 :
77 0 : uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(0,0);
78 0 : uno::Reference< text::XTextRange > xDestTextRange(xDestCell, UNO_QUERY_THROW);
79 0 : OUString aDestString = xDestTextRange->getString();
80 :
81 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong string imported", aDestString, aSrcString);
82 0 : }
83 :
84 0 : void XSpreadsheets2::testImportValue()
85 : {
86 : /**
87 : tests the cell B1 containing a value correctly imported
88 : */
89 0 : importSheetToCopy();
90 :
91 0 : uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(1,0);
92 0 : sal_Int32 aSrcValue = xSrcCell->getValue();
93 :
94 0 : uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(1,0);
95 0 : sal_Int32 aDestValue = xDestCell->getValue();
96 :
97 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong value imported", aSrcValue, aDestValue);
98 0 : }
99 :
100 0 : void XSpreadsheets2::testImportFormulaBasicMath()
101 : {
102 : /**
103 : tests the cell C1 containing an arithmetic formula correctly imported
104 : */
105 0 : importSheetToCopy();
106 :
107 0 : uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(2,0);
108 0 : OUString aSrcFormula = xSrcCell->getFormula();
109 :
110 0 : uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(2,0);
111 0 : OUString aDestFormula = xDestCell->getFormula();
112 :
113 : // potential problem later: formulas might be adjusted
114 : // add some tests that the formulas are correctly adjusted
115 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula imported", aDestFormula, aSrcFormula);
116 0 : }
117 :
118 0 : void XSpreadsheets2::testImportFormulaWithNamedRange()
119 : {
120 : /**
121 : tests the cell D1 containing a formula that uses a NamedRange expression
122 : */
123 0 : importSheetToCopy();
124 :
125 0 : uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(3,0);
126 0 : OUString aSrcFormula = xSrcCell->getFormula();
127 :
128 0 : uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(3,0);
129 0 : OUString aDestFormula = xDestCell->getFormula();
130 :
131 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong Namedrange formula imported", aDestFormula, aSrcFormula);
132 0 : }
133 :
134 0 : void XSpreadsheets2::testImportOverExistingNamedRange()
135 : {
136 : /**
137 : Both Source and Target file define the named range initial1
138 : in Source, initial1 is defined outside the copied sheet
139 : In Target, after import sheet, initial1 should point on its initial definition $Sheet1.$B$1
140 :
141 : NEED MORE WORK
142 : */
143 0 : importSheetToCopy();
144 :
145 0 : OUString aNamedRangeString("initial1");
146 :
147 0 : uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
148 0 : uno::Any aNr = xDestNamedRangesNameAccess->getByName(aNamedRangeString);
149 0 : uno::Reference< sheet::XNamedRange > xDestNamedRange(aNr, UNO_QUERY_THROW);
150 0 : OUString aNrDestContent = xDestNamedRange->getContent();
151 :
152 0 : OUString aExpectedContent("$Sheet1.$B$1");
153 :
154 0 : std::cout << "testImportSheet : initial1 aNrDestContent " << aNrDestContent << std::endl;
155 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong address for initial1", aNrDestContent, aExpectedContent);
156 :
157 0 : }
158 :
159 0 : void XSpreadsheets2::testImportNamedRangeDefinedInSource()
160 : {
161 : /**
162 : in Source file, InSheetRangeName named range is defined in the copied sheet
163 : it does not exists in target file
164 : test that the range named is created in target and that it points in the target copied sheet
165 : */
166 0 : importSheetToCopy();
167 :
168 : // New range name defined in imported sheet $SheetToCopy.$A$7
169 0 : OUString aNewInSheetNamedRangeString("InSheetRangeName");
170 0 : uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
171 0 : CPPUNIT_ASSERT_MESSAGE("InSheetRangeName", xDestNamedRangesNameAccess->hasByName(aNewInSheetNamedRangeString));
172 :
173 0 : uno::Any aNewInSheetNr = xDestNamedRangesNameAccess->getByName(aNewInSheetNamedRangeString);
174 0 : uno::Reference< sheet::XNamedRange > xDestNewInSheetNamedRange(aNewInSheetNr, UNO_QUERY_THROW);
175 0 : OUString aNewInSheetNrDestContent = xDestNewInSheetNamedRange->getContent();
176 0 : OUString aNewInSheetExpectedContent("$SheetToCopy.$A$7");
177 :
178 0 : std::cout << "testImportSheet : InSheetRangeName content " << aNewInSheetNrDestContent << std::endl;
179 0 : std::cout << "testImportSheet : InSheetRangeName expected " << aNewInSheetExpectedContent << std::endl;
180 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong address for InSheetRangeName", aNewInSheetNrDestContent, aNewInSheetExpectedContent);
181 0 : }
182 :
183 0 : void XSpreadsheets2::testImportNamedRangeRedefinedInSource()
184 : {
185 : /**
186 : in Source file, initial2 named range is defined in the copied sheet
187 : it is defined in another sheet of target file
188 : test that the range named points in the target copied sheet
189 : */
190 0 : importSheetToCopy();
191 :
192 : // the source file redefines an existing named range in the imported sheet --> the target should not be changed
193 0 : OUString aRedefinedInSheetNamedRangeString("initial2");
194 0 : uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
195 0 : CPPUNIT_ASSERT_MESSAGE("aRedefinedInSheetNamedRangeString", xDestNamedRangesNameAccess->hasByName(aRedefinedInSheetNamedRangeString));
196 :
197 0 : uno::Any aRedefinedInSheetNr = xDestNamedRangesNameAccess->getByName(aRedefinedInSheetNamedRangeString);
198 0 : uno::Reference< sheet::XNamedRange > xDestRedefinedInSheetNamedRange(aRedefinedInSheetNr, UNO_QUERY_THROW);
199 0 : OUString aRedefinedInSheetNrDestContent = xDestRedefinedInSheetNamedRange->getContent();
200 0 : OUString aRedefinedInSheetExpectedContent("$Sheet1.$B$2");
201 0 : std::cout << "testImportSheet : initial2 content " << aRedefinedInSheetNrDestContent << std::endl;
202 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong address for Redefined InSheet named range", aRedefinedInSheetNrDestContent, aRedefinedInSheetExpectedContent);
203 0 : }
204 :
205 0 : void XSpreadsheets2::testImportNewNamedRange()
206 : {
207 : /**
208 : in Source file, new_rangename range named is defined outside the copied sheet
209 : it does not exists in target file test that new_rangename is created and its
210 : content points to source file as an external reference
211 : */
212 0 : importSheetToCopy();
213 :
214 : //formula with a non-existant named range in dest - new_rangename
215 0 : OUString aNewNamedRangeString("new_rangename");
216 0 : uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
217 0 : CPPUNIT_ASSERT_MESSAGE("New NamedRange not created", xDestNamedRangesNameAccess->hasByName(aNewNamedRangeString));
218 :
219 : // verify the content of this new namedrange, pointing on $Sheet1.$B$1 in source. This address is already defined in target as NR content
220 :
221 0 : uno::Any aNewNr = xDestNamedRangesNameAccess->getByName(aNewNamedRangeString);
222 0 : uno::Reference< sheet::XNamedRange > xDestNewNamedRange(aNewNr, UNO_QUERY_THROW);
223 0 : OUString aNewNrDestContent = xDestNewNamedRange->getContent();
224 :
225 0 : OUString aNewExpectedContent("$Sheet1.$B$1");
226 :
227 0 : std::cout << "testImportSheet : new_rangename aNewExpectedContent " << aNewExpectedContent << std::endl;
228 0 : std::cout << "testImportSheet : new_rangename aNewNrDestContent " << aNewNrDestContent << std::endl;
229 0 : CPPUNIT_ASSERT_MESSAGE("Wrong New NamedRange formula string value", isExternalReference(aNewNrDestContent, aNewExpectedContent));
230 0 : }
231 :
232 0 : void XSpreadsheets2::testImportCellStyle()
233 : {
234 : /**
235 : in source file, imported sheet uses a cellstyle that does not exists in target
236 : test that
237 : - an imported cell D1 uses the right cellStyle
238 : - the cellStyle is created in CellStyles family
239 : - a property of the cellStyle (VertJustify) is correctly set
240 : */
241 0 : importSheetToCopy();
242 :
243 0 : uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(3,0);
244 0 : uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(3,0);
245 :
246 : //new style created in dest
247 0 : uno::Reference< beans::XPropertySet > xSrcCellPropSet (xSrcCell, UNO_QUERY_THROW);
248 0 : const OUString aCellProperty("CellStyle");
249 0 : OUString aSrcStyleName;
250 0 : CPPUNIT_ASSERT(xSrcCellPropSet->getPropertyValue(aCellProperty) >>= aSrcStyleName);
251 :
252 0 : uno::Reference< beans::XPropertySet > xDestCellPropSet (xSrcCell, UNO_QUERY_THROW);
253 0 : OUString aDestStyleName;
254 0 : CPPUNIT_ASSERT(xDestCellPropSet->getPropertyValue(aCellProperty) >>= aDestStyleName);
255 :
256 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong imported Cell Style", aDestStyleName, aSrcStyleName);
257 :
258 0 : uno::Reference< style::XStyleFamiliesSupplier > xFamiliesSupplier (xDestDoc, UNO_QUERY_THROW);
259 0 : uno::Reference< container::XNameAccess > xFamiliesNameAccess (xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW);
260 0 : OUString aCellFamilyName("CellStyles");
261 0 : uno::Any xCellStylesFamily = xFamiliesNameAccess->getByName(aCellFamilyName);
262 0 : uno::Reference< container::XNameContainer > xCellStylesFamilyNameAccess (xCellStylesFamily, UNO_QUERY_THROW);
263 :
264 0 : CPPUNIT_ASSERT_MESSAGE("New cell style not present", xCellStylesFamilyNameAccess->hasByName(aDestStyleName));
265 :
266 0 : uno::Any aCellStyle = xCellStylesFamilyNameAccess->getByName(aDestStyleName);
267 0 : uno::Reference< beans::XPropertySet > xCellStyleProp (aCellStyle, UNO_QUERY_THROW);
268 0 : OUString aProperty("VertJustify");
269 0 : sal_Int32 aVertJustify = 0;
270 0 : CPPUNIT_ASSERT(xCellStyleProp->getPropertyValue(aProperty) >>= aVertJustify);
271 :
272 0 : CPPUNIT_ASSERT_MESSAGE("New style: VertJustify not set", aVertJustify == table::CellVertJustify_CENTER);
273 0 : }
274 :
275 0 : uno::Reference< sheet::XSpreadsheetDocument> XSpreadsheets2::getDoc(const OUString& aFileBase, uno::Reference< lang::XComponent >& xComp)
276 : {
277 0 : OUString aFileURL;
278 0 : createFileURL(aFileBase, aFileURL);
279 :
280 0 : if (!xComp.is())
281 0 : xComp = loadFromDesktop(aFileURL);
282 :
283 0 : CPPUNIT_ASSERT(xComp.is());
284 :
285 0 : uno::Reference< sheet::XSpreadsheetDocument > xDoc(xComp, UNO_QUERY_THROW);
286 0 : CPPUNIT_ASSERT(xDoc.is());
287 0 : return xDoc;
288 : }
289 :
290 0 : uno::Reference< sheet::XNamedRanges> XSpreadsheets2::getNamedRanges(uno::Reference< sheet::XSpreadsheetDocument> xDoc)
291 : {
292 0 : uno::Reference< beans::XPropertySet > xPropSet (xDoc, UNO_QUERY_THROW);
293 0 : OUString NamedRangesPropertyString("NamedRanges");
294 0 : uno::Reference< sheet::XNamedRanges > xNamedRanges(xPropSet->getPropertyValue(NamedRangesPropertyString), UNO_QUERY_THROW);
295 0 : CPPUNIT_ASSERT(xNamedRanges.is());
296 :
297 0 : return xNamedRanges;
298 : }
299 :
300 0 : void XSpreadsheets2::importSheetToCopy()
301 : {
302 0 : uno::Reference< container::XNameAccess> xSrcNameAccess(init(),UNO_QUERY_THROW);
303 0 : xSrcSheet = uno::Reference< sheet::XSpreadsheet >( xSrcNameAccess->getByName(aSrcSheetName), UNO_QUERY_THROW);
304 :
305 0 : static uno::Reference< lang::XComponent > xDestComponent;
306 0 : if (!xDestComponent.is())
307 : {
308 0 : xDestDoc = getDoc(aDestFileBase, xDestComponent);
309 0 : CPPUNIT_ASSERT(xDestDoc.is());
310 :
311 : // import sheet
312 0 : uno::Reference< sheet::XSpreadsheets2 > xDestSheets (xDestDoc->getSheets(), UNO_QUERY_THROW);
313 0 : sal_Int32 nDestPos = 0;
314 0 : sal_Int32 nDestPosEffective = xDestSheets->importSheet(xDocument, aSrcSheetName, nDestPos);
315 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong sheet index", nDestPosEffective, nDestPos);
316 : }
317 : else
318 : {
319 0 : xDestDoc = uno::Reference< sheet::XSpreadsheetDocument >(xDestComponent,UNO_QUERY_THROW);
320 : }
321 :
322 0 : uno::Reference< container::XNameAccess > xDestSheetNameAccess (xDestDoc->getSheets(), UNO_QUERY_THROW);
323 0 : xDestSheet = uno::Reference< sheet::XSpreadsheet > ( xDestSheetNameAccess->getByName(aSrcSheetName), UNO_QUERY_THROW);
324 0 : }
325 :
326 0 : bool XSpreadsheets2::isExternalReference(const OUString& aDestContent, const OUString& aSrcContent )
327 : {
328 0 : OUString aStart("'file://");
329 :
330 0 : CPPUNIT_ASSERT(aDestContent.startsWith(aStart));
331 :
332 0 : return (aDestContent.endsWithIgnoreAsciiCase(aSrcContent, NULL) // same cell address
333 0 : && aDestContent.indexOf(aSrcFileName)>0); // contains source file name
334 : }
335 :
336 0 : }
337 :
338 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|