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: xmlgrhlp.cxx,v $
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_svx.hxx"
33 #include <com/sun/star/embed/XTransactedObject.hpp>
34 #ifndef _COM_SUN_STAR_EMBED_ElementModes_HPP_
35 #include <com/sun/star/embed/ElementModes.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/lang/XInitialization.hpp>
41 #include <cppuhelper/compbase4.hxx>
43 #include <unotools/ucbstreamhelper.hxx>
44 #include <unotools/streamwrap.hxx>
45 #include <unotools/tempfile.hxx>
46 #include <tools/debug.hxx>
47 #include <vcl/cvtgrf.hxx>
48 #include <vcl/gfxlink.hxx>
49 #include <vcl/metaact.hxx>
50 #include <tools/zcodec.hxx>
53 #include "xmlgrhlp.hxx"
61 using namespace com::sun::star
;
62 using namespace com::sun::star::uno
;
63 using namespace com::sun::star::io
;
65 using ::com::sun::star::lang::XMultiServiceFactory
;
67 #define XML_GRAPHICSTORAGE_NAME "Pictures"
68 #define XML_PACKAGE_URL_BASE "vnd.sun.star.Package:"
69 #define XML_GRAPHICOBJECT_URL_BASE "vnd.sun.star.GraphicObject:"
71 // ---------------------------
72 // - SvXMLGraphicInputStream -
73 // ---------------------------
75 const MetaCommentAction
* ImplCheckForEPS( GDIMetaFile
& rMtf
)
77 static ByteString
aComment( (const sal_Char
*)"EPSReplacementGraphic" );
78 const MetaCommentAction
* pComment
= NULL
;
80 if ( ( rMtf
.GetActionCount() >= 2 )
81 && ( rMtf
.FirstAction()->GetType() == META_EPS_ACTION
)
82 && ( ((const MetaAction
*)rMtf
.GetAction( 1 ))->GetType() == META_COMMENT_ACTION
)
83 && ( ((const MetaCommentAction
*)rMtf
.GetAction( 1 ))->GetComment() == aComment
) )
84 pComment
= (const MetaCommentAction
*)rMtf
.GetAction( 1 );
89 class SvXMLGraphicInputStream
: public::cppu::WeakImplHelper1
< XInputStream
>
93 virtual sal_Int32 SAL_CALL
readBytes( Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
) throw(NotConnectedException
, BufferSizeExceededException
, RuntimeException
);
94 virtual sal_Int32 SAL_CALL
readSomeBytes(Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
) throw(NotConnectedException
, BufferSizeExceededException
, RuntimeException
);
95 virtual void SAL_CALL
skipBytes(sal_Int32 nBytesToSkip
) throw(NotConnectedException
, BufferSizeExceededException
, RuntimeException
);
96 virtual sal_Int32 SAL_CALL
available() throw(NotConnectedException
, RuntimeException
);
97 virtual void SAL_CALL
closeInput() throw(NotConnectedException
, RuntimeException
);
101 ::utl::TempFile maTmp
;
102 Reference
< XInputStream
> mxStmWrapper
;
105 SvXMLGraphicInputStream();
106 SvXMLGraphicInputStream( const SvXMLGraphicInputStream
& );
107 SvXMLGraphicInputStream
& operator==( SvXMLGraphicInputStream
& );
111 SvXMLGraphicInputStream( const ::rtl::OUString
& rGraphicId
);
112 virtual ~SvXMLGraphicInputStream();
114 sal_Bool
Exists() const { return mxStmWrapper
.is(); }
117 // -----------------------------------------------------------------------------
119 SvXMLGraphicInputStream::SvXMLGraphicInputStream( const ::rtl::OUString
& rGraphicId
)
121 String
aGraphicId( rGraphicId
);
122 GraphicObject
aGrfObject( ByteString( aGraphicId
, RTL_TEXTENCODING_ASCII_US
) );
124 maTmp
.EnableKillingFile();
126 if( aGrfObject
.GetType() != GRAPHIC_NONE
)
128 SvStream
* pStm
= ::utl::UcbStreamHelper::CreateStream( maTmp
.GetURL(), STREAM_WRITE
| STREAM_TRUNC
);
132 Graphic
aGraphic( (Graphic
&) aGrfObject
.GetGraphic() );
133 const GfxLink
aGfxLink( aGraphic
.GetLink() );
134 sal_Bool bRet
= sal_False
;
136 if( aGfxLink
.GetDataSize() && aGfxLink
.GetData() )
138 pStm
->Write( aGfxLink
.GetData(), aGfxLink
.GetDataSize() );
139 bRet
= ( pStm
->GetError() == 0 );
143 if( aGraphic
.GetType() == GRAPHIC_BITMAP
)
145 GraphicFilter
* pFilter
= GetGrfFilter();
148 if( aGraphic
.IsAnimated() )
149 aFormat
= String( RTL_CONSTASCII_USTRINGPARAM( "gif" ) );
151 aFormat
= String( RTL_CONSTASCII_USTRINGPARAM( "png" ) );
153 bRet
= ( pFilter
->ExportGraphic( aGraphic
, String(), *pStm
, pFilter
->GetExportFormatNumberForShortName( aFormat
) ) == 0 );
155 else if( aGraphic
.GetType() == GRAPHIC_GDIMETAFILE
)
157 pStm
->SetVersion( SOFFICE_FILEFORMAT_8
);
158 pStm
->SetCompressMode( COMPRESSMODE_ZBITMAP
);
159 ( (GDIMetaFile
&) aGraphic
.GetGDIMetaFile() ).Write( *pStm
);
160 bRet
= ( pStm
->GetError() == 0 );
167 mxStmWrapper
= new ::utl::OInputStreamWrapper( pStm
, sal_True
);
175 // -----------------------------------------------------------------------------
177 SvXMLGraphicInputStream::~SvXMLGraphicInputStream()
181 // -----------------------------------------------------------------------------
183 sal_Int32 SAL_CALL
SvXMLGraphicInputStream::readBytes( Sequence
< sal_Int8
>& rData
, sal_Int32 nBytesToRead
)
184 throw( NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
186 if( !mxStmWrapper
.is() )
187 throw NotConnectedException();
189 return mxStmWrapper
->readBytes( rData
, nBytesToRead
);
192 // -----------------------------------------------------------------------------
194 sal_Int32 SAL_CALL
SvXMLGraphicInputStream::readSomeBytes( Sequence
< sal_Int8
>& rData
, sal_Int32 nMaxBytesToRead
)
195 throw( NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
197 if( !mxStmWrapper
.is() )
198 throw NotConnectedException() ;
200 return mxStmWrapper
->readSomeBytes( rData
, nMaxBytesToRead
);
203 // -----------------------------------------------------------------------------
205 void SAL_CALL
SvXMLGraphicInputStream::skipBytes( sal_Int32 nBytesToSkip
)
206 throw( NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
208 if( !mxStmWrapper
.is() )
209 throw NotConnectedException() ;
211 mxStmWrapper
->skipBytes( nBytesToSkip
);
214 // -----------------------------------------------------------------------------
216 sal_Int32 SAL_CALL
SvXMLGraphicInputStream::available() throw( NotConnectedException
, RuntimeException
)
218 if( !mxStmWrapper
.is() )
219 throw NotConnectedException() ;
221 return mxStmWrapper
->available();
224 // -----------------------------------------------------------------------------
226 void SAL_CALL
SvXMLGraphicInputStream::closeInput() throw( NotConnectedException
, RuntimeException
)
228 if( !mxStmWrapper
.is() )
229 throw NotConnectedException() ;
231 mxStmWrapper
->closeInput();
234 // ----------------------------
235 // - SvXMLGraphicOutputStream -
236 // ----------------------------
238 class SvXMLGraphicOutputStream
: public::cppu::WeakImplHelper1
< XOutputStream
>
243 virtual void SAL_CALL
writeBytes( const Sequence
< sal_Int8
>& rData
) throw( NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
);
244 virtual void SAL_CALL
flush() throw( NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
);
245 virtual void SAL_CALL
closeOutput() throw( NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
);
249 ::utl::TempFile
* mpTmp
;
251 Reference
< XOutputStream
> mxStmWrapper
;
252 GraphicObject maGrfObj
;
256 SvXMLGraphicOutputStream( const SvXMLGraphicOutputStream
& );
257 SvXMLGraphicOutputStream
& operator==( SvXMLGraphicOutputStream
& );
261 SvXMLGraphicOutputStream();
262 virtual ~SvXMLGraphicOutputStream();
264 sal_Bool
Exists() const { return mxStmWrapper
.is(); }
265 const GraphicObject
& GetGraphicObject();
268 // -----------------------------------------------------------------------------
270 SvXMLGraphicOutputStream::SvXMLGraphicOutputStream() :
271 mpTmp( new ::utl::TempFile
),
272 mbClosed( sal_False
)
274 mpTmp
->EnableKillingFile();
276 mpOStm
= ::utl::UcbStreamHelper::CreateStream( mpTmp
->GetURL(), STREAM_WRITE
| STREAM_TRUNC
);
279 mxStmWrapper
= new ::utl::OOutputStreamWrapper( *mpOStm
);
282 // -----------------------------------------------------------------------------
284 SvXMLGraphicOutputStream::~SvXMLGraphicOutputStream()
290 // -----------------------------------------------------------------------------
292 void SAL_CALL
SvXMLGraphicOutputStream::writeBytes( const Sequence
< sal_Int8
>& rData
)
293 throw( NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
295 if( !mxStmWrapper
.is() )
296 throw NotConnectedException() ;
298 mxStmWrapper
->writeBytes( rData
);
301 // -----------------------------------------------------------------------------
303 void SAL_CALL
SvXMLGraphicOutputStream::flush()
304 throw( NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
306 if( !mxStmWrapper
.is() )
307 throw NotConnectedException() ;
309 mxStmWrapper
->flush();
312 // -----------------------------------------------------------------------------
314 void SAL_CALL
SvXMLGraphicOutputStream::closeOutput()
315 throw( NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
317 if( !mxStmWrapper
.is() )
318 throw NotConnectedException() ;
320 mxStmWrapper
->closeOutput();
321 mxStmWrapper
= Reference
< XOutputStream
>();
326 // ------------------------------------------------------------------------------
328 const GraphicObject
& SvXMLGraphicOutputStream::GetGraphicObject()
330 if( mbClosed
&& ( maGrfObj
.GetType() == GRAPHIC_NONE
) && mpOStm
)
335 USHORT nFormat
= GRFILTER_FORMAT_DONTKNOW
;
336 USHORT pDeterminedFormat
= GRFILTER_FORMAT_DONTKNOW
;
337 GetGrfFilter()->ImportGraphic( aGraphic
, String(), *mpOStm
,nFormat
,&pDeterminedFormat
);
339 if (pDeterminedFormat
== GRFILTER_FORMAT_DONTKNOW
)
341 //Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format
342 //unzip them and try again
344 BYTE sFirstBytes
[ 2 ];
346 mpOStm
->Seek( STREAM_SEEK_TO_END
);
347 ULONG nStreamLen
= mpOStm
->Tell();
352 SvLockBytes
* pLockBytes
= mpOStm
->GetLockBytes();
354 pLockBytes
->SetSynchronMode( TRUE
);
356 mpOStm
->Seek( STREAM_SEEK_TO_END
);
357 nStreamLen
= mpOStm
->Tell();
360 if( nStreamLen
>= 2 )
363 mpOStm
->Read( sFirstBytes
, 2 );
365 if( sFirstBytes
[0] == 0x1f && sFirstBytes
[1] == 0x8b )
367 SvMemoryStream
* pDest
= new SvMemoryStream
;
368 ZCodec
aZCodec( 0x8000, 0x8000 );
369 aZCodec
.BeginCompression(ZCODEC_GZ_LIB
);
371 aZCodec
.Decompress( *mpOStm
, *pDest
);
373 if (aZCodec
.EndCompression() && pDest
)
375 pDest
->Seek( STREAM_SEEK_TO_END
);
376 ULONG nStreamLen_
= pDest
->Tell();
380 GetGrfFilter()->ImportGraphic( aGraphic
, String(), *pDest
,nFormat
,&pDeterminedFormat
);
389 if( maGrfObj
.GetType() != GRAPHIC_NONE
)
391 delete mpOStm
, mpOStm
= NULL
;
392 delete mpTmp
, mpTmp
= NULL
;
399 // ----------------------
400 // - SvXMLGraphicHelper -
401 // ----------------------
403 SvXMLGraphicHelper::SvXMLGraphicHelper( SvXMLGraphicHelperMode eCreateMode
) :
404 ::cppu::WeakComponentImplHelper2
< ::com::sun::star::document::XGraphicObjectResolver
,
405 ::com::sun::star::document::XBinaryStreamResolver
>( maMutex
)
407 Init( NULL
, eCreateMode
, sal_False
);
410 SvXMLGraphicHelper::SvXMLGraphicHelper() :
411 ::cppu::WeakComponentImplHelper2
< ::com::sun::star::document::XGraphicObjectResolver
,
412 ::com::sun::star::document::XBinaryStreamResolver
>( maMutex
)
416 // -----------------------------------------------------------------------------
418 SvXMLGraphicHelper::~SvXMLGraphicHelper()
422 // -----------------------------------------------------------------------------
424 void SAL_CALL
SvXMLGraphicHelper::disposing()
428 // -----------------------------------------------------------------------------
430 sal_Bool
SvXMLGraphicHelper::ImplGetStreamNames( const ::rtl::OUString
& rURLStr
,
431 ::rtl::OUString
& rPictureStorageName
,
432 ::rtl::OUString
& rPictureStreamName
)
434 String
aURLStr( rURLStr
);
435 sal_Bool bRet
= sal_False
;
439 aURLStr
= aURLStr
.GetToken( aURLStr
.GetTokenCount( ':' ) - 1, ':' );
440 const sal_uInt32 nTokenCount
= aURLStr
.GetTokenCount( '/' );
442 if( 1 == nTokenCount
)
444 rPictureStorageName
= String( RTL_CONSTASCII_USTRINGPARAM( XML_GRAPHICSTORAGE_NAME
) );
445 rPictureStreamName
= aURLStr
;
448 else if( 2 == nTokenCount
)
450 rPictureStorageName
= aURLStr
.GetToken( 0, '/' );
452 DBG_ASSERT( rPictureStorageName
.getLength() &&
453 rPictureStorageName
.getStr()[ 0 ] != '#',
454 "invalid relative URL" );
456 rPictureStreamName
= aURLStr
.GetToken( 1, '/' );
461 DBG_ERROR( "SvXMLGraphicHelper::ImplInsertGraphicURL: invalid scheme" );
468 // -----------------------------------------------------------------------------
470 uno::Reference
< embed::XStorage
> SvXMLGraphicHelper::ImplGetGraphicStorage( const ::rtl::OUString
& rStorageName
)
472 uno::Reference
< embed::XStorage
> xRetStorage
;
473 if( mxRootStorage
.is() )
477 xRetStorage
= mxRootStorage
->openStorageElement(
478 maCurStorageName
= rStorageName
,
479 ( GRAPHICHELPER_MODE_WRITE
== meCreateMode
)
480 ? embed::ElementModes::READWRITE
481 : embed::ElementModes::READ
);
483 catch ( uno::Exception
& )
486 //#i43196# try again to open the storage element - this time readonly
487 if(!xRetStorage
.is())
491 xRetStorage
= mxRootStorage
->openStorageElement( maCurStorageName
= rStorageName
, embed::ElementModes::READ
);
493 catch ( uno::Exception
& )
502 // -----------------------------------------------------------------------------
504 SvxGraphicHelperStream_Impl
SvXMLGraphicHelper::ImplGetGraphicStream( const ::rtl::OUString
& rPictureStorageName
,
505 const ::rtl::OUString
& rPictureStreamName
,
508 SvxGraphicHelperStream_Impl aRet
;
509 aRet
.xStorage
= ImplGetGraphicStorage( rPictureStorageName
);
511 if( aRet
.xStorage
.is() )
513 sal_Int32 nMode
= embed::ElementModes::READ
;
514 if ( GRAPHICHELPER_MODE_WRITE
== meCreateMode
)
516 nMode
= embed::ElementModes::READWRITE
;
518 nMode
|= embed::ElementModes::TRUNCATE
;
521 aRet
.xStream
= aRet
.xStorage
->openStreamElement( rPictureStreamName
, nMode
);
522 if( aRet
.xStream
.is() && ( GRAPHICHELPER_MODE_WRITE
== meCreateMode
) )
524 //REMOVE ::rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM("Encrypted") );
525 ::rtl::OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
526 uno::Reference
< beans::XPropertySet
> xProps( aRet
.xStream
, uno::UNO_QUERY
);
527 xProps
->setPropertyValue( aPropName
, uno::makeAny( sal_True
) );
534 // -----------------------------------------------------------------------------
536 String
SvXMLGraphicHelper::ImplGetGraphicMimeType( const String
& rFileName
) const
538 struct XMLGraphicMimeTypeMapper
541 const char* pMimeType
;
544 static XMLGraphicMimeTypeMapper aMapper
[] =
546 { "gif", "image/gif" },
547 { "png", "image/png" },
548 { "jpg", "image/jpeg" },
549 { "tif", "image/tiff" }
554 if( ( rFileName
.Len() >= 4 ) && ( rFileName
.GetChar( rFileName
.Len() - 4 ) == '.' ) )
556 const ByteString
aExt( rFileName
.Copy( rFileName
.Len() - 3 ), RTL_TEXTENCODING_ASCII_US
);
558 for( long i
= 0, nCount
= sizeof( aMapper
) / sizeof( aMapper
[ 0 ] ); ( i
< nCount
) && !aMimeType
.Len(); i
++ )
559 if( aExt
== aMapper
[ i
].pExt
)
560 aMimeType
= String( aMapper
[ i
].pMimeType
, RTL_TEXTENCODING_ASCII_US
);
566 // -----------------------------------------------------------------------------
568 Graphic
SvXMLGraphicHelper::ImplReadGraphic( const ::rtl::OUString
& rPictureStorageName
,
569 const ::rtl::OUString
& rPictureStreamName
)
572 SvxGraphicHelperStream_Impl
aStream( ImplGetGraphicStream( rPictureStorageName
, rPictureStreamName
, FALSE
) );
573 if( aStream
.xStream
.is() )
575 SvStream
* pStream
= utl::UcbStreamHelper::CreateStream( aStream
.xStream
);
576 GetGrfFilter()->ImportGraphic( aGraphic
, String(), *pStream
);
583 // -----------------------------------------------------------------------------
585 sal_Bool
SvXMLGraphicHelper::ImplWriteGraphic( const ::rtl::OUString
& rPictureStorageName
,
586 const ::rtl::OUString
& rPictureStreamName
,
587 const ::rtl::OUString
& rGraphicId
)
589 String
aGraphicId( rGraphicId
);
590 GraphicObject
aGrfObject( ByteString( aGraphicId
, RTL_TEXTENCODING_ASCII_US
) );
591 sal_Bool bRet
= sal_False
;
593 if( aGrfObject
.GetType() != GRAPHIC_NONE
)
595 SvxGraphicHelperStream_Impl
aStream( ImplGetGraphicStream( rPictureStorageName
, rPictureStreamName
, FALSE
) );
596 if( aStream
.xStream
.is() )
598 Graphic
aGraphic( (Graphic
&) aGrfObject
.GetGraphic() );
599 const GfxLink
aGfxLink( aGraphic
.GetLink() );
600 const ::rtl::OUString
aMimeType( ImplGetGraphicMimeType( rPictureStreamName
) );
602 uno::Reference
< beans::XPropertySet
> xProps( aStream
.xStream
, uno::UNO_QUERY
);
604 // set stream properties (MediaType/Compression)
605 if( aMimeType
.getLength() )
608 xProps
->setPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), aAny
);
611 const sal_Bool bCompressed
= ( ( 0 == aMimeType
.getLength() ) || ( aMimeType
== ::rtl::OUString::createFromAscii( "image/tiff" ) ) );
612 aAny
<<= bCompressed
;
613 xProps
->setPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), aAny
);
615 SvStream
* pStream
= utl::UcbStreamHelper::CreateStream( aStream
.xStream
);
616 if( aGfxLink
.GetDataSize() && aGfxLink
.GetData() )
617 pStream
->Write( aGfxLink
.GetData(), aGfxLink
.GetDataSize() );
620 if( aGraphic
.GetType() == GRAPHIC_BITMAP
)
622 GraphicFilter
* pFilter
= GetGrfFilter();
625 if( aGraphic
.IsAnimated() )
626 aFormat
= String( RTL_CONSTASCII_USTRINGPARAM( "gif" ) );
628 aFormat
= String( RTL_CONSTASCII_USTRINGPARAM( "png" ) );
630 bRet
= ( pFilter
->ExportGraphic( aGraphic
, String(), *pStream
,
631 pFilter
->GetExportFormatNumberForShortName( aFormat
) ) == 0 );
633 else if( aGraphic
.GetType() == GRAPHIC_GDIMETAFILE
)
635 pStream
->SetVersion( SOFFICE_FILEFORMAT_8
);
636 pStream
->SetCompressMode( COMPRESSMODE_ZBITMAP
);
638 // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
639 GDIMetaFile
& rMtf( (GDIMetaFile
&)aGraphic
.GetGDIMetaFile() );
640 const MetaCommentAction
* pComment
= ImplCheckForEPS( rMtf
);
643 sal_uInt32 nSize
= pComment
->GetDataSize();
644 const BYTE
* pData
= pComment
->GetData();
645 if ( nSize
&& pData
)
646 pStream
->Write( pData
, nSize
);
648 const MetaEPSAction
* pAct
= ( (const MetaEPSAction
*)rMtf
.FirstAction() );
649 const GfxLink
& rLink
= pAct
->GetLink();
651 pStream
->Write( rLink
.GetData(), rLink
.GetDataSize() );
654 rMtf
.Write( *pStream
);
656 bRet
= ( pStream
->GetError() == 0 );
659 uno::Reference
< embed::XTransactedObject
> xStorage(
660 aStream
.xStorage
, uno::UNO_QUERY
);
662 aStream
.xStream
->getOutputStream()->closeOutput();
671 // -----------------------------------------------------------------------------
673 void SvXMLGraphicHelper::ImplInsertGraphicURL( const ::rtl::OUString
& rURLStr
, sal_uInt32 nInsertPos
, rtl::OUString
& rRequestedFileName
)
675 rtl::OUString
aURLString( rURLStr
);
676 ::rtl::OUString aPictureStorageName
, aPictureStreamName
;
677 if( ( maURLSet
.find( aURLString
) != maURLSet
.end() ) )
679 URLPairVector::iterator
aIter( maGrfURLs
.begin() ), aEnd( maGrfURLs
.end() );
680 while( aIter
!= aEnd
)
682 if( aURLString
== (*aIter
).first
)
684 maGrfURLs
[ nInsertPos
].second
= (*aIter
).second
;
691 else if( ImplGetStreamNames( aURLString
, aPictureStorageName
, aPictureStreamName
) )
693 URLPair
& rURLPair
= maGrfURLs
[ nInsertPos
];
695 if( GRAPHICHELPER_MODE_READ
== meCreateMode
)
697 const GraphicObject
aObj( ImplReadGraphic( aPictureStorageName
, aPictureStreamName
) );
699 if( aObj
.GetType() != GRAPHIC_NONE
)
701 const static ::rtl::OUString
aBaseURL( RTL_CONSTASCII_USTRINGPARAM( XML_GRAPHICOBJECT_URL_BASE
) );
703 maGrfObjs
.push_back( aObj
);
704 rURLPair
.second
= aBaseURL
;
705 rURLPair
.second
+= String( aObj
.GetUniqueID().GetBuffer(), RTL_TEXTENCODING_ASCII_US
);
708 rURLPair
.second
= String();
712 const String
aGraphicObjectId( aPictureStreamName
);
713 const GraphicObject
aGrfObject( ByteString( aGraphicObjectId
, RTL_TEXTENCODING_ASCII_US
) );
715 if( aGrfObject
.GetType() != GRAPHIC_NONE
)
717 String
aStreamName( aGraphicObjectId
);
718 Graphic
aGraphic( (Graphic
&) aGrfObject
.GetGraphic() );
719 const GfxLink
aGfxLink( aGraphic
.GetLink() );
722 if( aGfxLink
.GetDataSize() )
724 switch( aGfxLink
.GetType() )
726 case( GFX_LINK_TYPE_EPS_BUFFER
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) ); break;
727 case( GFX_LINK_TYPE_NATIVE_GIF
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) ); break;
728 case( GFX_LINK_TYPE_NATIVE_JPG
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".jpg" ) ); break;
729 case( GFX_LINK_TYPE_NATIVE_PNG
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ); break;
730 case( GFX_LINK_TYPE_NATIVE_TIF
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".tif" ) ); break;
731 case( GFX_LINK_TYPE_NATIVE_WMF
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".wmf" ) ); break;
732 case( GFX_LINK_TYPE_NATIVE_MET
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".met" ) ); break;
733 case( GFX_LINK_TYPE_NATIVE_PCT
): aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".pct" ) ); break;
736 aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".grf" ) );
742 if( aGrfObject
.GetType() == GRAPHIC_BITMAP
)
744 if( aGrfObject
.IsAnimated() )
745 aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) );
747 aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) );
749 else if( aGrfObject
.GetType() == GRAPHIC_GDIMETAFILE
)
751 // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
752 GDIMetaFile
& rMtf( (GDIMetaFile
&)aGraphic
.GetGDIMetaFile() );
753 if ( ImplCheckForEPS( rMtf
) )
754 aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) );
756 aExtension
= String( RTL_CONSTASCII_USTRINGPARAM( ".svm" ) );
760 rtl::OUString aURLEntry
;
761 const String
sPictures( RTL_CONSTASCII_USTRINGPARAM( "Pictures/" ) );
763 if ( rRequestedFileName
.getLength() )
765 aURLEntry
= sPictures
;
766 aURLEntry
+= rRequestedFileName
;
767 aURLEntry
+= aExtension
;
769 URLPairVector::iterator
aIter( maGrfURLs
.begin() ), aEnd( maGrfURLs
.end() );
770 while( aIter
!= aEnd
)
772 if( aURLEntry
== (*aIter
).second
)
777 aStreamName
= rRequestedFileName
;
780 aStreamName
+= aExtension
;
782 if( mbDirect
&& aStreamName
.Len() )
783 ImplWriteGraphic( aPictureStorageName
, aStreamName
, aGraphicObjectId
);
785 rURLPair
.second
= sPictures
;
786 rURLPair
.second
+= aStreamName
;
790 maURLSet
.insert( aURLString
);
794 // -----------------------------------------------------------------------------
796 void SvXMLGraphicHelper::Init( const uno::Reference
< embed::XStorage
>& rXMLStorage
,
797 SvXMLGraphicHelperMode eCreateMode
,
800 mxRootStorage
= rXMLStorage
;
801 meCreateMode
= eCreateMode
;
802 mbDirect
= ( ( GRAPHICHELPER_MODE_READ
== meCreateMode
) ? bDirect
: sal_True
);
805 // -----------------------------------------------------------------------------
807 SvXMLGraphicHelper
* SvXMLGraphicHelper::Create( const uno::Reference
< embed::XStorage
>& rXMLStorage
,
808 SvXMLGraphicHelperMode eCreateMode
,
811 SvXMLGraphicHelper
* pThis
= new SvXMLGraphicHelper
;
814 pThis
->Init( rXMLStorage
, eCreateMode
, bDirect
);
819 // -----------------------------------------------------------------------------
821 SvXMLGraphicHelper
* SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode eCreateMode
)
823 SvXMLGraphicHelper
* pThis
= new SvXMLGraphicHelper
;
826 pThis
->Init( NULL
, eCreateMode
, sal_False
);
831 // -----------------------------------------------------------------------------
833 void SvXMLGraphicHelper::Destroy( SvXMLGraphicHelper
* pSvXMLGraphicHelper
)
835 if( pSvXMLGraphicHelper
)
837 pSvXMLGraphicHelper
->dispose();
838 pSvXMLGraphicHelper
->release();
842 // -----------------------------------------------------------------------------
844 // XGraphicObjectResolver
845 ::rtl::OUString SAL_CALL
SvXMLGraphicHelper::resolveGraphicObjectURL( const ::rtl::OUString
& rURL
)
846 throw(uno::RuntimeException
)
848 ::osl::MutexGuard
aGuard( maMutex
);
849 const sal_Int32 nIndex
= maGrfURLs
.size();
851 rtl::OUString
aURL( rURL
);
852 rtl::OUString aUserData
;
853 rtl::OUString aRequestedFileName
;
855 sal_Int32 nUser
= rURL
.indexOf( '?', 0 );
858 aURL
= rtl::OUString( rURL
.copy( 0, nUser
) );
860 aUserData
= rURL
.copy( nUser
, rURL
.getLength() - nUser
);
862 if ( aUserData
.getLength() )
864 sal_Int32 nIndex2
= 0;
867 rtl::OUString aToken
= aUserData
.getToken( 0, ';', nIndex2
);
868 sal_Int32 n
= aToken
.indexOf( '=' );
869 if ( ( n
> 0 ) && ( ( n
+ 1 ) < aToken
.getLength() ) )
871 rtl::OUString
aParam( aToken
.copy( 0, n
) );
872 rtl::OUString
aValue( aToken
.copy( n
+ 1, aToken
.getLength() - ( n
+ 1 ) ) );
874 const rtl::OUString
sRequestedName( RTL_CONSTASCII_USTRINGPARAM("requestedName") );
875 if ( aParam
.match( sRequestedName
) )
876 aRequestedFileName
= aValue
;
879 while ( nIndex2
>= 0 );
882 maGrfURLs
.push_back( ::std::make_pair( aURL
, ::rtl::OUString() ) );
883 ImplInsertGraphicURL( aURL
, nIndex
, aRequestedFileName
);
885 return maGrfURLs
[ nIndex
].second
;
888 // -----------------------------------------------------------------------------
890 // XBinaryStreamResolver
891 Reference
< XInputStream
> SAL_CALL
SvXMLGraphicHelper::getInputStream( const ::rtl::OUString
& rURL
)
892 throw( RuntimeException
)
894 Reference
< XInputStream
> xRet
;
895 ::rtl::OUString aPictureStorageName
, aGraphicId
;
898 if( ( GRAPHICHELPER_MODE_WRITE
== meCreateMode
) &&
899 ImplGetStreamNames( rURL
, aPictureStorageName
, aGraphicId
) )
901 SvXMLGraphicInputStream
* pInputStream
= new SvXMLGraphicInputStream( aGraphicId
);
903 if( pInputStream
->Exists() )
912 // -----------------------------------------------------------------------------
914 Reference
< XOutputStream
> SAL_CALL
SvXMLGraphicHelper::createOutputStream()
915 throw( RuntimeException
)
917 Reference
< XOutputStream
> xRet
;
919 if( GRAPHICHELPER_MODE_READ
== meCreateMode
)
921 SvXMLGraphicOutputStream
* pOutputStream
= new SvXMLGraphicOutputStream
;
923 if( pOutputStream
->Exists() )
924 maGrfStms
.push_back( xRet
= pOutputStream
);
926 delete pOutputStream
;
932 // -----------------------------------------------------------------------------
934 ::rtl::OUString SAL_CALL
SvXMLGraphicHelper::resolveOutputStream( const Reference
< XOutputStream
>& rxBinaryStream
)
935 throw( RuntimeException
)
937 ::rtl::OUString aRet
;
939 if( ( GRAPHICHELPER_MODE_READ
== meCreateMode
) && rxBinaryStream
.is() )
941 if( ::std::find( maGrfStms
.begin(), maGrfStms
.end(), rxBinaryStream
) != maGrfStms
.end() )
943 SvXMLGraphicOutputStream
* pOStm
= static_cast< SvXMLGraphicOutputStream
* >( rxBinaryStream
.get() );
947 const GraphicObject
& rGrfObj
= pOStm
->GetGraphicObject();
948 const ::rtl::OUString
aId( ::rtl::OUString::createFromAscii( rGrfObj
.GetUniqueID().GetBuffer() ) );
950 if( aId
.getLength() )
952 aRet
= ::rtl::OUString::createFromAscii( XML_GRAPHICOBJECT_URL_BASE
);
963 // --------------------------------------------------------------------------------
965 // for instantiation via service manager
971 typedef ::cppu::WeakComponentImplHelper4
<
972 lang::XInitialization
,
973 document::XGraphicObjectResolver
,
974 document::XBinaryStreamResolver
,
976 SvXMLGraphicImportExportHelper_Base
;
980 virtual ~MutexContainer();
983 mutable ::osl::Mutex m_aMutex
;
985 MutexContainer::~MutexContainer()
989 class SvXMLGraphicImportExportHelper
:
990 public impl::MutexContainer
,
991 public impl::SvXMLGraphicImportExportHelper_Base
994 SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode
);
997 // is called from WeakComponentImplHelper when XComponent::dispose() was
998 // called from outside
999 virtual void SAL_CALL
disposing();
1001 // ____ XInitialization ____
1002 // one argument is allowed, which is the XStorage
1003 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
)
1007 // ____ XGraphicObjectResolver ____
1008 virtual ::rtl::OUString SAL_CALL
resolveGraphicObjectURL( const ::rtl::OUString
& aURL
)
1009 throw (RuntimeException
);
1011 // ____ XBinaryStreamResolver ____
1012 virtual Reference
< io::XInputStream
> SAL_CALL
getInputStream( const ::rtl::OUString
& aURL
)
1013 throw (RuntimeException
);
1014 virtual Reference
< io::XOutputStream
> SAL_CALL
createOutputStream()
1015 throw (RuntimeException
);
1016 virtual ::rtl::OUString SAL_CALL
resolveOutputStream( const Reference
< io::XOutputStream
>& aBinaryStream
)
1017 throw (RuntimeException
);
1019 // ____ XServiceInfo ____
1020 virtual ::rtl::OUString SAL_CALL
getImplementationName()
1021 throw (RuntimeException
);
1022 virtual ::sal_Bool SAL_CALL
supportsService( const ::rtl::OUString
& ServiceName
)
1023 throw (RuntimeException
);
1024 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames()
1025 throw (RuntimeException
);
1028 SvXMLGraphicHelperMode m_eGraphicHelperMode
;
1029 Reference
< XGraphicObjectResolver
> m_xGraphicObjectResolver
;
1030 Reference
< XBinaryStreamResolver
> m_xBinaryStreamResolver
;
1033 SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode
) :
1034 impl::SvXMLGraphicImportExportHelper_Base( m_aMutex
),
1035 m_eGraphicHelperMode( eMode
)
1038 void SAL_CALL
SvXMLGraphicImportExportHelper::disposing()
1040 Reference
< XComponent
> xComp( m_xGraphicObjectResolver
, UNO_QUERY
);
1041 OSL_ASSERT( xComp
.is());
1044 // m_xBinaryStreamResolver is a reference to the same object => don't call
1048 // ____ XInitialization ____
1049 void SAL_CALL
SvXMLGraphicImportExportHelper::initialize(
1050 const Sequence
< Any
>& aArguments
)
1051 throw (Exception
, RuntimeException
)
1053 Reference
< embed::XStorage
> xStorage
;
1054 if( aArguments
.getLength() > 0 )
1055 aArguments
[0] >>= xStorage
;
1057 SvXMLGraphicHelper
* pHelper( SvXMLGraphicHelper::Create( xStorage
, m_eGraphicHelperMode
));
1058 m_xGraphicObjectResolver
.set( pHelper
);
1059 m_xBinaryStreamResolver
.set( pHelper
);
1060 // SvXMLGraphicHelper::Create calls acquire. Since we have two references
1061 // now it is safe (and necessary) to undo this acquire
1065 // ____ XGraphicObjectResolver ____
1066 ::rtl::OUString SAL_CALL
SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const ::rtl::OUString
& aURL
)
1067 throw (uno::RuntimeException
)
1069 return m_xGraphicObjectResolver
->resolveGraphicObjectURL( aURL
);
1073 // ____ XBinaryStreamResolver ____
1074 Reference
< io::XInputStream
> SAL_CALL
SvXMLGraphicImportExportHelper::getInputStream( const ::rtl::OUString
& aURL
)
1075 throw (uno::RuntimeException
)
1077 return m_xBinaryStreamResolver
->getInputStream( aURL
);
1079 Reference
< io::XOutputStream
> SAL_CALL
SvXMLGraphicImportExportHelper::createOutputStream()
1080 throw (uno::RuntimeException
)
1082 return m_xBinaryStreamResolver
->createOutputStream();
1084 ::rtl::OUString SAL_CALL
SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference
< io::XOutputStream
>& aBinaryStream
)
1085 throw (uno::RuntimeException
)
1087 return m_xBinaryStreamResolver
->resolveOutputStream( aBinaryStream
);
1090 // ____ XServiceInfo ____
1091 ::rtl::OUString SAL_CALL
SvXMLGraphicImportExportHelper::getImplementationName()
1092 throw (uno::RuntimeException
)
1094 if( m_eGraphicHelperMode
== GRAPHICHELPER_MODE_READ
)
1095 return SvXMLGraphicImportHelper_getImplementationName();
1096 return SvXMLGraphicExportHelper_getImplementationName();
1098 ::sal_Bool SAL_CALL
SvXMLGraphicImportExportHelper::supportsService( const ::rtl::OUString
& ServiceName
)
1099 throw (uno::RuntimeException
)
1101 Sequence
< ::rtl::OUString
> aServiceNames( getSupportedServiceNames());
1102 const ::rtl::OUString
* pBegin
= aServiceNames
.getConstArray();
1103 const ::rtl::OUString
* pEnd
= pBegin
+ aServiceNames
.getLength();
1104 return (::std::find( pBegin
, pEnd
, ServiceName
) != pEnd
);
1106 Sequence
< ::rtl::OUString
> SAL_CALL
SvXMLGraphicImportExportHelper::getSupportedServiceNames()
1107 throw (uno::RuntimeException
)
1109 if( m_eGraphicHelperMode
== GRAPHICHELPER_MODE_READ
)
1110 return SvXMLGraphicImportHelper_getSupportedServiceNames();
1111 return SvXMLGraphicExportHelper_getSupportedServiceNames();
1115 Reference
< XInterface
> SAL_CALL
SvXMLGraphicImportHelper_createInstance(const Reference
< XMultiServiceFactory
> & /* rSMgr */ )
1118 return static_cast< XWeak
* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_READ
));
1120 ::rtl::OUString SAL_CALL
SvXMLGraphicImportHelper_getImplementationName()
1123 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicImportHelper" ));
1125 Sequence
< ::rtl::OUString
> SAL_CALL
SvXMLGraphicImportHelper_getSupportedServiceNames()
1128 // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service
1129 Sequence
< ::rtl::OUString
> aSupportedServiceNames( 2 );
1130 aSupportedServiceNames
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) );
1131 aSupportedServiceNames
[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) );
1132 return aSupportedServiceNames
;
1136 Reference
< XInterface
> SAL_CALL
SvXMLGraphicExportHelper_createInstance(const Reference
< XMultiServiceFactory
> & /* rSMgr */ )
1139 return static_cast< XWeak
* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_WRITE
));
1141 ::rtl::OUString SAL_CALL
SvXMLGraphicExportHelper_getImplementationName()
1144 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicExportHelper" ));
1146 Sequence
< ::rtl::OUString
> SAL_CALL
SvXMLGraphicExportHelper_getSupportedServiceNames()
1149 // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service
1150 Sequence
< ::rtl::OUString
> aSupportedServiceNames( 2 );
1151 aSupportedServiceNames
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) );
1152 aSupportedServiceNames
[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) );
1153 return aSupportedServiceNames
;