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