|  | /************************************************************** | 
|  | * | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements.  See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership.  The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (the | 
|  | * "License"); you may not use this file except in compliance | 
|  | * with the License.  You may obtain a copy of the License at | 
|  | * | 
|  | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied.  See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | * | 
|  | *************************************************************/ | 
|  |  | 
|  |  | 
|  |  | 
|  | // MARKER(update_precomp.py): autogen include statement, do not remove | 
|  | #include "precompiled_svx.hxx" | 
|  | #include <com/sun/star/embed/XTransactedObject.hpp> | 
|  | #ifndef _COM_SUN_STAR_EMBED_ElementModes_HPP_ | 
|  | #include <com/sun/star/embed/ElementModes.hpp> | 
|  | #endif | 
|  | #include <com/sun/star/beans/XPropertySet.hpp> | 
|  | #include <com/sun/star/lang/XMultiServiceFactory.hpp> | 
|  | #include <com/sun/star/lang/XServiceInfo.hpp> | 
|  | #include <com/sun/star/lang/XInitialization.hpp> | 
|  | #include <cppuhelper/compbase4.hxx> | 
|  |  | 
|  | #include <unotools/ucbstreamhelper.hxx> | 
|  | #include <unotools/streamwrap.hxx> | 
|  | #include <unotools/tempfile.hxx> | 
|  | #include <tools/debug.hxx> | 
|  | #include <vcl/cvtgrf.hxx> | 
|  | #include <vcl/gfxlink.hxx> | 
|  | #include <vcl/metaact.hxx> | 
|  | #include <tools/zcodec.hxx> | 
|  |  | 
|  | #include "svtools/filter.hxx" | 
|  | #include "svx/xmlgrhlp.hxx" | 
|  |  | 
|  | #include <algorithm> | 
|  |  | 
|  | // ----------- | 
|  | // - Defines - | 
|  | // ----------- | 
|  |  | 
|  | using namespace com::sun::star; | 
|  | using namespace com::sun::star::uno; | 
|  | using namespace com::sun::star::io; | 
|  |  | 
|  | using ::com::sun::star::lang::XMultiServiceFactory; | 
|  |  | 
|  | #define XML_GRAPHICSTORAGE_NAME		"Pictures" | 
|  | #define XML_PACKAGE_URL_BASE		"vnd.sun.star.Package:" | 
|  | #define XML_GRAPHICOBJECT_URL_BASE	"vnd.sun.star.GraphicObject:" | 
|  |  | 
|  | // --------------------------- | 
|  | // - SvXMLGraphicInputStream - | 
|  | // --------------------------- | 
|  |  | 
|  | const MetaCommentAction* ImplCheckForEPS( GDIMetaFile& rMtf ) | 
|  | { | 
|  | static ByteString aComment( (const sal_Char*)"EPSReplacementGraphic" ); | 
|  | const MetaCommentAction* pComment = NULL; | 
|  |  | 
|  | if ( ( rMtf.GetActionCount() >= 2 ) | 
|  | && ( rMtf.FirstAction()->GetType() == META_EPS_ACTION ) | 
|  | && ( ((const MetaAction*)rMtf.GetAction( 1 ))->GetType() == META_COMMENT_ACTION ) | 
|  | && ( ((const MetaCommentAction*)rMtf.GetAction( 1 ))->GetComment() == aComment ) ) | 
|  | pComment = (const MetaCommentAction*)rMtf.GetAction( 1 ); | 
|  |  | 
|  | return pComment; | 
|  | } | 
|  |  | 
|  | class SvXMLGraphicInputStream : public::cppu::WeakImplHelper1< XInputStream > | 
|  | { | 
|  | private: | 
|  |  | 
|  | virtual sal_Int32	SAL_CALL	readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException); | 
|  | virtual sal_Int32	SAL_CALL	readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException); | 
|  | virtual void		SAL_CALL	skipBytes(sal_Int32 nBytesToSkip) throw(NotConnectedException, BufferSizeExceededException, RuntimeException); | 
|  | virtual sal_Int32	SAL_CALL	available() throw(NotConnectedException, RuntimeException); | 
|  | virtual void		SAL_CALL	closeInput() throw(NotConnectedException, RuntimeException); | 
|  |  | 
|  | private: | 
|  |  | 
|  | ::utl::TempFile                 maTmp; | 
|  | Reference< XInputStream >       mxStmWrapper; | 
|  |  | 
|  | // not available | 
|  | SvXMLGraphicInputStream(); | 
|  | SvXMLGraphicInputStream( const SvXMLGraphicInputStream& ); | 
|  | SvXMLGraphicInputStream&        operator==( SvXMLGraphicInputStream& ); | 
|  |  | 
|  | public: | 
|  |  | 
|  | SvXMLGraphicInputStream( const ::rtl::OUString& rGraphicId ); | 
|  | virtual                         ~SvXMLGraphicInputStream(); | 
|  |  | 
|  | sal_Bool                        Exists() const { return mxStmWrapper.is(); } | 
|  | }; | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicInputStream::SvXMLGraphicInputStream( const ::rtl::OUString& rGraphicId ) | 
|  | { | 
|  | String			aGraphicId( rGraphicId ); | 
|  | GraphicObject	aGrfObject( ByteString( aGraphicId, RTL_TEXTENCODING_ASCII_US ) ); | 
|  |  | 
|  | maTmp.EnableKillingFile(); | 
|  |  | 
|  | if( aGrfObject.GetType() != GRAPHIC_NONE ) | 
|  | { | 
|  | SvStream* pStm = ::utl::UcbStreamHelper::CreateStream( maTmp.GetURL(), STREAM_WRITE | STREAM_TRUNC ); | 
|  |  | 
|  | if( pStm ) | 
|  | { | 
|  | Graphic			aGraphic( (Graphic&) aGrfObject.GetGraphic() ); | 
|  | const GfxLink	aGfxLink( aGraphic.GetLink() ); | 
|  | sal_Bool        bRet = sal_False; | 
|  |  | 
|  | if( aGfxLink.GetDataSize() && aGfxLink.GetData() ) | 
|  | { | 
|  | pStm->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() ); | 
|  | bRet = ( pStm->GetError() == 0 ); | 
|  | } | 
|  | else | 
|  | { | 
|  | if( aGraphic.GetType() == GRAPHIC_BITMAP ) | 
|  | { | 
|  | GraphicFilter*  pFilter = GraphicFilter::GetGraphicFilter(); | 
|  | String          aFormat; | 
|  |  | 
|  | if( aGraphic.IsAnimated() ) | 
|  | aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "gif" ) ); | 
|  | else | 
|  | aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "png" ) ); | 
|  |  | 
|  | bRet = ( pFilter->ExportGraphic( aGraphic, String(), *pStm, pFilter->GetExportFormatNumberForShortName( aFormat ) ) == 0 ); | 
|  | } | 
|  | else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE ) | 
|  | { | 
|  | pStm->SetVersion( SOFFICE_FILEFORMAT_8 ); | 
|  | pStm->SetCompressMode( COMPRESSMODE_ZBITMAP ); | 
|  | ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( *pStm ); | 
|  | bRet = ( pStm->GetError() == 0 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | if( bRet ) | 
|  | { | 
|  | pStm->Seek( 0 ); | 
|  | mxStmWrapper = new ::utl::OInputStreamWrapper( pStm, sal_True ); | 
|  | } | 
|  | else | 
|  | delete pStm; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicInputStream::~SvXMLGraphicInputStream() | 
|  | { | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | sal_Int32 SAL_CALL SvXMLGraphicInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) | 
|  | throw( NotConnectedException, BufferSizeExceededException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException(); | 
|  |  | 
|  | return mxStmWrapper->readBytes( rData, nBytesToRead ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | sal_Int32 SAL_CALL SvXMLGraphicInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) | 
|  | throw( NotConnectedException, BufferSizeExceededException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | return mxStmWrapper->readSomeBytes( rData, nMaxBytesToRead ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicInputStream::skipBytes( sal_Int32 nBytesToSkip ) | 
|  | throw( NotConnectedException, BufferSizeExceededException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | mxStmWrapper->skipBytes( nBytesToSkip ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | sal_Int32 SAL_CALL SvXMLGraphicInputStream::available() throw( NotConnectedException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | return mxStmWrapper->available(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicInputStream::closeInput() throw( NotConnectedException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | mxStmWrapper->closeInput(); | 
|  | } | 
|  |  | 
|  | // ---------------------------- | 
|  | // - SvXMLGraphicOutputStream - | 
|  | // ---------------------------- | 
|  |  | 
|  | class SvXMLGraphicOutputStream : public::cppu::WeakImplHelper1< XOutputStream > | 
|  | { | 
|  | private: | 
|  |  | 
|  | // XOutputStream | 
|  | virtual void SAL_CALL           writeBytes( const Sequence< sal_Int8 >& rData ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ); | 
|  | virtual void SAL_CALL           flush() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ); | 
|  | virtual void SAL_CALL           closeOutput() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ); | 
|  |  | 
|  | private: | 
|  |  | 
|  | ::utl::TempFile*                mpTmp; | 
|  | SvStream*                       mpOStm; | 
|  | Reference< XOutputStream >      mxStmWrapper; | 
|  | GraphicObject                   maGrfObj; | 
|  | sal_Bool                        mbClosed; | 
|  |  | 
|  | // not available | 
|  | SvXMLGraphicOutputStream( const SvXMLGraphicOutputStream& ); | 
|  | SvXMLGraphicOutputStream&       operator==( SvXMLGraphicOutputStream& ); | 
|  |  | 
|  | public: | 
|  |  | 
|  | SvXMLGraphicOutputStream(); | 
|  | virtual                         ~SvXMLGraphicOutputStream(); | 
|  |  | 
|  | sal_Bool                        Exists() const { return mxStmWrapper.is(); } | 
|  | const GraphicObject&            GetGraphicObject(); | 
|  | }; | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicOutputStream::SvXMLGraphicOutputStream() : | 
|  | mpTmp( new ::utl::TempFile ), | 
|  | mbClosed( sal_False ) | 
|  | { | 
|  | mpTmp->EnableKillingFile(); | 
|  |  | 
|  | mpOStm = ::utl::UcbStreamHelper::CreateStream( mpTmp->GetURL(), STREAM_WRITE | STREAM_TRUNC ); | 
|  |  | 
|  | if( mpOStm ) | 
|  | mxStmWrapper = new ::utl::OOutputStreamWrapper( *mpOStm ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicOutputStream::~SvXMLGraphicOutputStream() | 
|  | { | 
|  | delete mpTmp; | 
|  | delete mpOStm; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicOutputStream::writeBytes( const Sequence< sal_Int8 >& rData ) | 
|  | throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | mxStmWrapper->writeBytes( rData ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicOutputStream::flush() | 
|  | throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | mxStmWrapper->flush(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicOutputStream::closeOutput() | 
|  | throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) | 
|  | { | 
|  | if( !mxStmWrapper.is() ) | 
|  | throw NotConnectedException() ; | 
|  |  | 
|  | mxStmWrapper->closeOutput(); | 
|  | mxStmWrapper = Reference< XOutputStream >(); | 
|  |  | 
|  | mbClosed = sal_True; | 
|  | } | 
|  |  | 
|  | // ------------------------------------------------------------------------------ | 
|  |  | 
|  | const GraphicObject& SvXMLGraphicOutputStream::GetGraphicObject() | 
|  | { | 
|  | if( mbClosed && ( maGrfObj.GetType() == GRAPHIC_NONE ) && mpOStm ) | 
|  | { | 
|  | Graphic aGraphic; | 
|  |  | 
|  | mpOStm->Seek( 0 ); | 
|  | sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW; | 
|  | sal_uInt16 pDeterminedFormat = GRFILTER_FORMAT_DONTKNOW; | 
|  | GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *mpOStm ,nFormat,&pDeterminedFormat ); | 
|  |  | 
|  | if (pDeterminedFormat == GRFILTER_FORMAT_DONTKNOW) | 
|  | { | 
|  | //Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format | 
|  | //unzip them and try again | 
|  |  | 
|  | sal_uInt8    sFirstBytes[ 2 ]; | 
|  |  | 
|  | mpOStm->Seek( STREAM_SEEK_TO_END ); | 
|  | sal_uIntPtr nStreamLen = mpOStm->Tell(); | 
|  | mpOStm->Seek( 0 ); | 
|  |  | 
|  | if ( !nStreamLen ) | 
|  | { | 
|  | SvLockBytes* pLockBytes = mpOStm->GetLockBytes(); | 
|  | if ( pLockBytes  ) | 
|  | pLockBytes->SetSynchronMode( sal_True ); | 
|  |  | 
|  | mpOStm->Seek( STREAM_SEEK_TO_END ); | 
|  | nStreamLen = mpOStm->Tell(); | 
|  | mpOStm->Seek( 0 ); | 
|  | } | 
|  | if( nStreamLen >= 2 ) | 
|  | { | 
|  | //read two byte | 
|  | mpOStm->Read( sFirstBytes, 2 ); | 
|  |  | 
|  | if( sFirstBytes[0] == 0x1f && sFirstBytes[1] == 0x8b ) | 
|  | { | 
|  | SvMemoryStream* pDest = new SvMemoryStream; | 
|  | ZCodec aZCodec( 0x8000, 0x8000 ); | 
|  | aZCodec.BeginCompression(ZCODEC_GZ_LIB); | 
|  | mpOStm->Seek( 0 ); | 
|  | aZCodec.Decompress( *mpOStm, *pDest ); | 
|  |  | 
|  | if (aZCodec.EndCompression() && pDest ) | 
|  | { | 
|  | pDest->Seek( STREAM_SEEK_TO_END ); | 
|  | sal_uIntPtr nStreamLen_ = pDest->Tell(); | 
|  | if (nStreamLen_) | 
|  | { | 
|  | pDest->Seek(0L); | 
|  | GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pDest ,nFormat,&pDeterminedFormat ); | 
|  | } | 
|  | } | 
|  | delete pDest; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | maGrfObj = aGraphic; | 
|  | if( maGrfObj.GetType() != GRAPHIC_NONE ) | 
|  | { | 
|  | delete mpOStm, mpOStm = NULL; | 
|  | delete mpTmp, mpTmp = NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | return maGrfObj; | 
|  | } | 
|  |  | 
|  | // ---------------------- | 
|  | // - SvXMLGraphicHelper - | 
|  | // ---------------------- | 
|  |  | 
|  | SvXMLGraphicHelper::SvXMLGraphicHelper( SvXMLGraphicHelperMode eCreateMode ) : | 
|  | ::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver, | 
|  | ::com::sun::star::document::XBinaryStreamResolver >( maMutex ) | 
|  | { | 
|  | Init( NULL, eCreateMode, sal_False ); | 
|  | } | 
|  |  | 
|  | SvXMLGraphicHelper::SvXMLGraphicHelper() : | 
|  | ::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver, | 
|  | ::com::sun::star::document::XBinaryStreamResolver >( maMutex ) | 
|  | { | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicHelper::~SvXMLGraphicHelper() | 
|  | { | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicHelper::disposing() | 
|  | { | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool SvXMLGraphicHelper::ImplGetStreamNames( const ::rtl::OUString& rURLStr, | 
|  | ::rtl::OUString& rPictureStorageName, | 
|  | ::rtl::OUString& rPictureStreamName ) | 
|  | { | 
|  | String		aURLStr( rURLStr ); | 
|  | sal_Bool	bRet = sal_False; | 
|  |  | 
|  | if( aURLStr.Len() ) | 
|  | { | 
|  | aURLStr = aURLStr.GetToken( aURLStr.GetTokenCount( ':' ) - 1, ':' ); | 
|  | const sal_uInt32 nTokenCount = aURLStr.GetTokenCount( '/' ); | 
|  |  | 
|  | if( 1 == nTokenCount ) | 
|  | { | 
|  | rPictureStorageName = String( RTL_CONSTASCII_USTRINGPARAM( XML_GRAPHICSTORAGE_NAME ) ); | 
|  | rPictureStreamName = aURLStr; | 
|  | bRet = sal_True; | 
|  | } | 
|  | else if( 2 == nTokenCount ) | 
|  | { | 
|  | rPictureStorageName = aURLStr.GetToken( 0, '/' ); | 
|  |  | 
|  | DBG_ASSERT( rPictureStorageName.getLength() && | 
|  | rPictureStorageName.getStr()[ 0 ] != '#', | 
|  | "invalid relative URL" ); | 
|  |  | 
|  | rPictureStreamName = aURLStr.GetToken( 1, '/' ); | 
|  | bRet = sal_True; | 
|  | } | 
|  | else | 
|  | { | 
|  | DBG_ERROR( "SvXMLGraphicHelper::ImplInsertGraphicURL: invalid scheme" ); | 
|  | } | 
|  | } | 
|  |  | 
|  | return bRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | uno::Reference < embed::XStorage > SvXMLGraphicHelper::ImplGetGraphicStorage( const ::rtl::OUString& rStorageName ) | 
|  | { | 
|  | uno::Reference < embed::XStorage > xRetStorage; | 
|  | if( mxRootStorage.is() ) | 
|  | { | 
|  | try | 
|  | { | 
|  | xRetStorage = mxRootStorage->openStorageElement( | 
|  | maCurStorageName = rStorageName, | 
|  | ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) | 
|  | ? embed::ElementModes::READWRITE | 
|  | : embed::ElementModes::READ ); | 
|  | } | 
|  | catch ( uno::Exception& ) | 
|  | { | 
|  | } | 
|  | //#i43196# try again to open the storage element - this time readonly | 
|  | if(!xRetStorage.is()) | 
|  | { | 
|  | try | 
|  | { | 
|  | xRetStorage = mxRootStorage->openStorageElement( maCurStorageName = rStorageName, embed::ElementModes::READ ); | 
|  | } | 
|  | catch ( uno::Exception& ) | 
|  | { | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return xRetStorage; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvxGraphicHelperStream_Impl SvXMLGraphicHelper::ImplGetGraphicStream( const ::rtl::OUString& rPictureStorageName, | 
|  | const ::rtl::OUString& rPictureStreamName, | 
|  | sal_Bool bTruncate ) | 
|  | { | 
|  | SvxGraphicHelperStream_Impl aRet; | 
|  | aRet.xStorage = ImplGetGraphicStorage( rPictureStorageName ); | 
|  |  | 
|  | if( aRet.xStorage.is() ) | 
|  | { | 
|  | sal_Int32 nMode = embed::ElementModes::READ; | 
|  | if ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) | 
|  | { | 
|  | nMode = embed::ElementModes::READWRITE; | 
|  | if ( bTruncate ) | 
|  | nMode |= embed::ElementModes::TRUNCATE; | 
|  | } | 
|  |  | 
|  | aRet.xStream = aRet.xStorage->openStreamElement( rPictureStreamName, nMode ); | 
|  | if( aRet.xStream.is() && ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) ) | 
|  | { | 
|  | //REMOVE				::rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ); | 
|  | ::rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") ); | 
|  | uno::Reference < beans::XPropertySet > xProps( aRet.xStream, uno::UNO_QUERY ); | 
|  | xProps->setPropertyValue( aPropName, uno::makeAny( sal_True) ); | 
|  | } | 
|  | } | 
|  |  | 
|  | return aRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | String SvXMLGraphicHelper::ImplGetGraphicMimeType( const String& rFileName ) const | 
|  | { | 
|  | struct XMLGraphicMimeTypeMapper | 
|  | { | 
|  | const char*	pExt; | 
|  | const char*	pMimeType; | 
|  | }; | 
|  |  | 
|  | static XMLGraphicMimeTypeMapper aMapper[] = | 
|  | { | 
|  | { "gif", "image/gif" }, | 
|  | { "png", "image/png" }, | 
|  | { "jpg", "image/jpeg" }, | 
|  | { "tif", "image/tiff" }, | 
|  | { "svg", "image/svg+xml" } | 
|  | }; | 
|  |  | 
|  | String aMimeType; | 
|  |  | 
|  | if( ( rFileName.Len() >= 4 ) && ( rFileName.GetChar( rFileName.Len() - 4 ) == '.' ) ) | 
|  | { | 
|  | const ByteString aExt( rFileName.Copy( rFileName.Len() - 3 ), RTL_TEXTENCODING_ASCII_US ); | 
|  |  | 
|  | for( long i = 0, nCount = sizeof( aMapper ) / sizeof( aMapper[ 0 ] ); ( i < nCount ) && !aMimeType.Len(); i++ ) | 
|  | if( aExt == aMapper[ i ].pExt ) | 
|  | aMimeType = String( aMapper[ i ].pMimeType, RTL_TEXTENCODING_ASCII_US ); | 
|  | } | 
|  |  | 
|  | return aMimeType; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | Graphic SvXMLGraphicHelper::ImplReadGraphic( const ::rtl::OUString& rPictureStorageName, | 
|  | const ::rtl::OUString& rPictureStreamName ) | 
|  | { | 
|  | Graphic				aGraphic; | 
|  | SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, sal_False ) ); | 
|  | if( aStream.xStream.is() ) | 
|  | { | 
|  | SvStream* pStream = utl::UcbStreamHelper::CreateStream( aStream.xStream ); | 
|  | GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pStream ); | 
|  | delete pStream; | 
|  | } | 
|  |  | 
|  | return aGraphic; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool SvXMLGraphicHelper::ImplWriteGraphic( const ::rtl::OUString& rPictureStorageName, | 
|  | const ::rtl::OUString& rPictureStreamName, | 
|  | const ::rtl::OUString& rGraphicId ) | 
|  | { | 
|  | String			aGraphicId( rGraphicId ); | 
|  | GraphicObject	aGrfObject( ByteString( aGraphicId, RTL_TEXTENCODING_ASCII_US ) ); | 
|  | sal_Bool		bRet = sal_False; | 
|  |  | 
|  | if( aGrfObject.GetType() != GRAPHIC_NONE ) | 
|  | { | 
|  | SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, sal_False ) ); | 
|  | if( aStream.xStream.is() ) | 
|  | { | 
|  | Graphic			aGraphic( (Graphic&) aGrfObject.GetGraphic() ); | 
|  | const GfxLink	aGfxLink( aGraphic.GetLink() ); | 
|  | const ::rtl::OUString  aMimeType( ImplGetGraphicMimeType( rPictureStreamName ) ); | 
|  | uno::Any        aAny; | 
|  | uno::Reference < beans::XPropertySet > xProps( aStream.xStream, uno::UNO_QUERY ); | 
|  |  | 
|  | // set stream properties (MediaType/Compression) | 
|  | if( aMimeType.getLength() ) | 
|  | { | 
|  | aAny <<= aMimeType; | 
|  | xProps->setPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), aAny ); | 
|  | } | 
|  |  | 
|  | const sal_Bool bCompressed = ( ( 0 == aMimeType.getLength() ) || ( aMimeType == ::rtl::OUString::createFromAscii( "image/tiff" ) ) ); | 
|  | aAny <<= bCompressed; | 
|  | xProps->setPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), aAny ); | 
|  |  | 
|  | SvStream* pStream = utl::UcbStreamHelper::CreateStream( aStream.xStream ); | 
|  | if( aGfxLink.GetDataSize() && aGfxLink.GetData() ) | 
|  | pStream->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() ); | 
|  | else | 
|  | { | 
|  | if( aGraphic.GetType() == GRAPHIC_BITMAP ) | 
|  | { | 
|  | GraphicFilter*  pFilter = GraphicFilter::GetGraphicFilter(); | 
|  | String          aFormat; | 
|  |  | 
|  | if( aGraphic.IsAnimated() ) | 
|  | aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "gif" ) ); | 
|  | else | 
|  | aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "png" ) ); | 
|  |  | 
|  | bRet = ( pFilter->ExportGraphic( aGraphic, String(), *pStream, | 
|  | pFilter->GetExportFormatNumberForShortName( aFormat ) ) == 0 ); | 
|  | } | 
|  | else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE ) | 
|  | { | 
|  | pStream->SetVersion( SOFFICE_FILEFORMAT_8 ); | 
|  | pStream->SetCompressMode( COMPRESSMODE_ZBITMAP ); | 
|  |  | 
|  | // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm | 
|  | GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() ); | 
|  | const MetaCommentAction* pComment = ImplCheckForEPS( rMtf ); | 
|  | if ( pComment ) | 
|  | { | 
|  | sal_uInt32	nSize = pComment->GetDataSize(); | 
|  | const sal_uInt8* pData = pComment->GetData(); | 
|  | if ( nSize && pData ) | 
|  | pStream->Write( pData, nSize ); | 
|  |  | 
|  | const MetaEPSAction* pAct = ( (const MetaEPSAction*)rMtf.FirstAction() ); | 
|  | const GfxLink&		 rLink = pAct->GetLink(); | 
|  |  | 
|  | pStream->Write( rLink.GetData(), rLink.GetDataSize() ); | 
|  | } | 
|  | else | 
|  | rMtf.Write( *pStream ); | 
|  |  | 
|  | bRet = ( pStream->GetError() == 0 ); | 
|  | } | 
|  | } | 
|  | uno::Reference < embed::XTransactedObject > xStorage( | 
|  | aStream.xStorage, uno::UNO_QUERY); | 
|  | delete pStream; | 
|  | aStream.xStream->getOutputStream()->closeOutput(); | 
|  | if( xStorage.is() ) | 
|  | xStorage->commit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | return bRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SvXMLGraphicHelper::ImplInsertGraphicURL( const ::rtl::OUString& rURLStr, sal_uInt32 nInsertPos, rtl::OUString& rRequestedFileName ) | 
|  | { | 
|  | rtl::OUString aURLString( rURLStr ); | 
|  | ::rtl::OUString	aPictureStorageName, aPictureStreamName; | 
|  | if( ( maURLSet.find( aURLString ) != maURLSet.end() ) ) | 
|  | { | 
|  | URLPairVector::iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() ); | 
|  | while( aIter != aEnd ) | 
|  | { | 
|  | if( aURLString == (*aIter).first ) | 
|  | { | 
|  | maGrfURLs[ nInsertPos ].second = (*aIter).second; | 
|  | aIter = aEnd; | 
|  | } | 
|  | else | 
|  | aIter++; | 
|  | } | 
|  | } | 
|  | else if( ImplGetStreamNames( aURLString, aPictureStorageName, aPictureStreamName ) ) | 
|  | { | 
|  | URLPair& rURLPair = maGrfURLs[ nInsertPos ]; | 
|  |  | 
|  | if( GRAPHICHELPER_MODE_READ == meCreateMode ) | 
|  | { | 
|  | const GraphicObject aObj( ImplReadGraphic( aPictureStorageName, aPictureStreamName ) ); | 
|  |  | 
|  | if( aObj.GetType() != GRAPHIC_NONE ) | 
|  | { | 
|  | const static ::rtl::OUString aBaseURL( RTL_CONSTASCII_USTRINGPARAM( XML_GRAPHICOBJECT_URL_BASE ) ); | 
|  |  | 
|  | maGrfObjs.push_back( aObj ); | 
|  | rURLPair.second = aBaseURL; | 
|  | rURLPair.second += String( aObj.GetUniqueID().GetBuffer(), RTL_TEXTENCODING_ASCII_US ); | 
|  | } | 
|  | else | 
|  | rURLPair.second = String(); | 
|  | } | 
|  | else | 
|  | { | 
|  | const String		aGraphicObjectId( aPictureStreamName ); | 
|  | const ByteString    aAsciiObjectID( aGraphicObjectId, RTL_TEXTENCODING_ASCII_US ); | 
|  | const GraphicObject	aGrfObject( aAsciiObjectID ); | 
|  | if( aGrfObject.GetType() != GRAPHIC_NONE ) | 
|  | { | 
|  | String			aStreamName( aGraphicObjectId ); | 
|  | Graphic			aGraphic( (Graphic&) aGrfObject.GetGraphic() ); | 
|  | const GfxLink	aGfxLink( aGraphic.GetLink() ); | 
|  | String			aExtension; | 
|  |  | 
|  | if( aGfxLink.GetDataSize() ) | 
|  | { | 
|  | switch( aGfxLink.GetType() ) | 
|  | { | 
|  | case( GFX_LINK_TYPE_EPS_BUFFER ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_GIF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) ); break; | 
|  |  | 
|  | // #15508# added BMP type for better exports (checked, works) | 
|  | case( GFX_LINK_TYPE_NATIVE_BMP ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".bmp" ) ); break; | 
|  |  | 
|  | case( GFX_LINK_TYPE_NATIVE_JPG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".jpg" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_PNG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_TIF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".tif" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_WMF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".wmf" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_MET ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".met" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_PCT ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".pct" ) ); break; | 
|  | case( GFX_LINK_TYPE_NATIVE_SVG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".svg" ) ); break; | 
|  |  | 
|  | default: | 
|  | aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".grf" ) ); | 
|  | break; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if( aGrfObject.GetType() == GRAPHIC_BITMAP ) | 
|  | { | 
|  | if( aGrfObject.IsAnimated() ) | 
|  | aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) ); | 
|  | else | 
|  | aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ); | 
|  | } | 
|  | else if( aGrfObject.GetType() == GRAPHIC_GDIMETAFILE ) | 
|  | { | 
|  | // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm | 
|  | GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() ); | 
|  | if ( ImplCheckForEPS( rMtf ) ) | 
|  | aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) ); | 
|  | else | 
|  | aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".svm" ) ); | 
|  | } | 
|  | } | 
|  |  | 
|  | rtl::OUString aURLEntry; | 
|  | const String sPictures( RTL_CONSTASCII_USTRINGPARAM( "Pictures/" ) ); | 
|  |  | 
|  | if ( rRequestedFileName.getLength() ) | 
|  | { | 
|  | aURLEntry = sPictures; | 
|  | aURLEntry += rRequestedFileName; | 
|  | aURLEntry += aExtension; | 
|  |  | 
|  | URLPairVector::iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() ); | 
|  | while( aIter != aEnd ) | 
|  | { | 
|  | if( aURLEntry == (*aIter).second ) | 
|  | break; | 
|  | aIter++; | 
|  | } | 
|  | if ( aIter == aEnd ) | 
|  | aStreamName = rRequestedFileName; | 
|  | } | 
|  |  | 
|  | aStreamName += aExtension; | 
|  |  | 
|  | if( mbDirect && aStreamName.Len() ) | 
|  | ImplWriteGraphic( aPictureStorageName, aStreamName, aGraphicObjectId ); | 
|  |  | 
|  | rURLPair.second = sPictures; | 
|  | rURLPair.second += aStreamName; | 
|  | } | 
|  | #if OSL_DEBUG_LEVEL > 0 | 
|  | else | 
|  | { | 
|  | ByteString sMessage = "graphic object with ID '"; | 
|  | sMessage += aAsciiObjectID; | 
|  | sMessage += "' has an unknown type"; | 
|  | OSL_ENSURE( false, sMessage.GetBuffer() ); | 
|  | } | 
|  | #endif | 
|  | } | 
|  |  | 
|  | maURLSet.insert( aURLString ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage, | 
|  | SvXMLGraphicHelperMode eCreateMode, | 
|  | sal_Bool bDirect ) | 
|  | { | 
|  | mxRootStorage = rXMLStorage; | 
|  | meCreateMode = eCreateMode; | 
|  | mbDirect = ( ( GRAPHICHELPER_MODE_READ == meCreateMode ) ? bDirect : sal_True ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicHelper* SvXMLGraphicHelper::Create( const uno::Reference < embed::XStorage >& rXMLStorage, | 
|  | SvXMLGraphicHelperMode eCreateMode, | 
|  | sal_Bool bDirect ) | 
|  | { | 
|  | SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper; | 
|  |  | 
|  | pThis->acquire(); | 
|  | pThis->Init( rXMLStorage, eCreateMode, bDirect ); | 
|  |  | 
|  | return pThis; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | SvXMLGraphicHelper*	SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode eCreateMode ) | 
|  | { | 
|  | SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper; | 
|  |  | 
|  | pThis->acquire(); | 
|  | pThis->Init( NULL, eCreateMode, sal_False ); | 
|  |  | 
|  | return pThis; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void SvXMLGraphicHelper::Destroy( SvXMLGraphicHelper* pSvXMLGraphicHelper ) | 
|  | { | 
|  | if( pSvXMLGraphicHelper ) | 
|  | { | 
|  | pSvXMLGraphicHelper->dispose(); | 
|  | pSvXMLGraphicHelper->release(); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | // XGraphicObjectResolver | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicHelper::resolveGraphicObjectURL( const ::rtl::OUString& rURL ) | 
|  | throw(uno::RuntimeException) | 
|  | { | 
|  | ::osl::MutexGuard   aGuard( maMutex ); | 
|  | const sal_Int32     nIndex = maGrfURLs.size(); | 
|  |  | 
|  | rtl::OUString aURL( rURL ); | 
|  | rtl::OUString aUserData; | 
|  | rtl::OUString aRequestedFileName; | 
|  |  | 
|  | sal_Int32 nUser = rURL.indexOf( '?', 0 ); | 
|  | if ( nUser >= 0 ) | 
|  | { | 
|  | aURL = rtl::OUString( rURL.copy( 0, nUser ) ); | 
|  | nUser++; | 
|  | aUserData = rURL.copy( nUser, rURL.getLength() - nUser ); | 
|  | } | 
|  | if ( aUserData.getLength() ) | 
|  | { | 
|  | sal_Int32 nIndex2 = 0; | 
|  | do | 
|  | { | 
|  | rtl::OUString aToken = aUserData.getToken( 0, ';', nIndex2 ); | 
|  | sal_Int32 n = aToken.indexOf( '=' ); | 
|  | if ( ( n > 0 ) && ( ( n + 1 ) < aToken.getLength() ) ) | 
|  | { | 
|  | rtl::OUString aParam( aToken.copy( 0, n ) ); | 
|  | rtl::OUString aValue( aToken.copy( n + 1, aToken.getLength() - ( n + 1 ) ) ); | 
|  |  | 
|  | const rtl::OUString sRequestedName( RTL_CONSTASCII_USTRINGPARAM("requestedName") ); | 
|  | if ( aParam.match( sRequestedName ) ) | 
|  | aRequestedFileName = aValue; | 
|  | } | 
|  | } | 
|  | while ( nIndex2 >= 0 ); | 
|  | } | 
|  |  | 
|  | maGrfURLs.push_back( ::std::make_pair( aURL, ::rtl::OUString() ) ); | 
|  | ImplInsertGraphicURL( aURL, nIndex, aRequestedFileName ); | 
|  |  | 
|  | return maGrfURLs[ nIndex ].second; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | // XBinaryStreamResolver | 
|  | Reference< XInputStream > SAL_CALL SvXMLGraphicHelper::getInputStream( const ::rtl::OUString& rURL ) | 
|  | throw( RuntimeException ) | 
|  | { | 
|  | Reference< XInputStream >   xRet; | 
|  | ::rtl::OUString                    aPictureStorageName, aGraphicId; | 
|  |  | 
|  |  | 
|  | if( ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) && | 
|  | ImplGetStreamNames( rURL, aPictureStorageName, aGraphicId ) ) | 
|  | { | 
|  | SvXMLGraphicInputStream* pInputStream = new SvXMLGraphicInputStream( aGraphicId ); | 
|  |  | 
|  | if( pInputStream->Exists() ) | 
|  | xRet = pInputStream; | 
|  | else | 
|  | delete pInputStream; | 
|  | } | 
|  |  | 
|  | return xRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | Reference< XOutputStream > SAL_CALL SvXMLGraphicHelper::createOutputStream() | 
|  | throw( RuntimeException ) | 
|  | { | 
|  | Reference< XOutputStream > xRet; | 
|  |  | 
|  | if( GRAPHICHELPER_MODE_READ == meCreateMode ) | 
|  | { | 
|  | SvXMLGraphicOutputStream* pOutputStream = new SvXMLGraphicOutputStream; | 
|  |  | 
|  | if( pOutputStream->Exists() ) | 
|  | maGrfStms.push_back( xRet = pOutputStream ); | 
|  | else | 
|  | delete pOutputStream; | 
|  | } | 
|  |  | 
|  | return xRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicHelper::resolveOutputStream( const Reference< XOutputStream >& rxBinaryStream ) | 
|  | throw( RuntimeException ) | 
|  | { | 
|  | ::rtl::OUString aRet; | 
|  |  | 
|  | if( ( GRAPHICHELPER_MODE_READ == meCreateMode ) && rxBinaryStream.is() ) | 
|  | { | 
|  | if( ::std::find( maGrfStms.begin(), maGrfStms.end(), rxBinaryStream ) != maGrfStms.end() ) | 
|  | { | 
|  | SvXMLGraphicOutputStream* pOStm = static_cast< SvXMLGraphicOutputStream* >( rxBinaryStream.get() ); | 
|  |  | 
|  | if( pOStm ) | 
|  | { | 
|  | const GraphicObject&    rGrfObj = pOStm->GetGraphicObject(); | 
|  | const ::rtl::OUString          aId( ::rtl::OUString::createFromAscii( rGrfObj.GetUniqueID().GetBuffer() ) ); | 
|  |  | 
|  | if( aId.getLength() ) | 
|  | { | 
|  | aRet = ::rtl::OUString::createFromAscii( XML_GRAPHICOBJECT_URL_BASE ); | 
|  | aRet += aId; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return aRet; | 
|  | } | 
|  |  | 
|  |  | 
|  | // -------------------------------------------------------------------------------- | 
|  |  | 
|  | // for instantiation via service manager | 
|  | namespace svx | 
|  | { | 
|  |  | 
|  | namespace impl | 
|  | { | 
|  | typedef ::cppu::WeakComponentImplHelper4< | 
|  | lang::XInitialization, | 
|  | document::XGraphicObjectResolver, | 
|  | document::XBinaryStreamResolver, | 
|  | lang::XServiceInfo > | 
|  | SvXMLGraphicImportExportHelper_Base; | 
|  | class MutexContainer | 
|  | { | 
|  | public: | 
|  | virtual ~MutexContainer(); | 
|  |  | 
|  | protected: | 
|  | mutable ::osl::Mutex m_aMutex; | 
|  | }; | 
|  | MutexContainer::~MutexContainer() | 
|  | {} | 
|  | } // namespace impl | 
|  |  | 
|  | class SvXMLGraphicImportExportHelper : | 
|  | public impl::MutexContainer, | 
|  | public impl::SvXMLGraphicImportExportHelper_Base | 
|  | { | 
|  | public: | 
|  | SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ); | 
|  |  | 
|  | protected: | 
|  | // is called from WeakComponentImplHelper when XComponent::dispose() was | 
|  | // called from outside | 
|  | virtual void SAL_CALL disposing(); | 
|  |  | 
|  | // ____ XInitialization ____ | 
|  | // one argument is allowed, which is the XStorage | 
|  | virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) | 
|  | throw (Exception, | 
|  | RuntimeException); | 
|  |  | 
|  | // ____ XGraphicObjectResolver ____ | 
|  | virtual ::rtl::OUString SAL_CALL resolveGraphicObjectURL( const ::rtl::OUString& aURL ) | 
|  | throw (RuntimeException); | 
|  |  | 
|  | // ____ XBinaryStreamResolver ____ | 
|  | virtual Reference< io::XInputStream > SAL_CALL getInputStream( const ::rtl::OUString& aURL ) | 
|  | throw (RuntimeException); | 
|  | virtual Reference< io::XOutputStream > SAL_CALL createOutputStream() | 
|  | throw (RuntimeException); | 
|  | virtual ::rtl::OUString SAL_CALL resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream ) | 
|  | throw (RuntimeException); | 
|  |  | 
|  | // ____ XServiceInfo ____ | 
|  | virtual ::rtl::OUString SAL_CALL getImplementationName() | 
|  | throw (RuntimeException); | 
|  | virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) | 
|  | throw (RuntimeException); | 
|  | virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() | 
|  | throw (RuntimeException); | 
|  |  | 
|  | private: | 
|  | SvXMLGraphicHelperMode              m_eGraphicHelperMode; | 
|  | Reference< XGraphicObjectResolver > m_xGraphicObjectResolver; | 
|  | Reference< XBinaryStreamResolver >  m_xBinaryStreamResolver; | 
|  | }; | 
|  |  | 
|  | SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ) : | 
|  | impl::SvXMLGraphicImportExportHelper_Base( m_aMutex ), | 
|  | m_eGraphicHelperMode( eMode ) | 
|  | {} | 
|  |  | 
|  | void SAL_CALL SvXMLGraphicImportExportHelper::disposing() | 
|  | { | 
|  | Reference< XComponent > xComp( m_xGraphicObjectResolver, UNO_QUERY ); | 
|  | OSL_ASSERT( xComp.is()); | 
|  | if( xComp.is()) | 
|  | xComp->dispose(); | 
|  | // m_xBinaryStreamResolver is a reference to the same object => don't call | 
|  | // dispose() again | 
|  | } | 
|  |  | 
|  | // ____ XInitialization ____ | 
|  | void SAL_CALL SvXMLGraphicImportExportHelper::initialize( | 
|  | const Sequence< Any >& aArguments ) | 
|  | throw (Exception, RuntimeException) | 
|  | { | 
|  | Reference< embed::XStorage > xStorage; | 
|  | if( aArguments.getLength() > 0 ) | 
|  | aArguments[0] >>= xStorage; | 
|  |  | 
|  | SvXMLGraphicHelper * pHelper( SvXMLGraphicHelper::Create( xStorage, m_eGraphicHelperMode )); | 
|  | m_xGraphicObjectResolver.set( pHelper ); | 
|  | m_xBinaryStreamResolver.set( pHelper ); | 
|  | // SvXMLGraphicHelper::Create calls acquire.  Since we have two references | 
|  | // now it is safe (and necessary) to undo this acquire | 
|  | pHelper->release(); | 
|  | } | 
|  |  | 
|  | // ____ XGraphicObjectResolver ____ | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const ::rtl::OUString& aURL ) | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | return m_xGraphicObjectResolver->resolveGraphicObjectURL( aURL ); | 
|  | } | 
|  |  | 
|  |  | 
|  | // ____ XBinaryStreamResolver ____ | 
|  | Reference< io::XInputStream > SAL_CALL SvXMLGraphicImportExportHelper::getInputStream( const ::rtl::OUString& aURL ) | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | return m_xBinaryStreamResolver->getInputStream( aURL ); | 
|  | } | 
|  | Reference< io::XOutputStream > SAL_CALL SvXMLGraphicImportExportHelper::createOutputStream() | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | return m_xBinaryStreamResolver->createOutputStream(); | 
|  | } | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream ) | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | return m_xBinaryStreamResolver->resolveOutputStream( aBinaryStream ); | 
|  | } | 
|  |  | 
|  | // ____ XServiceInfo ____ | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::getImplementationName() | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ ) | 
|  | return SvXMLGraphicImportHelper_getImplementationName(); | 
|  | return SvXMLGraphicExportHelper_getImplementationName(); | 
|  | } | 
|  | ::sal_Bool SAL_CALL SvXMLGraphicImportExportHelper::supportsService( const ::rtl::OUString& ServiceName ) | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames()); | 
|  | const ::rtl::OUString * pBegin = aServiceNames.getConstArray(); | 
|  | const ::rtl::OUString * pEnd = pBegin + aServiceNames.getLength(); | 
|  | return (::std::find( pBegin, pEnd, ServiceName ) != pEnd); | 
|  | } | 
|  | Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicImportExportHelper::getSupportedServiceNames() | 
|  | throw (uno::RuntimeException) | 
|  | { | 
|  | if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ ) | 
|  | return SvXMLGraphicImportHelper_getSupportedServiceNames(); | 
|  | return SvXMLGraphicExportHelper_getSupportedServiceNames(); | 
|  | } | 
|  |  | 
|  | // import | 
|  | Reference< XInterface > SAL_CALL SvXMLGraphicImportHelper_createInstance(const Reference< XMultiServiceFactory > & /* rSMgr */ ) | 
|  | throw( Exception ) | 
|  | { | 
|  | return static_cast< XWeak* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_READ )); | 
|  | } | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicImportHelper_getImplementationName() | 
|  | throw() | 
|  | { | 
|  | return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicImportHelper" )); | 
|  | } | 
|  | Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicImportHelper_getSupportedServiceNames() | 
|  | throw() | 
|  | { | 
|  | // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service | 
|  | Sequence< ::rtl::OUString > aSupportedServiceNames( 2 ); | 
|  | aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) ); | 
|  | aSupportedServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) ); | 
|  | return aSupportedServiceNames; | 
|  | } | 
|  |  | 
|  | // export | 
|  | Reference< XInterface > SAL_CALL SvXMLGraphicExportHelper_createInstance(const Reference< XMultiServiceFactory > & /* rSMgr */ ) | 
|  | throw( Exception ) | 
|  | { | 
|  | return static_cast< XWeak* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_WRITE )); | 
|  | } | 
|  | ::rtl::OUString SAL_CALL SvXMLGraphicExportHelper_getImplementationName() | 
|  | throw() | 
|  | { | 
|  | return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicExportHelper" )); | 
|  | } | 
|  | Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicExportHelper_getSupportedServiceNames() | 
|  | throw() | 
|  | { | 
|  | // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service | 
|  | Sequence< ::rtl::OUString > aSupportedServiceNames( 2 ); | 
|  | aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) ); | 
|  | aSupportedServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) ); | 
|  | return aSupportedServiceNames; | 
|  | } | 
|  |  | 
|  | } // namespace svx |