1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlwrap.cxx,v $
10 * $Revision: 1.69.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include <rsc/rscsfx.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <sfx2/objsh.hxx>
41 #include <tools/debug.hxx>
42 #include <vos/xception.hxx>
43 #include <comphelper/processfactory.hxx>
44 #include <unotools/streamwrap.hxx>
45 #include <svx/xmlgrhlp.hxx>
46 #include <svtools/sfxecode.hxx>
47 #include <sfx2/frame.hxx>
48 #include <svtools/itemset.hxx>
49 #include <svtools/stritem.hxx>
50 #include <sfx2/sfxsids.hrc>
51 #include <tools/urlobj.hxx>
52 #include <com/sun/star/container/XChild.hpp>
53 #include <com/sun/star/beans/XPropertySetInfo.hpp>
54 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
55 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
56 #include <com/sun/star/xml/sax/InputSource.hpp>
57 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
58 #include <com/sun/star/xml/sax/XParser.hpp>
59 #include <com/sun/star/io/XActiveDataSource.hpp>
60 #include <com/sun/star/io/XActiveDataControl.hpp>
61 #include <com/sun/star/frame/XModel.hpp>
62 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
63 #include <com/sun/star/beans/PropertyAttribute.hpp>
64 #include <comphelper/extract.hxx>
65 #include <comphelper/propertysetinfo.hxx>
66 #include <comphelper/genericpropertyset.hxx>
67 #include <com/sun/star/container/XNameContainer.hpp>
68 #include <com/sun/star/lang/DisposedException.hpp>
69 #include <com/sun/star/packages/zip/ZipIOException.hpp>
70 #include <com/sun/star/embed/ElementModes.hpp>
72 #include <svx/xmleohlp.hxx>
73 #include <rtl/logfile.hxx>
74 #include <svtools/saveopt.hxx>
76 #include "document.hxx"
77 #include "xmlwrap.hxx"
78 #include "xmlimprt.hxx"
79 #include "xmlexprt.hxx"
81 #include "globstr.hrc"
82 #include "scerrors.hxx"
83 #include "XMLExportSharedData.hxx"
85 #define MAP_LEN(x) x, sizeof(x) - 1
87 using namespace com::sun::star
;
88 using ::rtl::OUString
;
90 // -----------------------------------------------------------------------
92 ScXMLImportWrapper::ScXMLImportWrapper(ScDocument
& rD
, SfxMedium
* pM
, const uno::Reference
< embed::XStorage
>& xStor
) :
97 DBG_ASSERT( pMedium
|| xStorage
.is(), "ScXMLImportWrapper: Medium or Storage must be set" );
100 //UNUSED2008-05 uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator(
101 //UNUSED2008-05 uno::Reference < frame::XModel> & rModel)
103 //UNUSED2008-05 DBG_ERROR( "The status indicator from medium must be used!" );
105 //UNUSED2008-05 uno::Reference<task::XStatusIndicator> xStatusIndicator;
107 //UNUSED2008-05 if (rModel.is())
109 //UNUSED2008-05 uno::Reference<frame::XController> xController( rModel->getCurrentController());
110 //UNUSED2008-05 if ( xController.is())
112 //UNUSED2008-05 uno::Reference<task::XStatusIndicatorFactory> xFactory( xController->getFrame(), uno::UNO_QUERY );
113 //UNUSED2008-05 if ( xFactory.is())
117 //UNUSED2008-05 xStatusIndicator.set(xFactory->createStatusIndicator());
119 //UNUSED2008-05 catch ( lang::DisposedException e )
121 //UNUSED2008-05 DBG_ERROR("Exception while trying to get a Status Indicator");
126 //UNUSED2008-05 return xStatusIndicator;
129 uno::Reference
<task::XStatusIndicator
> ScXMLImportWrapper::GetStatusIndicator()
131 uno::Reference
<task::XStatusIndicator
> xStatusIndicator
;
134 SfxItemSet
* pSet
= pMedium
->GetItemSet();
137 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
));
139 xStatusIndicator
.set(pItem
->GetValue(), uno::UNO_QUERY
);
142 return xStatusIndicator
;
145 sal_uInt32
ScXMLImportWrapper::ImportFromComponent(uno::Reference
<lang::XMultiServiceFactory
>& xServiceFactory
,
146 uno::Reference
<frame::XModel
>& xModel
, uno::Reference
<uno::XInterface
>& xXMLParser
,
147 xml::sax::InputSource
& aParserInput
,
148 const rtl::OUString
& sComponentName
, const rtl::OUString
& sDocName
,
149 const rtl::OUString
& sOldDocName
, uno::Sequence
<uno::Any
>& aArgs
,
150 sal_Bool bMustBeSuccessfull
)
152 uno::Reference
< io::XStream
> xDocStream
;
153 if ( !xStorage
.is() && pMedium
)
154 xStorage
= pMedium
->GetStorage();
156 // Get data source ...
158 // uno::Reference< uno::XInterface > xPipe;
159 // uno::Reference< io::XActiveDataSource > xSource;
161 sal_Bool bEncrypted
= sal_False
;
162 rtl::OUString
sStream(sDocName
);
167 uno::Reference
< container::XNameAccess
> xAccess( xStorage
, uno::UNO_QUERY
);
168 if ( xAccess
->hasByName(sDocName
) && xStorage
->isStreamElement( sDocName
) )
169 xDocStream
= xStorage
->openStreamElement( sDocName
, embed::ElementModes::READ
);
170 else if (sOldDocName
.getLength() && xAccess
->hasByName(sOldDocName
) && xStorage
->isStreamElement( sOldDocName
) )
172 xDocStream
= xStorage
->openStreamElement( sOldDocName
, embed::ElementModes::READ
);
173 sStream
= sOldDocName
;
178 aParserInput
.aInputStream
= xDocStream
->getInputStream();
179 uno::Reference
< beans::XPropertySet
> xSet( xDocStream
, uno::UNO_QUERY
);
181 uno::Any aAny
= xSet
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
184 catch( packages::WrongPasswordException
& )
186 return ERRCODE_SFX_WRONGPASSWORD
;
188 catch( packages::zip::ZipIOException
& )
190 return ERRCODE_IO_BROKENPACKAGE
;
192 catch( uno::Exception
& )
194 return SCERR_IMPORT_UNKNOWN
;
197 // #99667#; no longer necessary
198 /* else if ( pMedium )
200 // if there is a medium and if this medium has a load environment,
201 // we get an active data source from the medium.
202 pMedium->GetInStream()->Seek( 0 );
203 xSource = pMedium->GetDataSource();
204 DBG_ASSERT( xSource.is(), "got no data source from medium" );
208 // get a pipe for connecting the data source to the parser
209 xPipe = xServiceFactory->createInstance(
210 OUString::createFromAscii("com.sun.star.io.Pipe") );
211 DBG_ASSERT( xPipe.is(),
212 "XMLReader::Read: com.sun.star.io.Pipe service missing" );
216 // connect pipe's output stream to the data source
217 uno::Reference<io::XOutputStream> xPipeOutput( xPipe, uno::UNO_QUERY );
218 xSource->setOutputStream( xPipeOutput );
220 aParserInput.aInputStream =
221 uno::Reference< io::XInputStream >( xPipe, uno::UNO_QUERY );
224 return SCERR_IMPORT_UNKNOWN
;
227 uno::Reference
< beans::XPropertySet
> xInfoSet
;
228 if( aArgs
.getLength() > 0 )
229 aArgs
.getConstArray()[0] >>= xInfoSet
;
230 DBG_ASSERT( xInfoSet
.is(), "missing property set" );
233 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
234 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( sStream
) );
237 sal_uInt32
nReturn(0);
238 rDoc
.SetRangeOverflowType(0); // is modified by the importer if limits are exceeded
240 uno::Reference
<xml::sax::XDocumentHandler
> xDocHandler(
241 xServiceFactory
->createInstanceWithArguments(
242 sComponentName
, aArgs
),
244 DBG_ASSERT( xDocHandler
.is(), "can't get Calc importer" );
245 uno::Reference
<document::XImporter
> xImporter( xDocHandler
, uno::UNO_QUERY
);
246 uno::Reference
<lang::XComponent
> xComponent( xModel
, uno::UNO_QUERY
);
248 xImporter
->setTargetDocument( xComponent
);
250 // connect parser and filter
251 uno::Reference
<xml::sax::XParser
> xParser( xXMLParser
, uno::UNO_QUERY
);
252 xParser
->setDocumentHandler( xDocHandler
);
255 /* if( xSource.is() )
257 uno::Reference<io::XActiveDataControl> xSourceControl( xSource, uno::UNO_QUERY );
258 if( xSourceControl.is() )
259 xSourceControl->start();
264 xParser
->parseStream( aParserInput
);
266 catch( xml::sax::SAXParseException
& r
)
268 // sax parser sends wrapped exceptions,
269 // try to find the original one
270 xml::sax::SAXException aSaxEx
= *(xml::sax::SAXException
*)(&r
);
271 sal_Bool bTryChild
= sal_True
;
275 xml::sax::SAXException aTmp
;
276 if ( aSaxEx
.WrappedException
>>= aTmp
)
279 bTryChild
= sal_False
;
282 packages::zip::ZipIOException aBrokenPackage
;
283 if ( aSaxEx
.WrappedException
>>= aBrokenPackage
)
284 return ERRCODE_IO_BROKENPACKAGE
;
285 else if( bEncrypted
)
286 nReturn
= ERRCODE_SFX_WRONGPASSWORD
;
291 ByteString
aError( "SAX parse exception catched while importing:\n" );
292 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
293 DBG_ERROR( aError
.GetBuffer() );
296 String
sErr( String::CreateFromInt32( r
.LineNumber
));
298 sErr
+= String::CreateFromInt32( r
.ColumnNumber
);
300 if( sDocName
.getLength() )
302 nReturn
= *new TwoStringErrorInfo(
303 (bMustBeSuccessfull
? SCERR_IMPORT_FILE_ROWCOL
304 : SCWARN_IMPORT_FILE_ROWCOL
),
306 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
310 DBG_ASSERT( bMustBeSuccessfull
, "Warnings are not supported" );
311 nReturn
= *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL
, sErr
,
312 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
316 catch( xml::sax::SAXException
& r
)
318 packages::zip::ZipIOException aBrokenPackage
;
319 if ( r
.WrappedException
>>= aBrokenPackage
)
320 return ERRCODE_IO_BROKENPACKAGE
;
321 else if( bEncrypted
)
322 nReturn
= ERRCODE_SFX_WRONGPASSWORD
;
327 ByteString
aError( "SAX exception catched while importing:\n" );
328 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
329 DBG_ERROR( aError
.GetBuffer() );
331 (void)r
; // avoid warning in product version
333 nReturn
= SCERR_IMPORT_FORMAT
;
336 catch( packages::zip::ZipIOException
& r
)
339 ByteString
aError( "Zip exception catched while importing:\n" );
340 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
341 DBG_ERROR( aError
.GetBuffer() );
343 (void)r
; // avoid warning in product version
345 nReturn
= ERRCODE_IO_BROKENPACKAGE
;
347 catch( io::IOException
& r
)
350 ByteString
aError( "IO exception catched while importing:\n" );
351 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
352 DBG_ERROR( aError
.GetBuffer() );
354 (void)r
; // avoid warning in product version
356 nReturn
= SCERR_IMPORT_OPEN
;
358 catch( uno::Exception
& r
)
361 ByteString
aError( "uno exception catched while importing:\n" );
362 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
363 DBG_ERROR( aError
.GetBuffer() );
365 (void)r
; // avoid warning in product version
367 nReturn
= SCERR_IMPORT_UNKNOWN
;
370 // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler,
371 // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer.
372 // So the overflow warning ErrorCode is now stored in the document.
373 // Export works differently, there getImplementation still works.
375 if (rDoc
.HasRangeOverflow() && !nReturn
)
376 nReturn
= rDoc
.GetRangeOverflowType();
378 // free the component
379 xParser
->setDocumentHandler( NULL
);
385 sal_Bool
ScXMLImportWrapper::Import(sal_Bool bStylesOnly
, ErrCode
& nError
)
387 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog
, "sc", "sb99857", "ScXMLImportWrapper::Import" );
389 uno::Reference
<lang::XMultiServiceFactory
> xServiceFactory
=
390 comphelper::getProcessServiceFactory();
391 DBG_ASSERT( xServiceFactory
.is(), "got no service manager" );
392 if( !xServiceFactory
.is() )
395 xml::sax::InputSource aParserInput
;
397 aParserInput
.sSystemId
= OUString(pMedium
->GetName());
399 if ( !xStorage
.is() && pMedium
)
400 xStorage
= pMedium
->GetStorage();
403 uno::Reference
<uno::XInterface
> xXMLParser(
404 xServiceFactory
->createInstance(
405 OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) ));
406 DBG_ASSERT( xXMLParser
.is(), "com.sun.star.xml.sax.Parser service missing" );
407 if( !xXMLParser
.is() )
411 SfxObjectShell
* pObjSh
= rDoc
.GetDocumentShell();
414 rtl::OUString sEmpty
;
415 uno::Reference
<frame::XModel
> xModel(pObjSh
->GetModel());
417 /** property map for export info set */
418 comphelper::PropertyMapEntry aImportInfoMap
[] =
420 { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
421 { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
422 { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
423 { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference
<container::XNameAccess
> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
424 { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference
<uno::XInterface
> *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
425 { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
426 { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
427 { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
428 { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
430 { NULL
, 0, 0, NULL
, 0, 0 }
432 uno::Reference
< beans::XPropertySet
> xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap
) ) );
434 // ---- get BuildId from parent container if available
436 uno::Reference
< container::XChild
> xChild( xModel
, uno::UNO_QUERY
);
439 uno::Reference
< beans::XPropertySet
> xParentSet( xChild
->getParent(), uno::UNO_QUERY
);
440 if( xParentSet
.is() )
442 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xParentSet
->getPropertySetInfo() );
443 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
444 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(sPropName
) )
446 xInfoSet
->setPropertyValue( sPropName
, xParentSet
->getPropertyValue(sPropName
) );
451 // -------------------------------------
453 uno::Reference
<task::XStatusIndicator
> xStatusIndicator(GetStatusIndicator());
454 if (xStatusIndicator
.is())
456 sal_Int32
nProgressRange(1000000);
457 xStatusIndicator
->start(rtl::OUString(ScGlobal::GetRscString(STR_LOAD_DOC
)), nProgressRange
);
458 xInfoSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange
));
462 OSL_ENSURE( pMedium
, "There is no medium to get MediaDescriptor from!\n" );
463 ::rtl::OUString aBaseURL
= pMedium
? pMedium
->GetBaseURL() : ::rtl::OUString();
464 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
465 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aBaseURL
) );
467 // TODO/LATER: do not do it for embedded links
468 if( SFX_CREATE_MODE_EMBEDDED
== pObjSh
->GetCreateMode() )
471 if ( pMedium
&& pMedium
->GetItemSet() )
473 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
474 pMedium
->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
475 if ( pDocHierarchItem
)
476 aName
= pDocHierarchItem
->GetValue();
479 aName
= ::rtl::OUString::createFromAscii( "dummyObjectName" );
481 if( aName
.getLength() )
483 sPropName
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
484 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aName
) );
488 sal_Bool bOasis
= ( SotStorage::GetVersion( xStorage
) > SOFFICE_FILEFORMAT_60
);
490 sal_uInt32
nMetaRetval(0);
493 uno::Sequence
<uno::Any
> aMetaArgs(1);
494 uno::Any
* pMetaArgs
= aMetaArgs
.getArray();
495 pMetaArgs
[0] <<= xInfoSet
;
497 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta import start" );
499 nMetaRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
500 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter"))
501 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")),
502 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
503 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs
,
506 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta import end" );
509 SvXMLGraphicHelper
* pGraphicHelper
= NULL
;
510 uno::Reference
< document::XGraphicObjectResolver
> xGrfContainer
;
512 uno::Reference
< document::XEmbeddedObjectResolver
> xObjectResolver
;
513 SvXMLEmbeddedObjectHelper
*pObjectHelper
= NULL
;
517 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
, GRAPHICHELPER_MODE_READ
);
518 xGrfContainer
= pGraphicHelper
;
522 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create(xStorage
, *pObjSh
, EMBEDDEDOBJECTHELPER_MODE_READ
, sal_False
);
523 xObjectResolver
= pObjectHelper
;
526 uno::Sequence
<uno::Any
> aStylesArgs(4);
527 uno::Any
* pStylesArgs
= aStylesArgs
.getArray();
528 pStylesArgs
[0] <<= xInfoSet
;
529 pStylesArgs
[1] <<= xGrfContainer
;
530 pStylesArgs
[2] <<= xStatusIndicator
;
531 pStylesArgs
[3] <<= xObjectResolver
;
533 sal_uInt32
nSettingsRetval(0);
536 // Settings must be loaded first because of the printer setting,
537 // which is needed in the page styles (paper tray).
539 uno::Sequence
<uno::Any
> aSettingsArgs(1);
540 uno::Any
* pSettingsArgs
= aSettingsArgs
.getArray();
541 pSettingsArgs
[0] <<= xInfoSet
;
543 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings import start" );
545 nSettingsRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
546 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsImporter"))
547 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsImporter")),
548 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
549 sEmpty
, aSettingsArgs
, sal_False
);
551 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings import end" );
554 sal_uInt32
nStylesRetval(0);
556 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles import start" );
558 nStylesRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
559 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesImporter"))
560 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesImporter")),
561 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
562 sEmpty
, aStylesArgs
, sal_True
);
564 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles import end" );
567 sal_uInt32
nDocRetval(0);
570 uno::Sequence
<uno::Any
> aDocArgs(4);
571 uno::Any
* pDocArgs
= aDocArgs
.getArray();
572 pDocArgs
[0] <<= xInfoSet
;
573 pDocArgs
[1] <<= xGrfContainer
;
574 pDocArgs
[2] <<= xStatusIndicator
;
575 pDocArgs
[3] <<= xObjectResolver
;
577 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content import start" );
579 nDocRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
580 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentImporter"))
581 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentImporter")),
582 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml")),
583 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content.xml")), aDocArgs
,
586 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content import end" );
589 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
592 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
594 if (xStatusIndicator
.is())
595 xStatusIndicator
->end();
597 sal_Bool
bRet(sal_False
);
601 nError
= nStylesRetval
;
610 if (nDocRetval
== SCWARN_IMPORT_RANGE_OVERFLOW
||
611 nDocRetval
== SCWARN_IMPORT_ROW_OVERFLOW
||
612 nDocRetval
== SCWARN_IMPORT_COLUMN_OVERFLOW
||
613 nDocRetval
== SCWARN_IMPORT_SHEET_OVERFLOW
)
616 else if (nStylesRetval
)
617 nError
= nStylesRetval
;
618 else if (nMetaRetval
)
619 nError
= nMetaRetval
;
620 else if (nSettingsRetval
)
621 nError
= nSettingsRetval
;
626 // set BuildId on XModel for later OLE object loading
629 uno::Reference
< beans::XPropertySet
> xModelSet( xModel
, uno::UNO_QUERY
);
632 uno::Reference
< beans::XPropertySetInfo
> xModelSetInfo( xModelSet
->getPropertySetInfo() );
633 OUString
sBuildPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
634 if( xModelSetInfo
.is() && xModelSetInfo
->hasPropertyByName(sBuildPropName
) )
636 xModelSet
->setPropertyValue( sBuildPropName
, xInfoSet
->getPropertyValue(sBuildPropName
) );
641 // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
642 return bRet
;//!bStylesOnly ? bDocRetval : bStylesRetval;
647 bool lcl_HasValidStream(ScDocument
& rDoc
)
649 SfxObjectShell
* pObjSh
= rDoc
.GetDocumentShell();
650 if ( pObjSh
->IsDocShared() )
651 return false; // never copy stream from shared file
653 // don't read remote file again
654 // (could instead re-use medium directly in that case)
655 SfxMedium
* pSrcMed
= rDoc
.GetDocumentShell()->GetMedium();
656 if ( !pSrcMed
|| pSrcMed
->IsRemote() )
659 SCTAB nTabCount
= rDoc
.GetTableCount();
660 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
661 if (rDoc
.IsStreamValid(nTab
))
666 sal_Bool
ScXMLImportWrapper::ExportToComponent(uno::Reference
<lang::XMultiServiceFactory
>& xServiceFactory
,
667 uno::Reference
<frame::XModel
>& xModel
, uno::Reference
<uno::XInterface
>& xWriter
,
668 uno::Sequence
<beans::PropertyValue
>& aDescriptor
, const rtl::OUString
& sName
,
669 const rtl::OUString
& sMediaType
, const rtl::OUString
& sComponentName
,
670 const sal_Bool bPlainText
, uno::Sequence
<uno::Any
>& aArgs
, ScMySharedData
*& pSharedData
)
672 sal_Bool
bRet(sal_False
);
673 uno::Reference
<io::XOutputStream
> xOut
;
674 uno::Reference
<io::XStream
> xStream
;
676 if ( !xStorage
.is() && pMedium
)
677 xStorage
= pMedium
->GetOutputStorage();
681 // #96807#; trunc stream before use, because it could be an existing stream
682 // and the new content could be shorter than the old content. In this case
683 // would not all be over written by the new content and the xml file
684 // would not be valid.
685 xStream
= xStorage
->openStreamElement( sName
, embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
686 uno::Reference
< beans::XPropertySet
> xSet( xStream
, uno::UNO_QUERY
);
689 xSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType
));
690 OUString
aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
692 xSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), uno::makeAny(sal_False
));
694 // even plain stream should be encrypted in encrypted documents
695 xSet
->setPropertyValue( aUseCommonPassPropName
, uno::makeAny(sal_True
) );
698 xOut
= xStream
->getOutputStream();
700 // #99667#; no longer necessary
701 /* else if ( pMedium )
703 xOut = pMedium->GetDataSink();
707 uno::Reference
< beans::XPropertySet
> xInfoSet
;
708 if( aArgs
.getLength() > 0 )
709 aArgs
.getConstArray()[0] >>= xInfoSet
;
710 DBG_ASSERT( xInfoSet
.is(), "missing property set" );
713 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
714 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( sName
) );
717 uno::Reference
<io::XActiveDataSource
> xSrc( xWriter
, uno::UNO_QUERY
);
718 xSrc
->setOutputStream( xOut
);
720 uno::Reference
<document::XFilter
> xFilter(
721 xServiceFactory
->createInstanceWithArguments( sComponentName
, aArgs
),
723 DBG_ASSERT( xFilter
.is(), "can't get exporter" );
724 uno::Reference
<document::XExporter
> xExporter( xFilter
, uno::UNO_QUERY
);
725 uno::Reference
<lang::XComponent
> xComponent( xModel
, uno::UNO_QUERY
);
727 xExporter
->setSourceDocument( xComponent
);
731 ScXMLExport
* pExport
= static_cast<ScXMLExport
*>(SvXMLExport::getImplementation(xFilter
));
732 pExport
->SetSharedData(pSharedData
);
734 // if there are sheets to copy, get the source stream
735 if ( sName
.equalsAscii("content.xml") && lcl_HasValidStream(rDoc
) &&
736 ( pExport
->getExportFlags() & EXPORT_OASIS
) )
738 // old stream is still in this file's storage - open read-only
740 SfxMedium
* pSrcMed
= rDoc
.GetDocumentShell()->GetMedium();
741 String aSrcURL
= pSrcMed
->GetOrigURL();
743 // SfxMedium must not be read-only, or it will create a temp file in GetStorage
744 SfxMedium
aTmpMedium( aSrcURL
, STREAM_READWRITE
, FALSE
, NULL
, NULL
);
745 uno::Reference
<embed::XStorage
> xTmpStorage
= aTmpMedium
.GetStorage();
746 uno::Reference
<io::XStream
> xSrcStream
;
747 uno::Reference
<io::XInputStream
> xSrcInput
;
750 if (xTmpStorage
.is())
751 xSrcStream
= xTmpStorage
->openStreamElement( sName
, embed::ElementModes::READ
);
753 xSrcInput
= xSrcStream
->getInputStream();
755 catch (uno::Exception
&)
757 // stream not available (for example, password protected) - save normally (xSrcInput is null)
760 pExport
->SetSourceStream( xSrcInput
);
761 bRet
= xFilter
->filter( aDescriptor
);
762 pExport
->SetSourceStream( uno::Reference
<io::XInputStream
>() );
764 // If there was an error, reset all stream flags, so the next save attempt will use normal saving.
767 SCTAB nTabCount
= rDoc
.GetTableCount();
768 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
769 if (rDoc
.IsStreamValid(nTab
))
770 rDoc
.SetStreamValid(nTab
, FALSE
);
774 bRet
= xFilter
->filter( aDescriptor
);
776 pSharedData
= pExport
->GetSharedData();
778 //stream is closed by SAX parser
780 // xOut->closeOutput();
785 sal_Bool
ScXMLImportWrapper::Export(sal_Bool bStylesOnly
)
787 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog
, "sc", "sb99857", "ScXMLImportWrapper::Export" );
789 uno::Reference
<lang::XMultiServiceFactory
> xServiceFactory(comphelper::getProcessServiceFactory());
790 DBG_ASSERT( xServiceFactory
.is(), "got no service manager" );
791 if( !xServiceFactory
.is() )
794 uno::Reference
<uno::XInterface
> xWriter(xServiceFactory
->createInstance(
795 OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) ));
796 DBG_ASSERT( xWriter
.is(), "com.sun.star.xml.sax.Writer service missing" );
800 if ( !xStorage
.is() && pMedium
)
801 xStorage
= pMedium
->GetOutputStorage();
803 uno::Reference
<xml::sax::XDocumentHandler
> xHandler( xWriter
, uno::UNO_QUERY
);
806 OUString
sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml"));
808 sFileName
= pMedium
->GetName();
809 SfxObjectShell
* pObjSh
= rDoc
.GetDocumentShell();
810 uno::Sequence
<beans::PropertyValue
> aDescriptor(1);
811 beans::PropertyValue
* pProps
= aDescriptor
.getArray();
812 pProps
[0].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
813 pProps
[0].Value
<<= sFileName
;
815 /** property map for export info set */
816 comphelper::PropertyMapEntry aExportInfoMap
[] =
818 { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
819 { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
820 { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
821 { MAP_LEN( "WrittenNumberStyles" ), 0, &::getCppuType((uno::Sequence
<sal_Int32
>*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
822 { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
823 { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
824 { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
825 { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
826 { MAP_LEN( "StyleNames" ), 0, &::getCppuType( (uno::Sequence
<rtl::OUString
>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
827 { MAP_LEN( "StyleFamilies" ), 0, &::getCppuType( (uno::Sequence
<sal_Int32
>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
828 { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
829 { NULL
, 0, 0, NULL
, 0, 0 }
831 uno::Reference
< beans::XPropertySet
> xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap
) ) );
833 if ( pObjSh
&& xStorage
.is() )
835 pObjSh
->UpdateDocInfoForSave(); // update information
837 uno::Reference
<frame::XModel
> xModel(pObjSh
->GetModel());
838 uno::Reference
<task::XStatusIndicator
> xStatusIndicator(GetStatusIndicator());
839 sal_Int32
nProgressRange(1000000);
840 if(xStatusIndicator
.is())
841 xStatusIndicator
->start(rtl::OUString(ScGlobal::GetRscString(STR_SAVE_DOC
)), nProgressRange
);
842 xInfoSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange
));
844 SvtSaveOptions aSaveOpt
;
845 sal_Bool
bUsePrettyPrinting(aSaveOpt
.IsPrettyPrinting());
846 xInfoSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(bUsePrettyPrinting
));
848 const OUString
sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") );
849 xInfoSet
->setPropertyValue( sTargetStorage
, uno::Any( xStorage
) );
851 OSL_ENSURE( pMedium
, "There is no medium to get MediaDescriptor from!\n" );
852 ::rtl::OUString aBaseURL
= pMedium
? pMedium
->GetBaseURL( true ) : ::rtl::OUString();
853 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
854 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aBaseURL
) );
856 // TODO/LATER: do not do it for embedded links
857 if( SFX_CREATE_MODE_EMBEDDED
== pObjSh
->GetCreateMode() )
859 OUString aName
= ::rtl::OUString::createFromAscii( "dummyObjectName" );
860 if ( pMedium
&& pMedium
->GetItemSet() )
862 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
863 pMedium
->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
864 if ( pDocHierarchItem
)
865 aName
= pDocHierarchItem
->GetValue();
868 if( aName
.getLength() )
870 sPropName
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
871 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aName
) );
875 sal_Bool
bMetaRet(pObjSh
->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
);
876 sal_Bool
bStylesRet (sal_False
);
877 sal_Bool
bDocRet(sal_False
);
878 sal_Bool
bSettingsRet(sal_False
);
879 ScMySharedData
* pSharedData
= NULL
;
881 sal_Bool bOasis
= ( SotStorage::GetVersion( xStorage
) > SOFFICE_FILEFORMAT_60
);
884 if (!bStylesOnly
&& !bMetaRet
)
886 uno::Sequence
<uno::Any
> aMetaArgs(3);
887 uno::Any
* pMetaArgs
= aMetaArgs
.getArray();
888 pMetaArgs
[0] <<= xInfoSet
;
889 pMetaArgs
[1] <<= xHandler
;
890 pMetaArgs
[2] <<= xStatusIndicator
;
892 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta export start" );
894 bMetaRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
895 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
897 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaExporter"))
898 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaExporter")),
899 sal_True
, aMetaArgs
, pSharedData
);
901 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta export end" );
904 uno::Reference
< document::XEmbeddedObjectResolver
> xObjectResolver
;
905 SvXMLEmbeddedObjectHelper
*pObjectHelper
= 0;
907 uno::Reference
< document::XGraphicObjectResolver
> xGrfContainer
;
908 SvXMLGraphicHelper
* pGraphicHelper
= 0;
912 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
, GRAPHICHELPER_MODE_WRITE
, FALSE
);
913 xGrfContainer
= pGraphicHelper
;
918 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create( xStorage
, *pObjSh
, EMBEDDEDOBJECTHELPER_MODE_WRITE
, sal_False
);
919 xObjectResolver
= pObjectHelper
;
925 uno::Sequence
<uno::Any
> aStylesArgs(5);
926 uno::Any
* pStylesArgs
= aStylesArgs
.getArray();
927 pStylesArgs
[0] <<= xInfoSet
;
928 pStylesArgs
[1] <<= xGrfContainer
;
929 pStylesArgs
[2] <<= xStatusIndicator
;
930 pStylesArgs
[3] <<= xHandler
;
931 pStylesArgs
[4] <<= xObjectResolver
;
933 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles export start" );
935 bStylesRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
936 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
938 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesExporter"))
939 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesExporter")),
940 sal_False
, aStylesArgs
, pSharedData
);
942 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles export end" );
949 uno::Sequence
<uno::Any
> aDocArgs(5);
950 uno::Any
* pDocArgs
= aDocArgs
.getArray();
951 pDocArgs
[0] <<= xInfoSet
;
952 pDocArgs
[1] <<= xGrfContainer
;
953 pDocArgs
[2] <<= xStatusIndicator
;
954 pDocArgs
[3] <<= xHandler
;
955 pDocArgs
[4] <<= xObjectResolver
;
957 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content export start" );
959 bDocRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
960 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("content.xml")),
962 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentExporter"))
963 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentExporter")),
964 sal_False
, aDocArgs
, pSharedData
);
966 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content export end" );
970 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
973 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
979 uno::Sequence
<uno::Any
> aSettingsArgs(3);
980 uno::Any
* pSettingsArgs
= aSettingsArgs
.getArray();
981 pSettingsArgs
[0] <<= xInfoSet
;
982 pSettingsArgs
[1] <<= xHandler
;
983 pSettingsArgs
[2] <<= xStatusIndicator
;
985 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings export start" );
987 bSettingsRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
988 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
990 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsExporter"))
991 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsExporter")),
992 sal_False
, aSettingsArgs
, pSharedData
);
994 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings export end" );
1000 if (xStatusIndicator
.is())
1001 xStatusIndicator
->end();
1002 return bStylesRet
&& ((!bStylesOnly
&& bDocRet
&& bMetaRet
&& bSettingsRet
) || bStylesOnly
);
1005 // later: give string descriptor as parameter for doc type