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/.
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"
68 #include "globstr.hrc"
69 #include "scerrors.hxx"
70 #include "XMLExportSharedData.hxx"
72 #include "sheetdata.hxx"
73 #include "XMLCodeNameProvider.hxx"
75 #include <unonames.hxx>
77 using namespace com::sun::star
;
79 ScXMLImportWrapper::ScXMLImportWrapper( ScDocShell
& rDocSh
, SfxMedium
* pM
, const uno::Reference
< embed::XStorage
>& xStor
) :
81 rDoc(rDocSh
.GetDocument()),
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
;
93 SfxItemSet
* pSet
= pMedium
->GetItemSet();
96 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
));
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
);
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
;
132 aParserInput
.aInputStream
= xDocStream
->getInputStream();
133 uno::Reference
< beans::XPropertySet
> xSet( xDocStream
, uno::UNO_QUERY
);
135 uno::Any aAny
= xSet
->getPropertyValue("Encrypted");
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
;
152 return SCERR_IMPORT_UNKNOWN
;
155 uno::Reference
< beans::XPropertySet
> xInfoSet
;
156 if( aArgs
.getLength() > 0 )
157 aArgs
.getConstArray()[0] >>= xInfoSet
;
158 OSL_ENSURE( xInfoSet
.is(), "missing property set" );
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
),
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
);
176 xImporter
->setTargetDocument( xComponent
);
178 ScXMLImport
* pImporterImpl
= dynamic_cast<ScXMLImport
*>(xImporter
.get());
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;
198 xml::sax::SAXException aTmp
;
199 if ( aSaxEx
.WrappedException
>>= aTmp
)
205 packages::zip::ZipIOException aBrokenPackage
;
206 if ( aSaxEx
.WrappedException
>>= aBrokenPackage
)
207 return ERRCODE_IO_BROKENPACKAGE
;
208 else if( bEncrypted
)
209 nReturn
= ERRCODE_SFX_WRONGPASSWORD
;
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());
219 OUString sErr
= OUString::number( r
.LineNumber
) +
221 OUString::number( r
.ColumnNumber
);
223 if( !sDocName
.isEmpty() )
225 nReturn
= *new TwoStringErrorInfo(
226 (bMustBeSuccessfull
? SCERR_IMPORT_FILE_ROWCOL
227 : SCWARN_IMPORT_FILE_ROWCOL
),
229 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
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
;
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());
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() );
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());
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());
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
);
312 bool ScXMLImportWrapper::Import( sal_uInt8 nMode
, ErrCode
& rError
)
314 uno::Reference
<uno::XComponentContext
> xContext
= comphelper::getProcessComponentContext();
316 xml::sax::InputSource aParserInput
;
318 aParserInput
.sSystemId
= pMedium
->GetName();
320 if ( !xStorage
.is() && pMedium
)
321 xStorage
= pMedium
->GetStorage();
324 uno::Reference
<xml::sax::XParser
> xXMLParser
= xml::sax::Parser::create(xContext
);
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
);
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
));
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
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();
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
;
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
;
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
,
544 SAL_INFO( "sc.filter", "content import end" );
547 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
550 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
552 if (xStatusIndicator
.is())
553 xStatusIndicator
->end();
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
)
565 else if (nStylesRetval
)
566 rError
= nStylesRetval
;
567 else if (nMetaRetval
)
568 rError
= nMetaRetval
;
569 else if (nSettingsRetval
)
570 rError
= nSettingsRetval
;
574 // set BuildId on XModel for later OLE object loading
577 uno::Reference
< beans::XPropertySet
> xModelSet( xModel
, uno::UNO_QUERY
);
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
) );
589 uno::Any aAny
= xInfoSet
->getPropertyValue("ScriptConfiguration");
590 uno::Reference
<container::XNameAccess
> xCodeNameAccess
;
591 if( aAny
>>= xCodeNameAccess
)
592 XMLCodeNameProvider::set( xCodeNameAccess
, &rDoc
);
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() )
629 SCTAB nTabCount
= rDoc
.GetTableCount();
630 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
631 if (rDoc
.IsStreamValid(nTab
))
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
)
643 uno::Reference
<io::XOutputStream
> xOut
;
644 uno::Reference
<io::XStream
> xStream
;
646 if ( !xStorage
.is() && pMedium
)
647 xStorage
= pMedium
->GetOutputStorage();
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
);
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();
670 uno::Reference
< beans::XPropertySet
> xInfoSet
;
671 if( aArgs
.getLength() > 0 )
672 aArgs
.getConstArray()[0] >>= xInfoSet
;
673 OSL_ENSURE( xInfoSet
.is(), "missing property set" );
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
),
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
);
690 xExporter
->setSourceDocument( xComponent
);
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
);
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);
742 bRet
= xFilter
->filter( aDescriptor
);
744 pSharedData
= pExport
->GetSharedData();
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();
762 OUString
sTextMediaType("text/xml");
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);
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
);
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
&)
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"),
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;
891 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
, GRAPHICHELPER_MODE_WRITE
, false );
892 xGrfContainer
= pGraphicHelper
;
897 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create( xStorage
, *pObjSh
, EMBEDDEDOBJECTHELPER_MODE_WRITE
, false );
898 xObjectResolver
= pObjectHelper
;
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"),
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" );
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"),
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" );
949 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
952 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
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"),
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" );
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
988 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */