Update ooo320-m1
[ooovba.git] / sc / source / filter / xml / xmlwrap.cxx
blob0784df1ee69fd698e1b21e801e8f65e3183fbe30
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"
80 #include "global.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 ) :
93 rDoc(rD),
94 pMedium(pM),
95 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)
102 //UNUSED2008-05 {
103 //UNUSED2008-05 DBG_ERROR( "The status indicator from medium must be used!" );
104 //UNUSED2008-05
105 //UNUSED2008-05 uno::Reference<task::XStatusIndicator> xStatusIndicator;
106 //UNUSED2008-05
107 //UNUSED2008-05 if (rModel.is())
108 //UNUSED2008-05 {
109 //UNUSED2008-05 uno::Reference<frame::XController> xController( rModel->getCurrentController());
110 //UNUSED2008-05 if ( xController.is())
111 //UNUSED2008-05 {
112 //UNUSED2008-05 uno::Reference<task::XStatusIndicatorFactory> xFactory( xController->getFrame(), uno::UNO_QUERY );
113 //UNUSED2008-05 if ( xFactory.is())
114 //UNUSED2008-05 {
115 //UNUSED2008-05 try
116 //UNUSED2008-05 {
117 //UNUSED2008-05 xStatusIndicator.set(xFactory->createStatusIndicator());
118 //UNUSED2008-05 }
119 //UNUSED2008-05 catch ( lang::DisposedException e )
120 //UNUSED2008-05 {
121 //UNUSED2008-05 DBG_ERROR("Exception while trying to get a Status Indicator");
122 //UNUSED2008-05 }
123 //UNUSED2008-05 }
124 //UNUSED2008-05 }
125 //UNUSED2008-05 }
126 //UNUSED2008-05 return xStatusIndicator;
127 //UNUSED2008-05 }
129 uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator()
131 uno::Reference<task::XStatusIndicator> xStatusIndicator;
132 if (pMedium)
134 SfxItemSet* pSet = pMedium->GetItemSet();
135 if (pSet)
137 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL));
138 if (pItem)
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);
163 if( xStorage.is() )
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;
175 else
176 return sal_False;
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") ) );
182 aAny >>= bEncrypted;
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" );
205 if( !xSource.is() )
206 return sal_False;
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" );
213 if( !xPipe.is() )
214 return sal_False;
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 );
223 else
224 return SCERR_IMPORT_UNKNOWN;
226 // set Base URL
227 uno::Reference< beans::XPropertySet > xInfoSet;
228 if( aArgs.getLength() > 0 )
229 aArgs.getConstArray()[0] >>= xInfoSet;
230 DBG_ASSERT( xInfoSet.is(), "missing property set" );
231 if( xInfoSet.is() )
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 ),
243 uno::UNO_QUERY );
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 );
247 if (xImporter.is())
248 xImporter->setTargetDocument( xComponent );
250 // connect parser and filter
251 uno::Reference<xml::sax::XParser> xParser( xXMLParser, uno::UNO_QUERY );
252 xParser->setDocumentHandler( xDocHandler );
254 // parse
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;
273 while( bTryChild )
275 xml::sax::SAXException aTmp;
276 if ( aSaxEx.WrappedException >>= aTmp )
277 aSaxEx = aTmp;
278 else
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;
287 else
290 #ifdef DBG_UTIL
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() );
294 #endif
296 String sErr( String::CreateFromInt32( r.LineNumber ));
297 sErr += ',';
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),
305 sDocName, sErr,
306 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
308 else
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;
323 else
326 #ifdef DBG_UTIL
327 ByteString aError( "SAX exception catched while importing:\n" );
328 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
329 DBG_ERROR( aError.GetBuffer() );
330 #endif
331 (void)r; // avoid warning in product version
333 nReturn = SCERR_IMPORT_FORMAT;
336 catch( packages::zip::ZipIOException& r )
338 #ifdef DBG_UTIL
339 ByteString aError( "Zip exception catched while importing:\n" );
340 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
341 DBG_ERROR( aError.GetBuffer() );
342 #endif
343 (void)r; // avoid warning in product version
345 nReturn = ERRCODE_IO_BROKENPACKAGE;
347 catch( io::IOException& r )
349 #ifdef DBG_UTIL
350 ByteString aError( "IO exception catched while importing:\n" );
351 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
352 DBG_ERROR( aError.GetBuffer() );
353 #endif
354 (void)r; // avoid warning in product version
356 nReturn = SCERR_IMPORT_OPEN;
358 catch( uno::Exception& r )
360 #ifdef DBG_UTIL
361 ByteString aError( "uno exception catched while importing:\n" );
362 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
363 DBG_ERROR( aError.GetBuffer() );
364 #endif
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 );
381 // success!
382 return nReturn;
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() )
393 return sal_False;
395 xml::sax::InputSource aParserInput;
396 if (pMedium)
397 aParserInput.sSystemId = OUString(pMedium->GetName());
399 if ( !xStorage.is() && pMedium )
400 xStorage = pMedium->GetStorage();
402 // get parser
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() )
408 return sal_False;
410 // get filter
411 SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
412 if ( pObjSh )
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 );
437 if( xChild.is() )
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));
461 // Set base URI
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() )
470 OUString aName;
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();
478 else
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);
491 if(!bStylesOnly)
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,
504 sal_False);
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;
515 if( xStorage.is() )
517 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
518 xGrfContainer = pGraphicHelper;
520 if( pObjSh )
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);
534 if (!bStylesOnly)
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);
568 if (!bStylesOnly)
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,
584 sal_True);
586 RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import end" );
588 if( pGraphicHelper )
589 SvXMLGraphicHelper::Destroy( pGraphicHelper );
591 if( pObjectHelper )
592 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
594 if (xStatusIndicator.is())
595 xStatusIndicator->end();
597 sal_Bool bRet(sal_False);
598 if (bStylesOnly)
600 if (nStylesRetval)
601 nError = nStylesRetval;
602 else
603 bRet = sal_True;
605 else
607 if (nDocRetval)
609 nError = nDocRetval;
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)
614 bRet = sal_True;
616 else if (nStylesRetval)
617 nError = nStylesRetval;
618 else if (nMetaRetval)
619 nError = nMetaRetval;
620 else if (nSettingsRetval)
621 nError = nSettingsRetval;
622 else
623 bRet = sal_True;
626 // set BuildId on XModel for later OLE object loading
627 if( xInfoSet.is() )
629 uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
630 if( xModelSet.is() )
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;
644 return sal_False;
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() )
657 return false;
659 SCTAB nTabCount = rDoc.GetTableCount();
660 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
661 if (rDoc.IsStreamValid(nTab))
662 return true;
663 return false;
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();
679 if( xStorage.is() )
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 );
687 if (xSet.is())
689 xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType));
690 OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
691 if (bPlainText)
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();
706 // set Base URL
707 uno::Reference< beans::XPropertySet > xInfoSet;
708 if( aArgs.getLength() > 0 )
709 aArgs.getConstArray()[0] >>= xInfoSet;
710 DBG_ASSERT( xInfoSet.is(), "missing property set" );
711 if( xInfoSet.is() )
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 ),
722 uno::UNO_QUERY );
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 );
726 if (xExporter.is())
727 xExporter->setSourceDocument( xComponent );
729 if ( xFilter.is() )
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 );
752 if (xSrcStream.is())
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.
765 if (!bRet)
767 SCTAB nTabCount = rDoc.GetTableCount();
768 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
769 if (rDoc.IsStreamValid(nTab))
770 rDoc.SetStreamValid(nTab, FALSE);
773 else
774 bRet = xFilter->filter( aDescriptor );
776 pSharedData = pExport->GetSharedData();
778 //stream is closed by SAX parser
779 //if (xOut.is())
780 // xOut->closeOutput();
782 return bRet;
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() )
792 return sal_False;
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" );
797 if(!xWriter.is())
798 return sal_False;
800 if ( !xStorage.is() && pMedium )
801 xStorage = pMedium->GetOutputStorage();
803 uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY );
805 OUString sFileName;
806 OUString sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml"));
807 if (pMedium)
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 );
883 // meta export
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")),
896 sTextMediaType,
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;
910 if( xStorage.is() )
912 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, FALSE );
913 xGrfContainer = pGraphicHelper;
916 if( pObjSh )
918 pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, sal_False );
919 xObjectResolver = pObjectHelper;
922 // styles export
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")),
937 sTextMediaType,
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" );
945 // content export
947 if (!bStylesOnly)
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")),
961 sTextMediaType,
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" );
969 if( pGraphicHelper )
970 SvXMLGraphicHelper::Destroy( pGraphicHelper );
972 if( pObjectHelper )
973 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
975 // settings export
977 if (!bStylesOnly)
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")),
989 sTextMediaType,
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" );
997 if (pSharedData)
998 delete pSharedData;
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
1007 return sal_False;