fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / filter / xml / xmlwrap.cxx
blob9cb0a7139afa05de97fde9659318c365e6292d85
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rsc/rscsfx.hxx>
21 #include <sfx2/docfile.hxx>
22 #include <sfx2/objsh.hxx>
23 #include <sot/storage.hxx>
24 #include <osl/diagnose.h>
25 #include <comphelper/processfactory.hxx>
26 #include <unotools/streamwrap.hxx>
27 #include <svx/xmlgrhlp.hxx>
28 #include <svtools/sfxecode.hxx>
29 #include <sfx2/frame.hxx>
30 #include <svl/itemset.hxx>
31 #include <svl/stritem.hxx>
32 #include <sfx2/sfxsids.hrc>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/beans/XPropertySetInfo.hpp>
35 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
36 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
37 #include <com/sun/star/xml/sax/InputSource.hpp>
38 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
39 #include <com/sun/star/xml/sax/Parser.hpp>
40 #include <com/sun/star/xml/sax/Writer.hpp>
41 #include <com/sun/star/io/XActiveDataSource.hpp>
42 #include <com/sun/star/io/XActiveDataControl.hpp>
43 #include <com/sun/star/frame/XModel.hpp>
44 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
45 #include <com/sun/star/beans/PropertyAttribute.hpp>
46 #include <comphelper/extract.hxx>
47 #include <comphelper/propertysetinfo.hxx>
48 #include <comphelper/genericpropertyset.hxx>
49 #include <com/sun/star/container/XNameContainer.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
51 #include <com/sun/star/packages/zip/ZipIOException.hpp>
52 #include <com/sun/star/embed/ElementModes.hpp>
53 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
54 #include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
55 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
57 #include <sfx2/DocumentMetadataAccess.hxx>
58 #include <comphelper/documentconstants.hxx>
59 #include <svx/xmleohlp.hxx>
60 #include <rtl/strbuf.hxx>
61 #include <unotools/saveopt.hxx>
63 #include "document.hxx"
64 #include "xmlwrap.hxx"
65 #include "xmlimprt.hxx"
66 #include "xmlexprt.hxx"
67 #include "global.hxx"
68 #include "globstr.hrc"
69 #include "scerrors.hxx"
70 #include "XMLExportSharedData.hxx"
71 #include "docuno.hxx"
72 #include "sheetdata.hxx"
73 #include "XMLCodeNameProvider.hxx"
74 #include <docsh.hxx>
75 #include <unonames.hxx>
77 using namespace com::sun::star;
79 ScXMLImportWrapper::ScXMLImportWrapper( ScDocShell& rDocSh, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) :
80 mrDocShell(rDocSh),
81 rDoc(rDocSh.GetDocument()),
82 pMedium(pM),
83 xStorage(xStor)
85 OSL_ENSURE( pMedium || xStorage.is(), "ScXMLImportWrapper: Medium or Storage must be set" );
88 uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator()
90 uno::Reference<task::XStatusIndicator> xStatusIndicator;
91 if (pMedium)
93 SfxItemSet* pSet = pMedium->GetItemSet();
94 if (pSet)
96 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL));
97 if (pItem)
98 xStatusIndicator.set(pItem->GetValue(), uno::UNO_QUERY);
101 return xStatusIndicator;
104 sal_uInt32 ScXMLImportWrapper::ImportFromComponent(const uno::Reference<uno::XComponentContext>& xContext,
105 uno::Reference<frame::XModel>& xModel, uno::Reference<xml::sax::XParser>& xParser,
106 xml::sax::InputSource& aParserInput,
107 const OUString& sComponentName, const OUString& sDocName,
108 const OUString& sOldDocName, uno::Sequence<uno::Any>& aArgs,
109 bool bMustBeSuccessfull)
111 uno::Reference < io::XStream > xDocStream;
112 if ( !xStorage.is() && pMedium )
113 xStorage = pMedium->GetStorage();
115 bool bEncrypted = false;
116 OUString sStream(sDocName);
117 if( xStorage.is() )
121 uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
122 if ( xAccess->hasByName(sDocName) && xStorage->isStreamElement( sDocName) )
123 xDocStream = xStorage->openStreamElement( sDocName, embed::ElementModes::READ );
124 else if (!sOldDocName.isEmpty() && xAccess->hasByName(sOldDocName) && xStorage->isStreamElement( sOldDocName) )
126 xDocStream = xStorage->openStreamElement( sOldDocName, embed::ElementModes::READ );
127 sStream = sOldDocName;
129 else
130 return SCERR_NONE;
132 aParserInput.aInputStream = xDocStream->getInputStream();
133 uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
135 uno::Any aAny = xSet->getPropertyValue("Encrypted");
136 aAny >>= bEncrypted;
138 catch( const packages::WrongPasswordException& )
140 return ERRCODE_SFX_WRONGPASSWORD;
142 catch( const packages::zip::ZipIOException& )
144 return ERRCODE_IO_BROKENPACKAGE;
146 catch( const uno::Exception& )
148 return SCERR_IMPORT_UNKNOWN;
151 else
152 return SCERR_IMPORT_UNKNOWN;
154 // set Base URL
155 uno::Reference< beans::XPropertySet > xInfoSet;
156 if( aArgs.getLength() > 0 )
157 aArgs.getConstArray()[0] >>= xInfoSet;
158 OSL_ENSURE( xInfoSet.is(), "missing property set" );
159 if( xInfoSet.is() )
161 OUString sPropName("StreamName");
162 xInfoSet->setPropertyValue( sPropName, uno::makeAny( sStream ) );
165 sal_uInt32 nReturn = SCERR_NONE;
166 rDoc.SetRangeOverflowType(0); // is modified by the importer if limits are exceeded
168 uno::Reference<xml::sax::XDocumentHandler> xDocHandler(
169 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
170 sComponentName, aArgs, xContext ),
171 uno::UNO_QUERY );
172 OSL_ENSURE( xDocHandler.is(), "can't get Calc importer" );
173 uno::Reference<document::XImporter> xImporter( xDocHandler, uno::UNO_QUERY );
174 uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY );
175 if (xImporter.is())
176 xImporter->setTargetDocument( xComponent );
178 ScXMLImport* pImporterImpl = dynamic_cast<ScXMLImport*>(xImporter.get());
179 if (pImporterImpl)
180 pImporterImpl->SetPostProcessData(&maPostProcessData);
182 // connect parser and filter
183 xParser->setDocumentHandler( xDocHandler );
187 xParser->parseStream( aParserInput );
189 catch( const xml::sax::SAXParseException& r )
191 // sax parser sends wrapped exceptions,
192 // try to find the original one
193 xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
194 bool bTryChild = true;
196 while( bTryChild )
198 xml::sax::SAXException aTmp;
199 if ( aSaxEx.WrappedException >>= aTmp )
200 aSaxEx = aTmp;
201 else
202 bTryChild = false;
205 packages::zip::ZipIOException aBrokenPackage;
206 if ( aSaxEx.WrappedException >>= aBrokenPackage )
207 return ERRCODE_IO_BROKENPACKAGE;
208 else if( bEncrypted )
209 nReturn = ERRCODE_SFX_WRONGPASSWORD;
210 else
213 #if OSL_DEBUG_LEVEL > 0
214 OStringBuffer aError("SAX parse exception caught while importing:\n");
215 aError.append(OUStringToOString(r.Message, RTL_TEXTENCODING_ASCII_US));
216 OSL_FAIL(aError.getStr());
217 #endif
219 OUString sErr = OUString::number( r.LineNumber ) +
220 "," +
221 OUString::number( r.ColumnNumber );
223 if( !sDocName.isEmpty() )
225 nReturn = *new TwoStringErrorInfo(
226 (bMustBeSuccessfull ? SCERR_IMPORT_FILE_ROWCOL
227 : SCWARN_IMPORT_FILE_ROWCOL),
228 sDocName, sErr,
229 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
231 else
233 OSL_ENSURE( bMustBeSuccessfull, "Warnings are not supported" );
234 nReturn = *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL, sErr,
235 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
239 catch( const xml::sax::SAXException& r )
241 packages::zip::ZipIOException aBrokenPackage;
242 if ( r.WrappedException >>= aBrokenPackage )
243 return ERRCODE_IO_BROKENPACKAGE;
244 else if( bEncrypted )
245 nReturn = ERRCODE_SFX_WRONGPASSWORD;
246 else
249 #if OSL_DEBUG_LEVEL > 0
250 OStringBuffer aError("SAX exception caught while importing:\n");
251 aError.append(OUStringToOString(r.Message,
252 RTL_TEXTENCODING_ASCII_US));
253 OSL_FAIL(aError.getStr());
254 #endif
255 (void)r; // avoid warning in product version
257 nReturn = SCERR_IMPORT_FORMAT;
260 catch( const packages::zip::ZipIOException& r )
262 #if OSL_DEBUG_LEVEL > 0
263 OStringBuffer aError("Zip exception caught while importing:\n");
264 aError.append(OUStringToOString(r.Message,
265 RTL_TEXTENCODING_ASCII_US));
266 OSL_FAIL( aError.getStr() );
267 #endif
268 (void)r; // avoid warning in product version
270 nReturn = ERRCODE_IO_BROKENPACKAGE;
272 catch( const io::IOException& r )
274 #if OSL_DEBUG_LEVEL > 0
275 OStringBuffer aError("IO exception caught while importing:\n");
276 aError.append(OUStringToOString(r.Message,
277 RTL_TEXTENCODING_ASCII_US));
278 OSL_FAIL(aError.getStr());
279 #endif
280 (void)r; // avoid warning in product version
282 nReturn = SCERR_IMPORT_OPEN;
284 catch( const uno::Exception& r )
286 #if OSL_DEBUG_LEVEL > 0
287 OStringBuffer aError("uno exception caught while importing:\n");
288 aError.append(OUStringToOString(r.Message,
289 RTL_TEXTENCODING_ASCII_US));
290 OSL_FAIL(aError.getStr());
291 #endif
292 (void)r; // avoid warning in product version
294 nReturn = SCERR_IMPORT_UNKNOWN;
297 // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler,
298 // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer.
299 // So the overflow warning ErrorCode is now stored in the document.
300 // Export works differently, there getImplementation still works.
302 if (rDoc.HasRangeOverflow() && !nReturn)
303 nReturn = rDoc.GetRangeOverflowType();
305 // free the component
306 xParser->setDocumentHandler( NULL );
308 // success!
309 return nReturn;
312 bool ScXMLImportWrapper::Import( sal_uInt8 nMode, ErrCode& rError )
314 uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
316 xml::sax::InputSource aParserInput;
317 if (pMedium)
318 aParserInput.sSystemId = pMedium->GetName();
320 if ( !xStorage.is() && pMedium )
321 xStorage = pMedium->GetStorage();
323 // get parser
324 uno::Reference<xml::sax::XParser> xXMLParser = xml::sax::Parser::create(xContext);
326 // get filter
327 OUString sEmpty;
328 uno::Reference<frame::XModel> xModel = mrDocShell.GetModel();
330 /** property map for export info set */
331 comphelper::PropertyMapEntry const aImportInfoMap[] =
333 { OUString("ProgressRange"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
334 { OUString("ProgressMax"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
335 { OUString("ProgressCurrent"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
336 { OUString("NumberStyles"), 0, cppu::UnoType<container::XNameAccess>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
337 { OUString("PrivateData"), 0, cppu::UnoType<uno::XInterface>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
338 { OUString("BaseURI"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
339 { OUString("StreamRelPath"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
340 { OUString("StreamName"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
341 { OUString("BuildId"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
342 { OUString("VBACompatibilityMode"), 0, cppu::UnoType<bool>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
343 { OUString("ScriptConfiguration"), 0, cppu::UnoType<container::XNameAccess>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
344 { OUString("OrganizerMode"), 0, cppu::UnoType<bool>::get(),
345 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
346 { OUString("SourceStorage"), 0, cppu::UnoType<embed::XStorage>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
347 { OUString(SC_UNO_ODS_LOCK_SOLAR_MUTEX), 0, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
348 { OUString(SC_UNO_ODS_IMPORT_STYLES), 0, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
349 { OUString(), 0, css::uno::Type(), 0, 0 }
351 uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) );
353 // No need to lock solar mutex when calling from the wrapper.
354 xInfoSet->setPropertyValue(SC_UNO_ODS_LOCK_SOLAR_MUTEX, uno::makeAny(false));
356 // ---- get BuildId from parent container if available
358 uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY );
359 if( xChild.is() )
361 uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
362 if( xParentSet.is() )
364 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
365 OUString sPropName("BuildId" );
366 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
368 xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
373 uno::Reference<task::XStatusIndicator> xStatusIndicator = GetStatusIndicator();
374 if (xStatusIndicator.is())
376 sal_Int32 nProgressRange(1000000);
377 xStatusIndicator->start(ScGlobal::GetRscString(STR_LOAD_DOC), nProgressRange);
378 xInfoSet->setPropertyValue("ProgressRange", uno::makeAny(nProgressRange));
381 // Set base URI
382 OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
383 OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : OUString();
384 OUString sPropName("BaseURI");
385 xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
387 // TODO/LATER: do not do it for embedded links
388 OUString aName;
389 if (SfxObjectCreateMode::EMBEDDED == mrDocShell.GetCreateMode())
391 if ( pMedium && pMedium->GetItemSet() )
393 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
394 pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
395 if ( pDocHierarchItem )
396 aName = pDocHierarchItem->GetValue();
398 else
399 aName = "dummyObjectName";
401 if( !aName.isEmpty() )
403 sPropName = "StreamRelPath";
404 xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
408 if (mrDocShell.GetCreateMode() == SfxObjectCreateMode::ORGANIZER)
409 xInfoSet->setPropertyValue("OrganizerMode", uno::makeAny(true));
411 xInfoSet->setPropertyValue( "SourceStorage", uno::Any( xStorage ) );
413 bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
415 if ((nMode & METADATA) == METADATA && bOasis)
417 // RDF metadata: ODF >= 1.2
420 const uno::Reference< rdf::XDocumentMetadataAccess > xDMA(
421 xModel, uno::UNO_QUERY_THROW );
422 const uno::Reference< rdf::XURI > xBaseURI(
423 ::sfx2::createBaseURI( xContext, xStorage, aBaseURL, aName ) );
424 uno::Reference<task::XInteractionHandler> xHandler =
425 mrDocShell.GetMedium()->GetInteractionHandler();
426 xDMA->loadMetadataFromStorage( xStorage, xBaseURI, xHandler );
428 catch ( const lang::WrappedTargetException & e)
430 ucb::InteractiveAugmentedIOException iaioe;
431 if ( e.TargetException >>= iaioe )
433 rError = SCERR_IMPORT_UNKNOWN;
435 else
437 rError = SCWARN_IMPORT_FEATURES_LOST;
440 catch ( const uno::Exception &)
442 rError = SCWARN_IMPORT_FEATURES_LOST;
446 // #i103539#: always read meta.xml for generator
447 sal_uInt32 nMetaRetval(0);
448 if ((nMode & METADATA) == METADATA)
450 uno::Sequence<uno::Any> aMetaArgs(1);
451 uno::Any* pMetaArgs = aMetaArgs.getArray();
452 pMetaArgs[0] <<= xInfoSet;
454 SAL_INFO( "sc.filter", "meta import start" );
456 nMetaRetval = ImportFromComponent(
457 xContext, xModel, xXMLParser, aParserInput,
458 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisMetaImporter")
459 : OUString("com.sun.star.comp.Calc.XMLMetaImporter"),
460 "meta.xml", "Meta.xml", aMetaArgs, false);
462 SAL_INFO( "sc.filter", "meta import end" );
465 SvXMLGraphicHelper* pGraphicHelper = NULL;
466 uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
468 uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
469 SvXMLEmbeddedObjectHelper *pObjectHelper = NULL;
471 if( xStorage.is() )
473 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
474 xGrfContainer = pGraphicHelper;
476 pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, mrDocShell, EMBEDDEDOBJECTHELPER_MODE_READ, false);
477 xObjectResolver = pObjectHelper;
479 uno::Sequence<uno::Any> aStylesArgs(4);
480 uno::Any* pStylesArgs = aStylesArgs.getArray();
481 pStylesArgs[0] <<= xInfoSet;
482 pStylesArgs[1] <<= xGrfContainer;
483 pStylesArgs[2] <<= xStatusIndicator;
484 pStylesArgs[3] <<= xObjectResolver;
486 sal_uInt32 nSettingsRetval(0);
487 if ((nMode & SETTINGS) == SETTINGS)
489 // Settings must be loaded first because of the printer setting,
490 // which is needed in the page styles (paper tray).
492 uno::Sequence<uno::Any> aSettingsArgs(1);
493 uno::Any* pSettingsArgs = aSettingsArgs.getArray();
494 pSettingsArgs[0] <<= xInfoSet;
496 SAL_INFO( "sc.filter", "settings import start" );
498 nSettingsRetval = ImportFromComponent(
499 xContext, xModel, xXMLParser, aParserInput,
500 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisSettingsImporter")
501 : OUString("com.sun.star.comp.Calc.XMLSettingsImporter"),
502 "settings.xml", sEmpty, aSettingsArgs, false);
504 SAL_INFO( "sc.filter", "settings import end" );
507 sal_uInt32 nStylesRetval(0);
508 if ((nMode & STYLES) == STYLES)
510 SAL_INFO( "sc.filter", "styles import start" );
512 nStylesRetval = ImportFromComponent(xContext, xModel, xXMLParser, aParserInput,
513 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisStylesImporter")
514 : OUString("com.sun.star.comp.Calc.XMLStylesImporter"),
515 OUString("styles.xml"),
516 sEmpty, aStylesArgs, true);
518 SAL_INFO( "sc.filter", "styles import end" );
521 sal_uInt32 nDocRetval(0);
522 if ((nMode & CONTENT) == CONTENT)
524 if (mrDocShell.GetCreateMode() == SfxObjectCreateMode::INTERNAL)
525 // We only need to import content for external link cache document.
526 xInfoSet->setPropertyValue(SC_UNO_ODS_IMPORT_STYLES, uno::makeAny(false));
528 uno::Sequence<uno::Any> aDocArgs(4);
529 uno::Any* pDocArgs = aDocArgs.getArray();
530 pDocArgs[0] <<= xInfoSet;
531 pDocArgs[1] <<= xGrfContainer;
532 pDocArgs[2] <<= xStatusIndicator;
533 pDocArgs[3] <<= xObjectResolver;
535 SAL_INFO( "sc.filter", "content import start" );
537 nDocRetval = ImportFromComponent(xContext, xModel, xXMLParser, aParserInput,
538 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisContentImporter")
539 : OUString("com.sun.star.comp.Calc.XMLContentImporter"),
540 OUString("content.xml"),
541 OUString("Content.xml"), aDocArgs,
542 true);
544 SAL_INFO( "sc.filter", "content import end" );
546 if( pGraphicHelper )
547 SvXMLGraphicHelper::Destroy( pGraphicHelper );
549 if( pObjectHelper )
550 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
552 if (xStatusIndicator.is())
553 xStatusIndicator->end();
555 bool bRet = false;
556 if (nDocRetval)
558 rError = nDocRetval;
559 if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW ||
560 nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW ||
561 nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW ||
562 nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW)
563 bRet = true;
565 else if (nStylesRetval)
566 rError = nStylesRetval;
567 else if (nMetaRetval)
568 rError = nMetaRetval;
569 else if (nSettingsRetval)
570 rError = nSettingsRetval;
571 else
572 bRet = true;
574 // set BuildId on XModel for later OLE object loading
575 if( xInfoSet.is() )
577 uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
578 if( xModelSet.is() )
580 uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
581 OUString sBuildPropName("BuildId" );
582 if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) )
584 xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) );
588 // Set Code Names
589 uno::Any aAny = xInfoSet->getPropertyValue("ScriptConfiguration");
590 uno::Reference <container::XNameAccess> xCodeNameAccess;
591 if( aAny >>= xCodeNameAccess )
592 XMLCodeNameProvider::set( xCodeNameAccess, &rDoc );
594 // VBA compatibility
595 bool bVBACompat = false;
596 if ( (xInfoSet->getPropertyValue("VBACompatibilityMode") >>= bVBACompat) && bVBACompat )
598 /* Set library container to VBA compatibility mode, this
599 forces loading the Basic project, which in turn creates the
600 VBA Globals object and does all related initialization. */
601 if ( xModelSet.is() ) try
603 uno::Reference< script::vba::XVBACompatibility > xVBACompat( xModelSet->getPropertyValue(
604 OUString( "BasicLibraries" ) ), uno::UNO_QUERY_THROW );
605 xVBACompat->setVBACompatibilityMode( sal_True );
607 catch( const uno::Exception& )
613 // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
614 return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval;
617 static bool lcl_HasValidStream(ScDocument& rDoc)
619 SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
620 if ( pObjSh->IsDocShared() )
621 return false; // never copy stream from shared file
623 // don't read remote file again
624 // (could instead re-use medium directly in that case)
625 SfxMedium* pSrcMed = rDoc.GetDocumentShell()->GetMedium();
626 if ( !pSrcMed || pSrcMed->IsRemote() )
627 return false;
629 SCTAB nTabCount = rDoc.GetTableCount();
630 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
631 if (rDoc.IsStreamValid(nTab))
632 return true;
633 return false;
636 bool ScXMLImportWrapper::ExportToComponent(const uno::Reference<uno::XComponentContext>& xContext,
637 uno::Reference<frame::XModel>& xModel, uno::Reference<xml::sax::XWriter>& xWriter,
638 uno::Sequence<beans::PropertyValue>& aDescriptor, const OUString& sName,
639 const OUString& sMediaType, const OUString& sComponentName,
640 uno::Sequence<uno::Any>& aArgs, ScMySharedData*& pSharedData)
642 bool bRet(false);
643 uno::Reference<io::XOutputStream> xOut;
644 uno::Reference<io::XStream> xStream;
646 if ( !xStorage.is() && pMedium )
647 xStorage = pMedium->GetOutputStorage();
649 if( xStorage.is() )
651 // #96807#; trunc stream before use, because it could be an existing stream
652 // and the new content could be shorter than the old content. In this case
653 // would not all be over written by the new content and the xml file
654 // would not be valid.
655 xStream = xStorage->openStreamElement( sName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
656 uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
657 if (xSet.is())
659 xSet->setPropertyValue("MediaType", uno::makeAny(sMediaType));
660 OUString aUseCommonPassPropName("UseCommonStoragePasswordEncryption");
662 // advise storage impl to use common encryption
663 xSet->setPropertyValue( aUseCommonPassPropName, uno::makeAny(sal_True) );
666 xOut = xStream->getOutputStream();
669 // set Base URL
670 uno::Reference< beans::XPropertySet > xInfoSet;
671 if( aArgs.getLength() > 0 )
672 aArgs.getConstArray()[0] >>= xInfoSet;
673 OSL_ENSURE( xInfoSet.is(), "missing property set" );
674 if( xInfoSet.is() )
676 OUString sPropName("StreamName");
677 xInfoSet->setPropertyValue( sPropName, uno::makeAny( sName ) );
680 xWriter->setOutputStream( xOut );
682 uno::Reference<document::XFilter> xFilter(
683 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
684 sComponentName , aArgs, xContext ),
685 uno::UNO_QUERY );
686 OSL_ENSURE( xFilter.is(), "can't get exporter" );
687 uno::Reference<document::XExporter> xExporter( xFilter, uno::UNO_QUERY );
688 uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY );
689 if (xExporter.is())
690 xExporter->setSourceDocument( xComponent );
692 if ( xFilter.is() )
694 ScXMLExport* pExport = static_cast<ScXMLExport*>(SvXMLExport::getImplementation(xFilter));
695 pExport->SetSharedData(pSharedData);
697 // if there are sheets to copy, get the source stream
698 if ( sName == "content.xml" && lcl_HasValidStream(rDoc) && ( pExport->getExportFlags() & SvXMLExportFlags::OASIS ) )
700 // old stream is still in this file's storage - open read-only
702 // #i106854# use the document's storage directly, without a temporary SfxMedium
703 uno::Reference<embed::XStorage> xTmpStorage = rDoc.GetDocumentShell()->GetStorage();
704 uno::Reference<io::XStream> xSrcStream;
705 uno::Reference<io::XInputStream> xSrcInput;
707 // #i108978# If an embedded object is saved and no events are notified, don't use the stream
708 // because without the ...DONE events, stream positions aren't updated.
709 ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xModel)->GetSheetSaveData();
710 if (pSheetData && pSheetData->IsInSupportedSave())
714 if (xTmpStorage.is())
715 xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ );
716 if (xSrcStream.is())
717 xSrcInput = xSrcStream->getInputStream();
719 catch ( const uno::Exception&)
721 // stream not available (for example, password protected) - save normally (xSrcInput is null)
725 pExport->SetSourceStream( xSrcInput );
726 bRet = xFilter->filter( aDescriptor );
727 pExport->SetSourceStream( uno::Reference<io::XInputStream>() );
729 // If there was an error, reset all stream flags, so the next save attempt will use normal saving.
730 // #i110692# For embedded objects, the stream may be unavailable for one save operation (m_pAntiImpl)
731 // and become available again later. But after saving normally once, the stream positions aren't
732 // valid anymore, so the flags also have to be reset if the stream wasn't available.
733 if ( !bRet || !xSrcInput.is() )
735 SCTAB nTabCount = rDoc.GetTableCount();
736 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
737 if (rDoc.IsStreamValid(nTab))
738 rDoc.SetStreamValid(nTab, false);
741 else
742 bRet = xFilter->filter( aDescriptor );
744 pSharedData = pExport->GetSharedData();
747 return bRet;
750 bool ScXMLImportWrapper::Export(bool bStylesOnly)
752 rDoc.CreateAllNoteCaptions();
754 uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
756 uno::Reference<xml::sax::XWriter> xWriter = xml::sax::Writer::create(xContext);
758 if ( !xStorage.is() && pMedium )
759 xStorage = pMedium->GetOutputStorage();
761 OUString sFileName;
762 OUString sTextMediaType("text/xml");
763 if (pMedium)
764 sFileName = pMedium->GetName();
765 SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
766 uno::Sequence<beans::PropertyValue> aDescriptor(1);
767 beans::PropertyValue* pProps = aDescriptor.getArray();
768 pProps[0].Name = "FileName";
769 pProps[0].Value <<= sFileName;
771 /** property map for export info set */
772 comphelper::PropertyMapEntry const aExportInfoMap[] =
774 { OUString("ProgressRange"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
775 { OUString("ProgressMax"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
776 { OUString("ProgressCurrent"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
777 { OUString("WrittenNumberStyles"), 0, cppu::UnoType<uno::Sequence<sal_Int32>>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
778 { OUString("UsePrettyPrinting"), 0, ::cppu::UnoType<sal_Bool>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
779 { OUString("BaseURI"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
780 { OUString("StreamRelPath"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
781 { OUString("StreamName"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
782 { OUString("StyleNames"), 0, cppu::UnoType<uno::Sequence<OUString>>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
783 { OUString("StyleFamilies"), 0, cppu::UnoType<uno::Sequence<sal_Int32>>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
784 { OUString("TargetStorage"), 0, cppu::UnoType<embed::XStorage>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
785 { OUString(), 0, css::uno::Type(), 0, 0 }
787 uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
789 if ( pObjSh && xStorage.is() )
791 uno::Reference<frame::XModel> xModel(pObjSh->GetModel());
792 uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator());
793 sal_Int32 nProgressRange(1000000);
794 if(xStatusIndicator.is())
795 xStatusIndicator->start(ScGlobal::GetRscString(STR_SAVE_DOC), nProgressRange);
796 xInfoSet->setPropertyValue("ProgressRange", uno::makeAny(nProgressRange));
798 SvtSaveOptions aSaveOpt;
799 bool bUsePrettyPrinting(aSaveOpt.IsPrettyPrinting());
800 xInfoSet->setPropertyValue("UsePrettyPrinting", uno::makeAny(bUsePrettyPrinting));
802 const OUString sTargetStorage("TargetStorage");
803 xInfoSet->setPropertyValue( sTargetStorage, uno::Any( xStorage ) );
805 OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
806 OUString aBaseURL = pMedium ? pMedium->GetBaseURL( true ) : OUString();
807 OUString sPropName("BaseURI");
808 xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
810 // TODO/LATER: do not do it for embedded links
811 if( SfxObjectCreateMode::EMBEDDED == pObjSh->GetCreateMode() )
813 OUString aName("dummyObjectName");
814 if ( pMedium && pMedium->GetItemSet() )
816 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
817 pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
818 if ( pDocHierarchItem )
819 aName = pDocHierarchItem->GetValue();
822 if( !aName.isEmpty() )
824 sPropName = "StreamRelPath";
825 xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
829 bool bMetaRet(pObjSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED);
830 bool bStylesRet (false);
831 bool bDocRet(false);
832 bool bSettingsRet(false);
833 ScMySharedData* pSharedData = NULL;
835 bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
837 // RDF metadata: ODF >= 1.2
838 if ( !bStylesOnly && bOasis )
840 const uno::Reference< beans::XPropertySet > xPropSet( xStorage, uno::UNO_QUERY_THROW );
843 OUString aVersion;
844 if (( xPropSet->getPropertyValue(
845 OUString("Version")) >>= aVersion )
846 && aVersion != ODFVER_010_TEXT
847 && aVersion != ODFVER_011_TEXT )
849 const uno::Reference< rdf::XDocumentMetadataAccess > xDMA(
850 xModel, uno::UNO_QUERY_THROW );
851 xDMA->storeMetadataToStorage( xStorage );
854 catch ( const beans::UnknownPropertyException &)
857 catch ( const uno::Exception &)
862 // meta export
863 if (!bStylesOnly && !bMetaRet)
865 uno::Sequence<uno::Any> aMetaArgs(3);
866 uno::Any* pMetaArgs = aMetaArgs.getArray();
867 pMetaArgs[0] <<= xInfoSet;
868 pMetaArgs[1] <<= xWriter;
869 pMetaArgs[2] <<= xStatusIndicator;
871 SAL_INFO( "sc.filter", "meta export start" );
873 bMetaRet = ExportToComponent(xContext, xModel, xWriter, aDescriptor,
874 OUString("meta.xml"),
875 sTextMediaType,
876 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisMetaExporter")
877 : OUString("com.sun.star.comp.Calc.XMLMetaExporter"),
878 aMetaArgs, pSharedData);
880 SAL_INFO( "sc.filter", "meta export end" );
883 uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
884 SvXMLEmbeddedObjectHelper *pObjectHelper = 0;
886 uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
887 SvXMLGraphicHelper* pGraphicHelper = 0;
889 if( xStorage.is() )
891 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, false );
892 xGrfContainer = pGraphicHelper;
895 if( pObjSh )
897 pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, false );
898 xObjectResolver = pObjectHelper;
901 // styles export
904 uno::Sequence<uno::Any> aStylesArgs(5);
905 uno::Any* pStylesArgs = aStylesArgs.getArray();
906 pStylesArgs[0] <<= xInfoSet;
907 pStylesArgs[1] <<= xGrfContainer;
908 pStylesArgs[2] <<= xStatusIndicator;
909 pStylesArgs[3] <<= xWriter;
910 pStylesArgs[4] <<= xObjectResolver;
912 SAL_INFO( "sc.filter", "styles export start" );
914 bStylesRet = ExportToComponent(xContext, xModel, xWriter, aDescriptor,
915 OUString("styles.xml"),
916 sTextMediaType,
917 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisStylesExporter")
918 : OUString("com.sun.star.comp.Calc.XMLStylesExporter"),
919 aStylesArgs, pSharedData);
921 SAL_INFO( "sc.filter", "styles export end" );
924 // content export
926 if (!bStylesOnly)
928 uno::Sequence<uno::Any> aDocArgs(5);
929 uno::Any* pDocArgs = aDocArgs.getArray();
930 pDocArgs[0] <<= xInfoSet;
931 pDocArgs[1] <<= xGrfContainer;
932 pDocArgs[2] <<= xStatusIndicator;
933 pDocArgs[3] <<= xWriter;
934 pDocArgs[4] <<= xObjectResolver;
936 SAL_INFO( "sc.filter", "content export start" );
938 bDocRet = ExportToComponent(xContext, xModel, xWriter, aDescriptor,
939 OUString("content.xml"),
940 sTextMediaType,
941 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisContentExporter")
942 : OUString("com.sun.star.comp.Calc.XMLContentExporter"),
943 aDocArgs, pSharedData);
945 SAL_INFO( "sc.filter", "content export end" );
948 if( pGraphicHelper )
949 SvXMLGraphicHelper::Destroy( pGraphicHelper );
951 if( pObjectHelper )
952 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
954 // settings export
956 if (!bStylesOnly)
958 uno::Sequence<uno::Any> aSettingsArgs(3);
959 uno::Any* pSettingsArgs = aSettingsArgs.getArray();
960 pSettingsArgs[0] <<= xInfoSet;
961 pSettingsArgs[1] <<= xWriter;
962 pSettingsArgs[2] <<= xStatusIndicator;
964 SAL_INFO( "sc.filter", "settings export start" );
966 bSettingsRet = ExportToComponent(xContext, xModel, xWriter, aDescriptor,
967 OUString("settings.xml"),
968 sTextMediaType,
969 bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisSettingsExporter")
970 : OUString("com.sun.star.comp.Calc.XMLSettingsExporter"),
971 aSettingsArgs, pSharedData);
973 SAL_INFO( "sc.filter", "settings export end" );
976 delete pSharedData;
978 if (xStatusIndicator.is())
979 xStatusIndicator->end();
980 return bStylesRet && ((!bStylesOnly && bDocRet && bMetaRet && bSettingsRet) || bStylesOnly);
983 // later: give string descriptor as parameter for doc type
985 return false;
988 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */