update dev300-m58
[ooovba.git] / sc / source / filter / xml / xmlwrap.cxx
blob14ec417e3c0fda515b44d7ba5d2af82bf48b532b
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 if( bEncrypted )
269 nReturn = ERRCODE_SFX_WRONGPASSWORD;
270 else
273 #ifdef DBG_UTIL
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() );
277 #endif
279 String sErr( String::CreateFromInt32( r.LineNumber ));
280 sErr += ',';
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),
288 sDocName, sErr,
289 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
291 else
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 )
301 if( bEncrypted )
302 nReturn = ERRCODE_SFX_WRONGPASSWORD;
303 else
306 #ifdef DBG_UTIL
307 ByteString aError( "SAX exception catched while importing:\n" );
308 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
309 DBG_ERROR( aError.GetBuffer() );
310 #endif
311 (void)r; // avoid warning in product version
313 nReturn = SCERR_IMPORT_FORMAT;
316 catch( packages::zip::ZipIOException& r )
318 #ifdef DBG_UTIL
319 ByteString aError( "Zip exception catched while importing:\n" );
320 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
321 DBG_ERROR( aError.GetBuffer() );
322 #endif
323 (void)r; // avoid warning in product version
325 nReturn = ERRCODE_IO_BROKENPACKAGE;
327 catch( io::IOException& r )
329 #ifdef DBG_UTIL
330 ByteString aError( "IO exception catched while importing:\n" );
331 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
332 DBG_ERROR( aError.GetBuffer() );
333 #endif
334 (void)r; // avoid warning in product version
336 nReturn = SCERR_IMPORT_OPEN;
338 catch( uno::Exception& r )
340 #ifdef DBG_UTIL
341 ByteString aError( "uno exception catched while importing:\n" );
342 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
343 DBG_ERROR( aError.GetBuffer() );
344 #endif
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 );
361 // success!
362 return nReturn;
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() )
373 return sal_False;
375 xml::sax::InputSource aParserInput;
376 if (pMedium)
377 aParserInput.sSystemId = OUString(pMedium->GetName());
379 if ( !xStorage.is() && pMedium )
380 xStorage = pMedium->GetStorage();
382 // get parser
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() )
388 return sal_False;
390 // get filter
391 SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
392 if ( pObjSh )
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 );
417 if( xChild.is() )
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));
441 // Set base URI
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() )
450 OUString aName;
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();
458 else
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);
471 if(!bStylesOnly)
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,
484 sal_False);
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;
495 if( xStorage.is() )
497 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
498 xGrfContainer = pGraphicHelper;
500 if( pObjSh )
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);
514 if (!bStylesOnly)
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);
548 if (!bStylesOnly)
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,
564 sal_True);
566 RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import end" );
568 if( pGraphicHelper )
569 SvXMLGraphicHelper::Destroy( pGraphicHelper );
571 if( pObjectHelper )
572 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
574 if (xStatusIndicator.is())
575 xStatusIndicator->end();
577 sal_Bool bRet(sal_False);
578 if (bStylesOnly)
580 if (nStylesRetval)
581 nError = nStylesRetval;
582 else
583 bRet = sal_True;
585 else
587 if (nDocRetval)
589 nError = nDocRetval;
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)
594 bRet = sal_True;
596 else if (nStylesRetval)
597 nError = nStylesRetval;
598 else if (nMetaRetval)
599 nError = nMetaRetval;
600 else if (nSettingsRetval)
601 nError = nSettingsRetval;
602 else
603 bRet = sal_True;
606 // set BuildId on XModel for later OLE object loading
607 if( xInfoSet.is() )
609 uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
610 if( xModelSet.is() )
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;
624 return sal_False;
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() )
637 return false;
639 SCTAB nTabCount = rDoc.GetTableCount();
640 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
641 if (rDoc.IsStreamValid(nTab))
642 return true;
643 return false;
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();
659 if( xStorage.is() )
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 );
667 if (xSet.is())
669 xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType));
670 OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
671 if (bPlainText)
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();
686 // set Base URL
687 uno::Reference< beans::XPropertySet > xInfoSet;
688 if( aArgs.getLength() > 0 )
689 aArgs.getConstArray()[0] >>= xInfoSet;
690 DBG_ASSERT( xInfoSet.is(), "missing property set" );
691 if( xInfoSet.is() )
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 ),
702 uno::UNO_QUERY );
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 );
706 if (xExporter.is())
707 xExporter->setSourceDocument( xComponent );
709 if ( xFilter.is() )
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 );
732 if (xSrcStream.is())
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.
745 if (!bRet)
747 SCTAB nTabCount = rDoc.GetTableCount();
748 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
749 if (rDoc.IsStreamValid(nTab))
750 rDoc.SetStreamValid(nTab, FALSE);
753 else
754 bRet = xFilter->filter( aDescriptor );
756 pSharedData = pExport->GetSharedData();
758 //stream is closed by SAX parser
759 //if (xOut.is())
760 // xOut->closeOutput();
762 return bRet;
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() )
772 return sal_False;
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" );
777 if(!xWriter.is())
778 return sal_False;
780 if ( !xStorage.is() && pMedium )
781 xStorage = pMedium->GetOutputStorage();
783 uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY );
785 OUString sFileName;
786 OUString sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml"));
787 if (pMedium)
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 );
863 // meta export
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")),
876 sTextMediaType,
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;
890 if( xStorage.is() )
892 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, FALSE );
893 xGrfContainer = pGraphicHelper;
896 if( pObjSh )
898 pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, sal_False );
899 xObjectResolver = pObjectHelper;
902 // styles export
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")),
917 sTextMediaType,
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" );
925 // content export
927 if (!bStylesOnly)
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")),
941 sTextMediaType,
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" );
949 if( pGraphicHelper )
950 SvXMLGraphicHelper::Destroy( pGraphicHelper );
952 if( pObjectHelper )
953 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
955 // settings export
957 if (!bStylesOnly)
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")),
969 sTextMediaType,
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" );
977 if (pSharedData)
978 delete pSharedData;
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
987 return sal_False;