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
)
269 nReturn
= ERRCODE_SFX_WRONGPASSWORD
;
274 ByteString
aError( "SAX parse exception catched while importing:\n" );
275 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
276 DBG_ERROR( aError
.GetBuffer() );
279 String
sErr( String::CreateFromInt32( r
.LineNumber
));
281 sErr
+= String::CreateFromInt32( r
.ColumnNumber
);
283 if( sDocName
.getLength() )
285 nReturn
= *new TwoStringErrorInfo(
286 (bMustBeSuccessfull
? SCERR_IMPORT_FILE_ROWCOL
287 : SCWARN_IMPORT_FILE_ROWCOL
),
289 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
293 DBG_ASSERT( bMustBeSuccessfull
, "Warnings are not supported" );
294 nReturn
= *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL
, sErr
,
295 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
299 catch( xml::sax::SAXException
& r
)
302 nReturn
= ERRCODE_SFX_WRONGPASSWORD
;
307 ByteString
aError( "SAX exception catched while importing:\n" );
308 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
309 DBG_ERROR( aError
.GetBuffer() );
311 (void)r
; // avoid warning in product version
313 nReturn
= SCERR_IMPORT_FORMAT
;
316 catch( packages::zip::ZipIOException
& r
)
319 ByteString
aError( "Zip exception catched while importing:\n" );
320 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
321 DBG_ERROR( aError
.GetBuffer() );
323 (void)r
; // avoid warning in product version
325 nReturn
= ERRCODE_IO_BROKENPACKAGE
;
327 catch( io::IOException
& r
)
330 ByteString
aError( "IO exception catched while importing:\n" );
331 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
332 DBG_ERROR( aError
.GetBuffer() );
334 (void)r
; // avoid warning in product version
336 nReturn
= SCERR_IMPORT_OPEN
;
338 catch( uno::Exception
& r
)
341 ByteString
aError( "uno exception catched while importing:\n" );
342 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
343 DBG_ERROR( aError
.GetBuffer() );
345 (void)r
; // avoid warning in product version
347 nReturn
= SCERR_IMPORT_UNKNOWN
;
350 // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler,
351 // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer.
352 // So the overflow warning ErrorCode is now stored in the document.
353 // Export works differently, there getImplementation still works.
355 if (rDoc
.HasRangeOverflow() && !nReturn
)
356 nReturn
= rDoc
.GetRangeOverflowType();
358 // free the component
359 xParser
->setDocumentHandler( NULL
);
365 sal_Bool
ScXMLImportWrapper::Import(sal_Bool bStylesOnly
, ErrCode
& nError
)
367 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog
, "sc", "sb99857", "ScXMLImportWrapper::Import" );
369 uno::Reference
<lang::XMultiServiceFactory
> xServiceFactory
=
370 comphelper::getProcessServiceFactory();
371 DBG_ASSERT( xServiceFactory
.is(), "got no service manager" );
372 if( !xServiceFactory
.is() )
375 xml::sax::InputSource aParserInput
;
377 aParserInput
.sSystemId
= OUString(pMedium
->GetName());
379 if ( !xStorage
.is() && pMedium
)
380 xStorage
= pMedium
->GetStorage();
383 uno::Reference
<uno::XInterface
> xXMLParser(
384 xServiceFactory
->createInstance(
385 OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) ));
386 DBG_ASSERT( xXMLParser
.is(), "com.sun.star.xml.sax.Parser service missing" );
387 if( !xXMLParser
.is() )
391 SfxObjectShell
* pObjSh
= rDoc
.GetDocumentShell();
394 rtl::OUString sEmpty
;
395 uno::Reference
<frame::XModel
> xModel(pObjSh
->GetModel());
397 /** property map for export info set */
398 comphelper::PropertyMapEntry aImportInfoMap
[] =
400 { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
401 { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
402 { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
403 { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference
<container::XNameAccess
> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
404 { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference
<uno::XInterface
> *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
405 { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
406 { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
407 { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
408 { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
410 { NULL
, 0, 0, NULL
, 0, 0 }
412 uno::Reference
< beans::XPropertySet
> xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap
) ) );
414 // ---- get BuildId from parent container if available
416 uno::Reference
< container::XChild
> xChild( xModel
, uno::UNO_QUERY
);
419 uno::Reference
< beans::XPropertySet
> xParentSet( xChild
->getParent(), uno::UNO_QUERY
);
420 if( xParentSet
.is() )
422 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xParentSet
->getPropertySetInfo() );
423 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
424 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(sPropName
) )
426 xInfoSet
->setPropertyValue( sPropName
, xParentSet
->getPropertyValue(sPropName
) );
431 // -------------------------------------
433 uno::Reference
<task::XStatusIndicator
> xStatusIndicator(GetStatusIndicator());
434 if (xStatusIndicator
.is())
436 sal_Int32
nProgressRange(1000000);
437 xStatusIndicator
->start(rtl::OUString(ScGlobal::GetRscString(STR_LOAD_DOC
)), nProgressRange
);
438 xInfoSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange
));
442 OSL_ENSURE( pMedium
, "There is no medium to get MediaDescriptor from!\n" );
443 ::rtl::OUString aBaseURL
= pMedium
? pMedium
->GetBaseURL() : ::rtl::OUString();
444 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
445 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aBaseURL
) );
447 // TODO/LATER: do not do it for embedded links
448 if( SFX_CREATE_MODE_EMBEDDED
== pObjSh
->GetCreateMode() )
451 if ( pMedium
&& pMedium
->GetItemSet() )
453 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
454 pMedium
->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
455 if ( pDocHierarchItem
)
456 aName
= pDocHierarchItem
->GetValue();
459 aName
= ::rtl::OUString::createFromAscii( "dummyObjectName" );
461 if( aName
.getLength() )
463 sPropName
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
464 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aName
) );
468 sal_Bool bOasis
= ( SotStorage::GetVersion( xStorage
) > SOFFICE_FILEFORMAT_60
);
470 sal_uInt32
nMetaRetval(0);
473 uno::Sequence
<uno::Any
> aMetaArgs(1);
474 uno::Any
* pMetaArgs
= aMetaArgs
.getArray();
475 pMetaArgs
[0] <<= xInfoSet
;
477 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta import start" );
479 nMetaRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
480 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter"))
481 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")),
482 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
483 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs
,
486 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta import end" );
489 SvXMLGraphicHelper
* pGraphicHelper
= NULL
;
490 uno::Reference
< document::XGraphicObjectResolver
> xGrfContainer
;
492 uno::Reference
< document::XEmbeddedObjectResolver
> xObjectResolver
;
493 SvXMLEmbeddedObjectHelper
*pObjectHelper
= NULL
;
497 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
, GRAPHICHELPER_MODE_READ
);
498 xGrfContainer
= pGraphicHelper
;
502 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create(xStorage
, *pObjSh
, EMBEDDEDOBJECTHELPER_MODE_READ
, sal_False
);
503 xObjectResolver
= pObjectHelper
;
506 uno::Sequence
<uno::Any
> aStylesArgs(4);
507 uno::Any
* pStylesArgs
= aStylesArgs
.getArray();
508 pStylesArgs
[0] <<= xInfoSet
;
509 pStylesArgs
[1] <<= xGrfContainer
;
510 pStylesArgs
[2] <<= xStatusIndicator
;
511 pStylesArgs
[3] <<= xObjectResolver
;
513 sal_uInt32
nSettingsRetval(0);
516 // Settings must be loaded first because of the printer setting,
517 // which is needed in the page styles (paper tray).
519 uno::Sequence
<uno::Any
> aSettingsArgs(1);
520 uno::Any
* pSettingsArgs
= aSettingsArgs
.getArray();
521 pSettingsArgs
[0] <<= xInfoSet
;
523 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings import start" );
525 nSettingsRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
526 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsImporter"))
527 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsImporter")),
528 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
529 sEmpty
, aSettingsArgs
, sal_False
);
531 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings import end" );
534 sal_uInt32
nStylesRetval(0);
536 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles import start" );
538 nStylesRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
539 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesImporter"))
540 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesImporter")),
541 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
542 sEmpty
, aStylesArgs
, sal_True
);
544 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles import end" );
547 sal_uInt32
nDocRetval(0);
550 uno::Sequence
<uno::Any
> aDocArgs(4);
551 uno::Any
* pDocArgs
= aDocArgs
.getArray();
552 pDocArgs
[0] <<= xInfoSet
;
553 pDocArgs
[1] <<= xGrfContainer
;
554 pDocArgs
[2] <<= xStatusIndicator
;
555 pDocArgs
[3] <<= xObjectResolver
;
557 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content import start" );
559 nDocRetval
= ImportFromComponent(xServiceFactory
, xModel
, xXMLParser
, aParserInput
,
560 bOasis
? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentImporter"))
561 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentImporter")),
562 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml")),
563 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content.xml")), aDocArgs
,
566 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content import end" );
569 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
572 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
574 if (xStatusIndicator
.is())
575 xStatusIndicator
->end();
577 sal_Bool
bRet(sal_False
);
581 nError
= nStylesRetval
;
590 if (nDocRetval
== SCWARN_IMPORT_RANGE_OVERFLOW
||
591 nDocRetval
== SCWARN_IMPORT_ROW_OVERFLOW
||
592 nDocRetval
== SCWARN_IMPORT_COLUMN_OVERFLOW
||
593 nDocRetval
== SCWARN_IMPORT_SHEET_OVERFLOW
)
596 else if (nStylesRetval
)
597 nError
= nStylesRetval
;
598 else if (nMetaRetval
)
599 nError
= nMetaRetval
;
600 else if (nSettingsRetval
)
601 nError
= nSettingsRetval
;
606 // set BuildId on XModel for later OLE object loading
609 uno::Reference
< beans::XPropertySet
> xModelSet( xModel
, uno::UNO_QUERY
);
612 uno::Reference
< beans::XPropertySetInfo
> xModelSetInfo( xModelSet
->getPropertySetInfo() );
613 OUString
sBuildPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
614 if( xModelSetInfo
.is() && xModelSetInfo
->hasPropertyByName(sBuildPropName
) )
616 xModelSet
->setPropertyValue( sBuildPropName
, xInfoSet
->getPropertyValue(sBuildPropName
) );
621 // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
622 return bRet
;//!bStylesOnly ? bDocRetval : bStylesRetval;
627 bool lcl_HasValidStream(ScDocument
& rDoc
)
629 SfxObjectShell
* pObjSh
= rDoc
.GetDocumentShell();
630 if ( pObjSh
->IsDocShared() )
631 return false; // never copy stream from shared file
633 // don't read remote file again
634 // (could instead re-use medium directly in that case)
635 SfxMedium
* pSrcMed
= rDoc
.GetDocumentShell()->GetMedium();
636 if ( !pSrcMed
|| pSrcMed
->IsRemote() )
639 SCTAB nTabCount
= rDoc
.GetTableCount();
640 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
641 if (rDoc
.IsStreamValid(nTab
))
646 sal_Bool
ScXMLImportWrapper::ExportToComponent(uno::Reference
<lang::XMultiServiceFactory
>& xServiceFactory
,
647 uno::Reference
<frame::XModel
>& xModel
, uno::Reference
<uno::XInterface
>& xWriter
,
648 uno::Sequence
<beans::PropertyValue
>& aDescriptor
, const rtl::OUString
& sName
,
649 const rtl::OUString
& sMediaType
, const rtl::OUString
& sComponentName
,
650 const sal_Bool bPlainText
, uno::Sequence
<uno::Any
>& aArgs
, ScMySharedData
*& pSharedData
)
652 sal_Bool
bRet(sal_False
);
653 uno::Reference
<io::XOutputStream
> xOut
;
654 uno::Reference
<io::XStream
> xStream
;
656 if ( !xStorage
.is() && pMedium
)
657 xStorage
= pMedium
->GetOutputStorage();
661 // #96807#; trunc stream before use, because it could be an existing stream
662 // and the new content could be shorter than the old content. In this case
663 // would not all be over written by the new content and the xml file
664 // would not be valid.
665 xStream
= xStorage
->openStreamElement( sName
, embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
666 uno::Reference
< beans::XPropertySet
> xSet( xStream
, uno::UNO_QUERY
);
669 xSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType
));
670 OUString
aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
672 xSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), uno::makeAny(sal_False
));
674 // even plain stream should be encrypted in encrypted documents
675 xSet
->setPropertyValue( aUseCommonPassPropName
, uno::makeAny(sal_True
) );
678 xOut
= xStream
->getOutputStream();
680 // #99667#; no longer necessary
681 /* else if ( pMedium )
683 xOut = pMedium->GetDataSink();
687 uno::Reference
< beans::XPropertySet
> xInfoSet
;
688 if( aArgs
.getLength() > 0 )
689 aArgs
.getConstArray()[0] >>= xInfoSet
;
690 DBG_ASSERT( xInfoSet
.is(), "missing property set" );
693 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
694 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( sName
) );
697 uno::Reference
<io::XActiveDataSource
> xSrc( xWriter
, uno::UNO_QUERY
);
698 xSrc
->setOutputStream( xOut
);
700 uno::Reference
<document::XFilter
> xFilter(
701 xServiceFactory
->createInstanceWithArguments( sComponentName
, aArgs
),
703 DBG_ASSERT( xFilter
.is(), "can't get exporter" );
704 uno::Reference
<document::XExporter
> xExporter( xFilter
, uno::UNO_QUERY
);
705 uno::Reference
<lang::XComponent
> xComponent( xModel
, uno::UNO_QUERY
);
707 xExporter
->setSourceDocument( xComponent
);
711 ScXMLExport
* pExport
= static_cast<ScXMLExport
*>(SvXMLExport::getImplementation(xFilter
));
712 pExport
->SetSharedData(pSharedData
);
714 // if there are sheets to copy, get the source stream
715 if ( sName
.equalsAscii("content.xml") && lcl_HasValidStream(rDoc
) &&
716 ( pExport
->getExportFlags() & EXPORT_OASIS
) )
718 // old stream is still in this file's storage - open read-only
720 SfxMedium
* pSrcMed
= rDoc
.GetDocumentShell()->GetMedium();
721 String aSrcURL
= pSrcMed
->GetOrigURL();
723 // SfxMedium must not be read-only, or it will create a temp file in GetStorage
724 SfxMedium
aTmpMedium( aSrcURL
, STREAM_READWRITE
, FALSE
, NULL
, NULL
);
725 uno::Reference
<embed::XStorage
> xTmpStorage
= aTmpMedium
.GetStorage();
726 uno::Reference
<io::XStream
> xSrcStream
;
727 uno::Reference
<io::XInputStream
> xSrcInput
;
730 if (xTmpStorage
.is())
731 xSrcStream
= xTmpStorage
->openStreamElement( sName
, embed::ElementModes::READ
);
733 xSrcInput
= xSrcStream
->getInputStream();
735 catch (uno::Exception
&)
737 // stream not available (for example, password protected) - save normally (xSrcInput is null)
740 pExport
->SetSourceStream( xSrcInput
);
741 bRet
= xFilter
->filter( aDescriptor
);
742 pExport
->SetSourceStream( uno::Reference
<io::XInputStream
>() );
744 // If there was an error, reset all stream flags, so the next save attempt will use normal saving.
747 SCTAB nTabCount
= rDoc
.GetTableCount();
748 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
749 if (rDoc
.IsStreamValid(nTab
))
750 rDoc
.SetStreamValid(nTab
, FALSE
);
754 bRet
= xFilter
->filter( aDescriptor
);
756 pSharedData
= pExport
->GetSharedData();
758 //stream is closed by SAX parser
760 // xOut->closeOutput();
765 sal_Bool
ScXMLImportWrapper::Export(sal_Bool bStylesOnly
)
767 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog
, "sc", "sb99857", "ScXMLImportWrapper::Export" );
769 uno::Reference
<lang::XMultiServiceFactory
> xServiceFactory(comphelper::getProcessServiceFactory());
770 DBG_ASSERT( xServiceFactory
.is(), "got no service manager" );
771 if( !xServiceFactory
.is() )
774 uno::Reference
<uno::XInterface
> xWriter(xServiceFactory
->createInstance(
775 OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) ));
776 DBG_ASSERT( xWriter
.is(), "com.sun.star.xml.sax.Writer service missing" );
780 if ( !xStorage
.is() && pMedium
)
781 xStorage
= pMedium
->GetOutputStorage();
783 uno::Reference
<xml::sax::XDocumentHandler
> xHandler( xWriter
, uno::UNO_QUERY
);
786 OUString
sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml"));
788 sFileName
= pMedium
->GetName();
789 SfxObjectShell
* pObjSh
= rDoc
.GetDocumentShell();
790 uno::Sequence
<beans::PropertyValue
> aDescriptor(1);
791 beans::PropertyValue
* pProps
= aDescriptor
.getArray();
792 pProps
[0].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
793 pProps
[0].Value
<<= sFileName
;
795 /** property map for export info set */
796 comphelper::PropertyMapEntry aExportInfoMap
[] =
798 { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
799 { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
800 { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
801 { MAP_LEN( "WrittenNumberStyles" ), 0, &::getCppuType((uno::Sequence
<sal_Int32
>*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
802 { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool
*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0},
803 { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
804 { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
805 { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString
*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
806 { MAP_LEN( "StyleNames" ), 0, &::getCppuType( (uno::Sequence
<rtl::OUString
>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
807 { MAP_LEN( "StyleFamilies" ), 0, &::getCppuType( (uno::Sequence
<sal_Int32
>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
808 { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
809 { NULL
, 0, 0, NULL
, 0, 0 }
811 uno::Reference
< beans::XPropertySet
> xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap
) ) );
813 if ( pObjSh
&& xStorage
.is() )
815 pObjSh
->UpdateDocInfoForSave(); // update information
817 uno::Reference
<frame::XModel
> xModel(pObjSh
->GetModel());
818 uno::Reference
<task::XStatusIndicator
> xStatusIndicator(GetStatusIndicator());
819 sal_Int32
nProgressRange(1000000);
820 if(xStatusIndicator
.is())
821 xStatusIndicator
->start(rtl::OUString(ScGlobal::GetRscString(STR_SAVE_DOC
)), nProgressRange
);
822 xInfoSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange
));
824 SvtSaveOptions aSaveOpt
;
825 sal_Bool
bUsePrettyPrinting(aSaveOpt
.IsPrettyPrinting());
826 xInfoSet
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(bUsePrettyPrinting
));
828 const OUString
sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") );
829 xInfoSet
->setPropertyValue( sTargetStorage
, uno::Any( xStorage
) );
831 OSL_ENSURE( pMedium
, "There is no medium to get MediaDescriptor from!\n" );
832 ::rtl::OUString aBaseURL
= pMedium
? pMedium
->GetBaseURL( true ) : ::rtl::OUString();
833 rtl::OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
834 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aBaseURL
) );
836 // TODO/LATER: do not do it for embedded links
837 if( SFX_CREATE_MODE_EMBEDDED
== pObjSh
->GetCreateMode() )
839 OUString aName
= ::rtl::OUString::createFromAscii( "dummyObjectName" );
840 if ( pMedium
&& pMedium
->GetItemSet() )
842 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
843 pMedium
->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
844 if ( pDocHierarchItem
)
845 aName
= pDocHierarchItem
->GetValue();
848 if( aName
.getLength() )
850 sPropName
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
851 xInfoSet
->setPropertyValue( sPropName
, uno::makeAny( aName
) );
855 sal_Bool
bMetaRet(pObjSh
->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
);
856 sal_Bool
bStylesRet (sal_False
);
857 sal_Bool
bDocRet(sal_False
);
858 sal_Bool
bSettingsRet(sal_False
);
859 ScMySharedData
* pSharedData
= NULL
;
861 sal_Bool bOasis
= ( SotStorage::GetVersion( xStorage
) > SOFFICE_FILEFORMAT_60
);
864 if (!bStylesOnly
&& !bMetaRet
)
866 uno::Sequence
<uno::Any
> aMetaArgs(3);
867 uno::Any
* pMetaArgs
= aMetaArgs
.getArray();
868 pMetaArgs
[0] <<= xInfoSet
;
869 pMetaArgs
[1] <<= xHandler
;
870 pMetaArgs
[2] <<= xStatusIndicator
;
872 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta export start" );
874 bMetaRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
875 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
877 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaExporter"))
878 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaExporter")),
879 sal_True
, aMetaArgs
, pSharedData
);
881 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "meta export end" );
884 uno::Reference
< document::XEmbeddedObjectResolver
> xObjectResolver
;
885 SvXMLEmbeddedObjectHelper
*pObjectHelper
= 0;
887 uno::Reference
< document::XGraphicObjectResolver
> xGrfContainer
;
888 SvXMLGraphicHelper
* pGraphicHelper
= 0;
892 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
, GRAPHICHELPER_MODE_WRITE
, FALSE
);
893 xGrfContainer
= pGraphicHelper
;
898 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create( xStorage
, *pObjSh
, EMBEDDEDOBJECTHELPER_MODE_WRITE
, sal_False
);
899 xObjectResolver
= pObjectHelper
;
905 uno::Sequence
<uno::Any
> aStylesArgs(5);
906 uno::Any
* pStylesArgs
= aStylesArgs
.getArray();
907 pStylesArgs
[0] <<= xInfoSet
;
908 pStylesArgs
[1] <<= xGrfContainer
;
909 pStylesArgs
[2] <<= xStatusIndicator
;
910 pStylesArgs
[3] <<= xHandler
;
911 pStylesArgs
[4] <<= xObjectResolver
;
913 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles export start" );
915 bStylesRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
916 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
918 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesExporter"))
919 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesExporter")),
920 sal_False
, aStylesArgs
, pSharedData
);
922 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "styles export end" );
929 uno::Sequence
<uno::Any
> aDocArgs(5);
930 uno::Any
* pDocArgs
= aDocArgs
.getArray();
931 pDocArgs
[0] <<= xInfoSet
;
932 pDocArgs
[1] <<= xGrfContainer
;
933 pDocArgs
[2] <<= xStatusIndicator
;
934 pDocArgs
[3] <<= xHandler
;
935 pDocArgs
[4] <<= xObjectResolver
;
937 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content export start" );
939 bDocRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
940 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("content.xml")),
942 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentExporter"))
943 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentExporter")),
944 sal_False
, aDocArgs
, pSharedData
);
946 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "content export end" );
950 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
953 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
959 uno::Sequence
<uno::Any
> aSettingsArgs(3);
960 uno::Any
* pSettingsArgs
= aSettingsArgs
.getArray();
961 pSettingsArgs
[0] <<= xInfoSet
;
962 pSettingsArgs
[1] <<= xHandler
;
963 pSettingsArgs
[2] <<= xStatusIndicator
;
965 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings export start" );
967 bSettingsRet
= ExportToComponent(xServiceFactory
, xModel
, xWriter
, aDescriptor
,
968 rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
970 bOasis
? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsExporter"))
971 : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsExporter")),
972 sal_False
, aSettingsArgs
, pSharedData
);
974 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "settings export end" );
980 if (xStatusIndicator
.is())
981 xStatusIndicator
->end();
982 return bStylesRet
&& ((!bStylesOnly
&& bDocRet
&& bMetaRet
&& bSettingsRet
) || bStylesOnly
);
985 // later: give string descriptor as parameter for doc type