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 <sal/config.h>
11 : #include <unotest/filters-test.hxx>
12 : #include <test/bootstrapfixture.hxx>
13 : #include <rtl/strbuf.hxx>
14 : #include <osl/file.hxx>
15 :
16 : #include <sfx2/app.hxx>
17 : #include <sfx2/docfilt.hxx>
18 : #include <sfx2/docfile.hxx>
19 : #include <sfx2/frame.hxx>
20 : #include <sfx2/sfxmodelfactory.hxx>
21 : #include <svl/stritem.hxx>
22 :
23 : #include <unotools/tempfile.hxx>
24 : #include <comphelper/storagehelper.hxx>
25 :
26 : #define CALC_DEBUG_OUTPUT 0
27 : #define TEST_BUG_FILES 0
28 :
29 : #include "helper/qahelper.hxx"
30 :
31 : #include "docsh.hxx"
32 : #include "postit.hxx"
33 : #include "patattr.hxx"
34 : #include "scitems.hxx"
35 : #include "document.hxx"
36 : #include "cellform.hxx"
37 :
38 : #define ODS_FORMAT_TYPE 50331943
39 : #define XLS_FORMAT_TYPE 318767171
40 : #define XLSX_FORMAT_TYPE 268959811
41 : #define LOTUS123_FORMAT_TYPE 268435649
42 :
43 : #define ODS 0
44 : #define XLS 1
45 : #define XLSX 2
46 : #define LOTUS123 3
47 :
48 : using namespace ::com::sun::star;
49 : using namespace ::com::sun::star::uno;
50 :
51 : namespace {
52 :
53 : struct FileFormat {
54 : const char* pName; const char* pFilterName; const char* pTypeName; unsigned int nFormatType;
55 : };
56 :
57 : FileFormat aFileFormats[] = {
58 : { "ods" , "calc8", "", ODS_FORMAT_TYPE },
59 : { "xls" , "MS Excel 97", "calc_MS_EXCEL_97", XLS_FORMAT_TYPE },
60 : { "xlsx", "Calc MS Excel 2007 XML" , "MS Excel 2007 XML", XLSX_FORMAT_TYPE },
61 : { "123" , "Lotus", "calc_Lotus", LOTUS123_FORMAT_TYPE }
62 : };
63 :
64 : }
65 :
66 6 : class ScExportTest : public test::BootstrapFixture
67 : {
68 : public:
69 : ScExportTest();
70 :
71 : virtual void setUp();
72 : virtual void tearDown();
73 :
74 : ScDocShellRef saveAndReload( ScDocShell*, const rtl::OUString&, const rtl::OUString&, const rtl::OUString&, sal_uLong );
75 : ScDocShellRef saveAndReloadPassword( ScDocShell*, const rtl::OUString&, const rtl::OUString&, const rtl::OUString&, sal_uLong );
76 :
77 : void test();
78 : void testPasswordExport();
79 : void testConditionalFormatExportXLSX();
80 :
81 2 : CPPUNIT_TEST_SUITE(ScExportTest);
82 1 : CPPUNIT_TEST(test);
83 : #if !defined(MACOSX) && !defined(DRAGONFLY) && !defined(WNT)
84 1 : CPPUNIT_TEST(testPasswordExport);
85 : #endif
86 1 : CPPUNIT_TEST(testConditionalFormatExportXLSX);
87 2 : CPPUNIT_TEST_SUITE_END();
88 :
89 : private:
90 : rtl::OUString m_aBaseString;
91 : uno::Reference<uno::XInterface> m_xCalcComponent;
92 :
93 : ScDocShellRef load(
94 : const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
95 : const OUString& rTypeName, sal_Int32 nFormat, sal_uLong nFormatType,
96 : const OUString* pPassword = NULL );
97 :
98 : ScDocShellRef saveAndReload( ScDocShell* pShell, sal_Int32 nFormat );
99 : ScDocShellRef loadDocument( const rtl::OUString& rFileNameBase, sal_Int32 nFormat );
100 : void createFileURL( const rtl::OUString& aFileBase, const rtl::OUString& rFileExtension, rtl::OUString& rFilePath);
101 : void createCSVPath(const rtl::OUString& rFileBase, rtl::OUString& rCSVPath);
102 : };
103 :
104 1 : void ScExportTest::createFileURL(const rtl::OUString& aFileBase, const rtl::OUString& aFileExtension, rtl::OUString& rFilePath)
105 : {
106 1 : rtl::OUString aSep("/");
107 1 : rtl::OUStringBuffer aBuffer( getSrcRootURL() );
108 1 : aBuffer.append(m_aBaseString).append(aSep).append(aFileExtension);
109 1 : aBuffer.append(aSep).append(aFileBase).append(aFileExtension);
110 1 : rFilePath = aBuffer.makeStringAndClear();
111 1 : }
112 :
113 1 : void ScExportTest::createCSVPath(const rtl::OUString& aFileBase, rtl::OUString& rCSVPath)
114 : {
115 1 : rtl::OUStringBuffer aBuffer(getSrcRootPath());
116 1 : aBuffer.append(m_aBaseString).append(rtl::OUString("/contentCSV/"));
117 1 : aBuffer.append(aFileBase).append(rtl::OUString("csv"));
118 1 : rCSVPath = aBuffer.makeStringAndClear();
119 1 : }
120 :
121 1 : ScDocShellRef ScExportTest::saveAndReloadPassword(ScDocShell* pShell, const rtl::OUString &rFilter,
122 : const rtl::OUString &rUserData, const rtl::OUString& rTypeName, sal_uLong nFormatType)
123 : {
124 1 : utl::TempFile aTempFile;
125 1 : aTempFile.EnableKillingFile();
126 1 : SfxMedium aStoreMedium( aTempFile.GetURL(), STREAM_STD_WRITE );
127 1 : sal_uInt32 nExportFormat = 0;
128 1 : if (nFormatType)
129 1 : nExportFormat = SFX_FILTER_EXPORT | SFX_FILTER_USESOPTIONS;
130 : SfxFilter* pExportFilter = new SfxFilter(
131 : rFilter,
132 : rtl::OUString(), nFormatType, nExportFormat, rTypeName, 0, rtl::OUString(),
133 1 : rUserData, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/scalc*")) );
134 1 : pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
135 1 : aStoreMedium.SetFilter(pExportFilter);
136 1 : SfxItemSet* pExportSet = aStoreMedium.GetItemSet();
137 1 : uno::Sequence< beans::NamedValue > aEncryptionData = comphelper::OStorageHelper::CreatePackageEncryptionData( rtl::OUString("test") );
138 1 : uno::Any xEncryptionData;
139 1 : xEncryptionData <<= aEncryptionData;
140 1 : pExportSet->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, xEncryptionData));
141 :
142 1 : uno::Reference< embed::XStorage > xMedStorage = aStoreMedium.GetStorage();
143 1 : ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xMedStorage, aEncryptionData );
144 :
145 1 : pShell->DoSaveAs( aStoreMedium );
146 1 : pShell->DoClose();
147 :
148 : //std::cout << "File: " << aTempFile.GetURL() << std::endl;
149 :
150 1 : sal_uInt32 nFormat = 0;
151 1 : if (nFormatType)
152 1 : nFormat = SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS;
153 :
154 1 : OUString aPass("test");
155 1 : return load(aTempFile.GetURL(), rFilter, rUserData, rTypeName, nFormat, nFormatType, &aPass);
156 : }
157 :
158 2 : ScDocShellRef ScExportTest::saveAndReload(ScDocShell* pShell, const rtl::OUString &rFilter,
159 : const rtl::OUString &rUserData, const rtl::OUString& rTypeName, sal_uLong nFormatType)
160 : {
161 :
162 2 : utl::TempFile aTempFile;
163 2 : aTempFile.EnableKillingFile();
164 2 : SfxMedium aStoreMedium( aTempFile.GetURL(), STREAM_STD_WRITE );
165 2 : sal_uInt32 nExportFormat = 0;
166 2 : if (nFormatType)
167 2 : nExportFormat = SFX_FILTER_EXPORT | SFX_FILTER_USESOPTIONS;
168 : SfxFilter* pExportFilter = new SfxFilter(
169 : rFilter,
170 : rtl::OUString(), nFormatType, nExportFormat, rTypeName, 0, rtl::OUString(),
171 2 : rUserData, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/scalc*")) );
172 2 : pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
173 2 : aStoreMedium.SetFilter(pExportFilter);
174 2 : pShell->DoSaveAs( aStoreMedium );
175 2 : pShell->DoClose();
176 :
177 : //std::cout << "File: " << aTempFile.GetURL() << std::endl;
178 :
179 2 : sal_uInt32 nFormat = 0;
180 2 : if (nFormatType)
181 2 : nFormat = SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS;
182 :
183 2 : return load(aTempFile.GetURL(), rFilter, rUserData, rTypeName, nFormat, nFormatType);
184 : }
185 :
186 4 : ScDocShellRef ScExportTest::load(
187 : const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
188 : const OUString& rTypeName, sal_Int32 nFormat, sal_uLong nFormatType, const OUString* pPassword )
189 : {
190 : SfxFilter* pFilter = new SfxFilter(
191 : rFilter,
192 : rtl::OUString(), nFormatType, nFormat, rTypeName, 0, rtl::OUString(),
193 4 : rUserData, OUString("private:factory/scalc*"));
194 4 : pFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
195 :
196 4 : ScDocShellRef xDocShRef = new ScDocShell;
197 4 : xDocShRef->GetDocument()->EnableUserInteraction(false);
198 4 : SfxMedium* pSrcMed = new SfxMedium(rURL, STREAM_STD_READ);
199 4 : pSrcMed->SetFilter(pFilter);
200 4 : pSrcMed->UseInteractionHandler(false);
201 4 : if (pPassword)
202 : {
203 1 : SfxItemSet* pSet = pSrcMed->GetItemSet();
204 1 : pSet->Put(SfxStringItem(SID_PASSWORD, *pPassword));
205 : }
206 4 : if (!xDocShRef->DoLoad(pSrcMed))
207 : {
208 0 : xDocShRef->DoClose();
209 : // load failed.
210 0 : xDocShRef.Clear();
211 : }
212 :
213 4 : return xDocShRef;
214 : }
215 :
216 2 : ScDocShellRef ScExportTest::saveAndReload( ScDocShell* pShell, sal_Int32 nFormat )
217 : {
218 2 : rtl::OUString aFileExtension(aFileFormats[nFormat].pName, strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
219 2 : rtl::OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
220 2 : rtl::OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
221 2 : ScDocShellRef xDocSh = saveAndReload(pShell, aFilterName, rtl::OUString(), aFilterType, aFileFormats[nFormat].nFormatType);
222 :
223 2 : CPPUNIT_ASSERT(xDocSh.Is());
224 2 : return xDocSh;
225 : }
226 :
227 1 : ScDocShellRef ScExportTest::loadDocument(const rtl::OUString& rFileName, sal_Int32 nFormat)
228 : {
229 1 : rtl::OUString aFileExtension(aFileFormats[nFormat].pName, strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
230 1 : rtl::OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
231 1 : rtl::OUString aFileName;
232 1 : createFileURL( rFileName, aFileExtension, aFileName );
233 1 : rtl::OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
234 1 : unsigned int nFormatType = aFileFormats[nFormat].nFormatType;
235 1 : unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
236 :
237 1 : return load(aFileName, aFilterName, OUString(), aFilterType, nClipboardId, nFormatType);
238 : }
239 :
240 1 : void ScExportTest::test()
241 : {
242 : ScDocShell* pShell = new ScDocShell(
243 : SFXMODEL_STANDARD |
244 : SFXMODEL_DISABLE_EMBEDDED_SCRIPTS |
245 1 : SFXMODEL_DISABLE_DOCUMENT_RECOVERY);
246 1 : pShell->DoInitNew();
247 :
248 1 : ScDocument* pDoc = pShell->GetDocument();
249 :
250 1 : pDoc->SetValue(0,0,0, 1.0);
251 1 : CPPUNIT_ASSERT(pDoc);
252 :
253 1 : ScDocShellRef xDocSh = saveAndReload( pShell, ODS );
254 :
255 1 : CPPUNIT_ASSERT(xDocSh.Is());
256 1 : ScDocument* pLoadedDoc = xDocSh->GetDocument();
257 1 : double aVal = pLoadedDoc->GetValue(0,0,0);
258 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(aVal, 1.0, 1e-8);
259 1 : }
260 :
261 1 : void ScExportTest::testPasswordExport()
262 : {
263 : ScDocShell* pShell = new ScDocShell(
264 : SFXMODEL_STANDARD |
265 : SFXMODEL_DISABLE_EMBEDDED_SCRIPTS |
266 1 : SFXMODEL_DISABLE_DOCUMENT_RECOVERY);
267 1 : pShell->DoInitNew();
268 :
269 1 : ScDocument* pDoc = pShell->GetDocument();
270 :
271 1 : pDoc->SetValue(0,0,0, 1.0);
272 1 : CPPUNIT_ASSERT(pDoc);
273 :
274 1 : sal_Int32 nFormat = ODS;
275 1 : rtl::OUString aFileExtension(aFileFormats[nFormat].pName, strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
276 1 : rtl::OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
277 1 : rtl::OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
278 1 : ScDocShellRef xDocSh = saveAndReloadPassword(pShell, aFilterName, rtl::OUString(), aFilterType, aFileFormats[nFormat].nFormatType);
279 :
280 1 : CPPUNIT_ASSERT(xDocSh.Is());
281 1 : ScDocument* pLoadedDoc = xDocSh->GetDocument();
282 1 : double aVal = pLoadedDoc->GetValue(0,0,0);
283 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(aVal, 1.0, 1e-8);
284 1 : }
285 :
286 1 : void ScExportTest::testConditionalFormatExportXLSX()
287 : {
288 1 : ScDocShellRef xShell = loadDocument("new_cond_format_test.", XLSX);
289 1 : CPPUNIT_ASSERT(xShell.Is());
290 :
291 1 : ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX);
292 1 : CPPUNIT_ASSERT(xDocSh.Is());
293 1 : ScDocument* pDoc = xDocSh->GetDocument();
294 1 : rtl::OUString aCSVFile("new_cond_format_test.");
295 1 : rtl::OUString aCSVPath;
296 1 : createCSVPath( aCSVFile, aCSVPath );
297 1 : testCondFile(aCSVPath, pDoc, 0);
298 1 : }
299 :
300 3 : ScExportTest::ScExportTest()
301 3 : : m_aBaseString(RTL_CONSTASCII_USTRINGPARAM("/sc/qa/unit/data"))
302 : {
303 3 : }
304 :
305 3 : void ScExportTest::setUp()
306 : {
307 3 : test::BootstrapFixture::setUp();
308 :
309 : // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
310 : // which is a private symbol to us, gets called
311 : m_xCalcComponent =
312 6 : getMultiServiceFactory()->createInstance(rtl::OUString(
313 3 : RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.SpreadsheetDocument")));
314 3 : CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
315 3 : }
316 :
317 3 : void ScExportTest::tearDown()
318 : {
319 3 : uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
320 3 : test::BootstrapFixture::tearDown();
321 3 : }
322 :
323 1 : CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
324 :
325 4 : CPPUNIT_PLUGIN_IMPLEMENT();
326 :
327 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|