/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: xmlwrap.cxx,v $ * * $Revision: 1.68 $ * * last change: $Author: rt $ $Date: 2008-03-12 13:17:13 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- #include #include #include #ifndef _TOOLS_DEBUG_HXX #include #endif #include #include #include #include #include #ifndef _SFXFRAME_HXX #include #endif #ifndef _SFXITEMSET_HXX #include #endif #ifndef _SFXSTRITEM_HXX #include #endif #ifndef _SFXSIDS_HRC #include #endif #ifndef _URLOBJ_HXX #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_ #include #endif #include #include #include #include #include #include #include #include #ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATORFACTORY_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HXX_ #include #endif #ifndef _COMPHELPER_EXTRACT_HXX_ #include #endif #ifndef _COMPHELPER_PROPERTSETINFO_HXX_ #include #endif #ifndef _COMPHELPER_GENERICPROPERTYSET_HXX_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ #include #endif #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPIOEXCEPTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HXX_ #include #endif #ifndef _XMLEOHLP_HXX #include #endif #ifndef _RTL_LOGFILE_HXX_ #include #endif #ifndef INCLUDED_SVTOOLS_SAVEOPT_HXX #include #endif #include "document.hxx" #include "xmlwrap.hxx" #include "xmlimprt.hxx" #include "xmlexprt.hxx" #ifndef SC_SCGLOB_HXX #include "global.hxx" #endif #ifndef __GLOBSTR_HRC_ #include "globstr.hrc" #endif #ifndef _SCERRORS_HXX #include "scerrors.hxx" #endif #ifndef SC_XMLEXPORTSHAREDDATA_HXX #include "XMLExportSharedData.hxx" #endif #ifndef SEQTYPE #if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500) #define SEQTYPE(x) (new ::com::sun::star::uno::Type( x )) #else #define SEQTYPE(x) &(x) #endif #endif #define MAP_LEN(x) x, sizeof(x) - 1 using namespace com::sun::star; // ----------------------------------------------------------------------- ScXMLImportWrapper::ScXMLImportWrapper(ScDocument& rD, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) : rDoc(rD), pMedium(pM), xStorage(xStor) { DBG_ASSERT( pMedium || xStorage.is(), "ScXMLImportWrapper: Medium or Storage must be set" ); } uno::Reference ScXMLImportWrapper::GetStatusIndicator( uno::Reference < frame::XModel> & rModel) { DBG_ERROR( "The status indicator from medium must be used!" ); uno::Reference xStatusIndicator; if (rModel.is()) { uno::Reference xController( rModel->getCurrentController()); if( xController.is()) { uno::Reference xFactory( xController->getFrame(), uno::UNO_QUERY ); if( xFactory.is()) { try { xStatusIndicator.set(xFactory->createStatusIndicator()); } catch( lang::DisposedException e ) { DBG_ERROR("Exception while trying to get a Status Indicator"); } } } } return xStatusIndicator; } uno::Reference ScXMLImportWrapper::GetStatusIndicator() { uno::Reference xStatusIndicator; if (pMedium) { SfxItemSet* pSet = pMedium->GetItemSet(); if (pSet) { const SfxUnoAnyItem* pItem = static_cast(pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL)); if (pItem) xStatusIndicator.set(pItem->GetValue(), uno::UNO_QUERY); } } return xStatusIndicator; } sal_uInt32 ScXMLImportWrapper::ImportFromComponent(uno::Reference& xServiceFactory, uno::Reference& xModel, uno::Reference& xXMLParser, xml::sax::InputSource& aParserInput, const rtl::OUString& sComponentName, const rtl::OUString& sDocName, const rtl::OUString& sOldDocName, uno::Sequence& aArgs, sal_Bool bMustBeSuccessfull) { uno::Reference < io::XStream > xDocStream; if ( !xStorage.is() && pMedium ) xStorage = pMedium->GetStorage(); // Get data source ... // uno::Reference< uno::XInterface > xPipe; // uno::Reference< io::XActiveDataSource > xSource; sal_Bool bEncrypted = sal_False; rtl::OUString sStream(sDocName); if( xStorage.is() ) { try { uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY ); if ( xAccess->hasByName(sDocName) && xStorage->isStreamElement( sDocName) ) xDocStream = xStorage->openStreamElement( sDocName, embed::ElementModes::READ ); else if (sOldDocName.getLength() && xAccess->hasByName(sOldDocName) && xStorage->isStreamElement( sOldDocName) ) { xDocStream = xStorage->openStreamElement( sOldDocName, embed::ElementModes::READ ); sStream = sOldDocName; } else return sal_False; aParserInput.aInputStream = xDocStream->getInputStream(); uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY ); uno::Any aAny = xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) ); aAny >>= bEncrypted; } catch( packages::WrongPasswordException& ) { return ERRCODE_SFX_WRONGPASSWORD; } catch( packages::zip::ZipIOException& ) { return ERRCODE_IO_BROKENPACKAGE; } catch( uno::Exception& ) { return SCERR_IMPORT_UNKNOWN; } } // #99667#; no longer necessary /* else if ( pMedium ) { // if there is a medium and if this medium has a load environment, // we get an active data source from the medium. pMedium->GetInStream()->Seek( 0 ); xSource = pMedium->GetDataSource(); DBG_ASSERT( xSource.is(), "got no data source from medium" ); if( !xSource.is() ) return sal_False; // get a pipe for connecting the data source to the parser xPipe = xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.io.Pipe") ); DBG_ASSERT( xPipe.is(), "XMLReader::Read: com.sun.star.io.Pipe service missing" ); if( !xPipe.is() ) return sal_False; // connect pipe's output stream to the data source uno::Reference xPipeOutput( xPipe, uno::UNO_QUERY ); xSource->setOutputStream( xPipeOutput ); aParserInput.aInputStream = uno::Reference< io::XInputStream >( xPipe, uno::UNO_QUERY ); }*/ else return SCERR_IMPORT_UNKNOWN; // set Base URL uno::Reference< beans::XPropertySet > xInfoSet; if( aArgs.getLength() > 0 ) aArgs.getConstArray()[0] >>= xInfoSet; DBG_ASSERT( xInfoSet.is(), "missing property set" ); if( xInfoSet.is() ) { rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") ); xInfoSet->setPropertyValue( sPropName, uno::makeAny( sStream ) ); } sal_uInt32 nReturn(0); rDoc.SetRangeOverflowType(0); // is modified by the importer if limits are exceeded uno::Reference xDocHandler( xServiceFactory->createInstanceWithArguments( sComponentName, aArgs ), uno::UNO_QUERY ); DBG_ASSERT( xDocHandler.is(), "can't get Calc importer" ); uno::Reference xImporter( xDocHandler, uno::UNO_QUERY ); uno::Reference xComponent( xModel, uno::UNO_QUERY ); if (xImporter.is()) xImporter->setTargetDocument( xComponent ); // connect parser and filter uno::Reference xParser( xXMLParser, uno::UNO_QUERY ); xParser->setDocumentHandler( xDocHandler ); // parse /* if( xSource.is() ) { uno::Reference xSourceControl( xSource, uno::UNO_QUERY ); if( xSourceControl.is() ) xSourceControl->start(); }*/ try { xParser->parseStream( aParserInput ); } catch( xml::sax::SAXParseException& r ) { if( bEncrypted ) nReturn = ERRCODE_SFX_WRONGPASSWORD; else { #ifdef DBG_UTIL ByteString aError( "SAX parse exception catched while importing:\n" ); aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); DBG_ERROR( aError.GetBuffer() ); #endif String sErr( String::CreateFromInt32( r.LineNumber )); sErr += ','; sErr += String::CreateFromInt32( r.ColumnNumber ); if( sDocName.getLength() ) { nReturn = *new TwoStringErrorInfo( (bMustBeSuccessfull ? SCERR_IMPORT_FILE_ROWCOL : SCWARN_IMPORT_FILE_ROWCOL), sDocName, sErr, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); } else { DBG_ASSERT( bMustBeSuccessfull, "Warnings are not supported" ); nReturn = *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL, sErr, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); } } } catch( xml::sax::SAXException& r ) { if( bEncrypted ) nReturn = ERRCODE_SFX_WRONGPASSWORD; else { #ifdef DBG_UTIL ByteString aError( "SAX exception catched while importing:\n" ); aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); DBG_ERROR( aError.GetBuffer() ); #endif (void)r; // avoid warning in product version nReturn = SCERR_IMPORT_FORMAT; } } catch( packages::zip::ZipIOException& r ) { #ifdef DBG_UTIL ByteString aError( "Zip exception catched while importing:\n" ); aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); DBG_ERROR( aError.GetBuffer() ); #endif (void)r; // avoid warning in product version nReturn = ERRCODE_IO_BROKENPACKAGE; } catch( io::IOException& r ) { #ifdef DBG_UTIL ByteString aError( "IO exception catched while importing:\n" ); aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); DBG_ERROR( aError.GetBuffer() ); #endif (void)r; // avoid warning in product version nReturn = SCERR_IMPORT_OPEN; } catch( uno::Exception& r ) { #ifdef DBG_UTIL ByteString aError( "uno exception catched while importing:\n" ); aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); DBG_ERROR( aError.GetBuffer() ); #endif (void)r; // avoid warning in product version nReturn = SCERR_IMPORT_UNKNOWN; } // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler, // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer. // So the overflow warning ErrorCode is now stored in the document. // Export works differently, there getImplementation still works. if (rDoc.HasRangeOverflow() && !nReturn) nReturn = rDoc.GetRangeOverflowType(); // free the component xParser->setDocumentHandler( NULL ); // success! return nReturn; } sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) { RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Import" ); uno::Reference xServiceFactory = comphelper::getProcessServiceFactory(); DBG_ASSERT( xServiceFactory.is(), "got no service manager" ); if( !xServiceFactory.is() ) return sal_False; xml::sax::InputSource aParserInput; if (pMedium) aParserInput.sSystemId = OUString(pMedium->GetName()); if ( !xStorage.is() && pMedium ) xStorage = pMedium->GetStorage(); // get parser uno::Reference xXMLParser( xServiceFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) )); DBG_ASSERT( xXMLParser.is(), "com.sun.star.xml.sax.Parser service missing" ); if( !xXMLParser.is() ) return sal_False; // get filter SfxObjectShell* pObjSh = rDoc.GetDocumentShell(); if ( pObjSh ) { rtl::OUString sEmpty; uno::Reference xModel(pObjSh->GetModel()); /** property map for export info set */ comphelper::PropertyMapEntry aImportInfoMap[] = { { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { NULL, 0, 0, NULL, 0, 0 } }; uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) ); // ---- get BuildId from parent container if available uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY ); if( xChild.is() ) { uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY ); if( xParentSet.is() ) { uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() ); OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) ); if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) ) { xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) ); } } } // ------------------------------------- uno::Reference xStatusIndicator(GetStatusIndicator()); if (xStatusIndicator.is()) { sal_Int32 nProgressRange(1000000); xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_LOAD_DOC)), nProgressRange); xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange)); } // Set base URI OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" ); ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : ::rtl::OUString(); rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") ); xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) ); // TODO/LATER: do not do it for embedded links if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() ) { OUString aName; if ( pMedium && pMedium->GetItemSet() ) { const SfxStringItem* pDocHierarchItem = static_cast( pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) ); if ( pDocHierarchItem ) aName = pDocHierarchItem->GetValue(); } else aName = ::rtl::OUString::createFromAscii( "dummyObjectName" ); if( aName.getLength() ) { sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")); xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) ); } } sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 ); sal_uInt32 nMetaRetval(0); if(!bStylesOnly) { uno::Sequence aMetaArgs(1); uno::Any* pMetaArgs = aMetaArgs.getArray(); pMetaArgs[0] <<= xInfoSet; RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import start" ); nMetaRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter")) : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs, sal_False); RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import end" ); } SvXMLGraphicHelper* pGraphicHelper = NULL; uno::Reference< document::XGraphicObjectResolver > xGrfContainer; uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver; SvXMLEmbeddedObjectHelper *pObjectHelper = NULL; if( xStorage.is() ) { pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ ); xGrfContainer = pGraphicHelper; if( pObjSh ) { pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_READ, sal_False ); xObjectResolver = pObjectHelper; } } uno::Sequence aStylesArgs(4); uno::Any* pStylesArgs = aStylesArgs.getArray(); pStylesArgs[0] <<= xInfoSet; pStylesArgs[1] <<= xGrfContainer; pStylesArgs[2] <<= xStatusIndicator; pStylesArgs[3] <<= xObjectResolver; sal_uInt32 nSettingsRetval(0); if (!bStylesOnly) { // Settings must be loaded first because of the printer setting, // which is needed in the page styles (paper tray). uno::Sequence aSettingsArgs(1); uno::Any* pSettingsArgs = aSettingsArgs.getArray(); pSettingsArgs[0] <<= xInfoSet; RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import start" ); nSettingsRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsImporter")) : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsImporter")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml")), sEmpty, aSettingsArgs, sal_False); RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import end" ); } sal_uInt32 nStylesRetval(0); { RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import start" ); nStylesRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesImporter")) : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesImporter")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("styles.xml")), sEmpty, aStylesArgs, sal_True); RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import end" ); } sal_uInt32 nDocRetval(0); if (!bStylesOnly) { uno::Sequence aDocArgs(4); uno::Any* pDocArgs = aDocArgs.getArray(); pDocArgs[0] <<= xInfoSet; pDocArgs[1] <<= xGrfContainer; pDocArgs[2] <<= xStatusIndicator; pDocArgs[3] <<= xObjectResolver; RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import start" ); nDocRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentImporter")) : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentImporter")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content.xml")), aDocArgs, sal_True); RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import end" ); } if( pGraphicHelper ) SvXMLGraphicHelper::Destroy( pGraphicHelper ); if( pObjectHelper ) SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper ); if (xStatusIndicator.is()) xStatusIndicator->end(); sal_Bool bRet(sal_False); if (bStylesOnly) { if (nStylesRetval) nError = nStylesRetval; else bRet = sal_True; } else { if (nDocRetval) { nError = nDocRetval; if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW || nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW || nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW || nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW) bRet = sal_True; } else if (nStylesRetval) nError = nStylesRetval; else if (nMetaRetval) nError = nMetaRetval; else if (nSettingsRetval) nError = nSettingsRetval; else bRet = sal_True; } // set BuildId on XModel for later OLE object loading if( xInfoSet.is() ) { uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY ); if( xModelSet.is() ) { uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() ); OUString sBuildPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) ); if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) ) { xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) ); } } } // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval; } return sal_False; } sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference& xServiceFactory, uno::Reference& xModel, uno::Reference& xWriter, uno::Sequence& aDescriptor, const rtl::OUString& sName, const rtl::OUString& sMediaType, const rtl::OUString& sComponentName, const sal_Bool bPlainText, uno::Sequence& aArgs, ScMySharedData*& pSharedData) { sal_Bool bRet(sal_False); uno::Reference xOut; uno::Reference xStream; if ( !xStorage.is() && pMedium ) xStorage = pMedium->GetOutputStorage(); if( xStorage.is() ) { // #96807#; trunc stream before use, because it could be an existing stream // and the new content could be shorter than the old content. In this case // would not all be over written by the new content and the xml file // would not be valid. xStream = xStorage->openStreamElement( sName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY ); if (xSet.is()) { xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType)); OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") ); if (bPlainText) xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), uno::makeAny(sal_False)); // even plain stream should be encrypted in encrypted documents xSet->setPropertyValue( aUseCommonPassPropName, uno::makeAny(sal_True) ); } xOut = xStream->getOutputStream(); } // #99667#; no longer necessary /* else if ( pMedium ) { xOut = pMedium->GetDataSink(); }*/ // set Base URL uno::Reference< beans::XPropertySet > xInfoSet; if( aArgs.getLength() > 0 ) aArgs.getConstArray()[0] >>= xInfoSet; DBG_ASSERT( xInfoSet.is(), "missing property set" ); if( xInfoSet.is() ) { rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") ); xInfoSet->setPropertyValue( sPropName, uno::makeAny( sName ) ); } uno::Reference xSrc( xWriter, uno::UNO_QUERY ); xSrc->setOutputStream( xOut ); uno::Reference xFilter( xServiceFactory->createInstanceWithArguments( sComponentName , aArgs ), uno::UNO_QUERY ); DBG_ASSERT( xFilter.is(), "can't get exporter" ); uno::Reference xExporter( xFilter, uno::UNO_QUERY ); uno::Reference xComponent( xModel, uno::UNO_QUERY ); if (xExporter.is()) xExporter->setSourceDocument( xComponent ); if ( xFilter.is() ) { ScXMLExport* pExport = static_cast(SvXMLExport::getImplementation(xFilter)); pExport->SetSharedData(pSharedData); bRet = xFilter->filter( aDescriptor ); pSharedData = pExport->GetSharedData(); //stream is closed by SAX parser //if (xOut.is()) // xOut->closeOutput(); } return bRet; } sal_Bool ScXMLImportWrapper::Export(sal_Bool bStylesOnly) { RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Export" ); uno::Reference xServiceFactory(comphelper::getProcessServiceFactory()); DBG_ASSERT( xServiceFactory.is(), "got no service manager" ); if( !xServiceFactory.is() ) return sal_False; uno::Reference xWriter(xServiceFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) )); DBG_ASSERT( xWriter.is(), "com.sun.star.xml.sax.Writer service missing" ); if(!xWriter.is()) return sal_False; if ( !xStorage.is() && pMedium ) xStorage = pMedium->GetOutputStorage(); uno::Reference xHandler( xWriter, uno::UNO_QUERY ); OUString sFileName; OUString sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml")); if (pMedium) sFileName = pMedium->GetName(); SfxObjectShell* pObjSh = rDoc.GetDocumentShell(); uno::Sequence aDescriptor(1); beans::PropertyValue* pProps = aDescriptor.getArray(); pProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) ); pProps[0].Value <<= sFileName; /** property map for export info set */ comphelper::PropertyMapEntry aExportInfoMap[] = { { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "WrittenNumberStyles" ), 0, &::getCppuType((uno::Sequence*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StyleNames" ), 0, &::getCppuType( (uno::Sequence*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StyleFamilies" ), 0, &::getCppuType( (uno::Sequence*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { NULL, 0, 0, NULL, 0, 0 } }; uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) ); if ( pObjSh && xStorage.is() ) { pObjSh->UpdateDocInfoForSave(); // update information uno::Reference xModel(pObjSh->GetModel()); uno::Reference xStatusIndicator(GetStatusIndicator()); sal_Int32 nProgressRange(1000000); if(xStatusIndicator.is()) xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_SAVE_DOC)), nProgressRange); xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange)); SvtSaveOptions aSaveOpt; sal_Bool bUsePrettyPrinting(aSaveOpt.IsPrettyPrinting()); xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(bUsePrettyPrinting)); const OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") ); xInfoSet->setPropertyValue( sTargetStorage, uno::Any( xStorage ) ); OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" ); ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL( true ) : ::rtl::OUString(); rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") ); xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) ); // TODO/LATER: do not do it for embedded links if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() ) { OUString aName = ::rtl::OUString::createFromAscii( "dummyObjectName" ); if ( pMedium && pMedium->GetItemSet() ) { const SfxStringItem* pDocHierarchItem = static_cast( pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) ); if ( pDocHierarchItem ) aName = pDocHierarchItem->GetValue(); } if( aName.getLength() ) { sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")); xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) ); } } sal_Bool bMetaRet(pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED); sal_Bool bStylesRet (sal_False); sal_Bool bDocRet(sal_False); sal_Bool bSettingsRet(sal_False); ScMySharedData* pSharedData = NULL; sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 ); // meta export if (!bStylesOnly && !bMetaRet) { uno::Sequence aMetaArgs(3); uno::Any* pMetaArgs = aMetaArgs.getArray(); pMetaArgs[0] <<= xInfoSet; pMetaArgs[1] <<= xHandler; pMetaArgs[2] <<= xStatusIndicator; RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export start" ); bMetaRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("meta.xml")), sTextMediaType, bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaExporter")) : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaExporter")), sal_True, aMetaArgs, pSharedData); RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export end" ); } uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver; SvXMLEmbeddedObjectHelper *pObjectHelper = 0; uno::Reference< document::XGraphicObjectResolver > xGrfContainer; SvXMLGraphicHelper* pGraphicHelper = 0; if( xStorage.is() ) { pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, FALSE ); xGrfContainer = pGraphicHelper; } if( pObjSh ) { pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, sal_False ); xObjectResolver = pObjectHelper; } // styles export { uno::Sequence aStylesArgs(5); uno::Any* pStylesArgs = aStylesArgs.getArray(); pStylesArgs[0] <<= xInfoSet; pStylesArgs[1] <<= xGrfContainer; pStylesArgs[2] <<= xStatusIndicator; pStylesArgs[3] <<= xHandler; pStylesArgs[4] <<= xObjectResolver; RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export start" ); bStylesRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("styles.xml")), sTextMediaType, bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesExporter")) : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesExporter")), sal_False, aStylesArgs, pSharedData); RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export end" ); } // content export if (!bStylesOnly) { uno::Sequence aDocArgs(5); uno::Any* pDocArgs = aDocArgs.getArray(); pDocArgs[0] <<= xInfoSet; pDocArgs[1] <<= xGrfContainer; pDocArgs[2] <<= xStatusIndicator; pDocArgs[3] <<= xHandler; pDocArgs[4] <<= xObjectResolver; RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export start" ); bDocRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("content.xml")), sTextMediaType, bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentExporter")) : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentExporter")), sal_False, aDocArgs, pSharedData); RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export end" ); } if( pGraphicHelper ) SvXMLGraphicHelper::Destroy( pGraphicHelper ); if( pObjectHelper ) SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper ); // settings export if (!bStylesOnly) { uno::Sequence aSettingsArgs(3); uno::Any* pSettingsArgs = aSettingsArgs.getArray(); pSettingsArgs[0] <<= xInfoSet; pSettingsArgs[1] <<= xHandler; pSettingsArgs[2] <<= xStatusIndicator; RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export start" ); bSettingsRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("settings.xml")), sTextMediaType, bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsExporter")) : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsExporter")), sal_False, aSettingsArgs, pSharedData); RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export end" ); } if (pSharedData) delete pSharedData; if (xStatusIndicator.is()) xStatusIndicator->end(); return bStylesRet && ((!bStylesOnly && bDocRet && bMetaRet && bSettingsRet) || bStylesOnly); } // later: give string descriptor as parameter for doc type return sal_False; }