Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <boost/noncopyable.hpp>
23 : #include <comphelper/string.hxx>
24 : #include <sal/macros.h>
25 : #include <com/sun/star/embed/XTransactedObject.hpp>
26 : #include <com/sun/star/embed/ElementModes.hpp>
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/lang/XServiceInfo.hpp>
30 : #include <com/sun/star/lang/XInitialization.hpp>
31 : #include <cppuhelper/compbase4.hxx>
32 : #include <cppuhelper/supportsservice.hxx>
33 :
34 : #include <rtl/ref.hxx>
35 : #include <unotools/ucbstreamhelper.hxx>
36 : #include <unotools/streamwrap.hxx>
37 : #include <unotools/tempfile.hxx>
38 : #include <unotools/saveopt.hxx>
39 : #include <tools/debug.hxx>
40 : #include <vcl/cvtgrf.hxx>
41 : #include <vcl/gfxlink.hxx>
42 : #include <vcl/metaact.hxx>
43 : #include <tools/zcodec.hxx>
44 :
45 : #include <vcl/graphicfilter.hxx>
46 : #include "svx/xmlgrhlp.hxx"
47 : #include "svx/xmleohlp.hxx"
48 :
49 : #include <algorithm>
50 :
51 : using namespace com::sun::star;
52 : using namespace com::sun::star::uno;
53 : using namespace com::sun::star::io;
54 :
55 : using ::com::sun::star::lang::XMultiServiceFactory;
56 :
57 : #define XML_GRAPHICSTORAGE_NAME "Pictures"
58 : #define XML_GRAPHICOBJECT_URL_BASE "vnd.sun.star.GraphicObject:"
59 :
60 : namespace {
61 :
62 0 : const MetaCommentAction* ImplCheckForEPS( GDIMetaFile& rMtf )
63 : {
64 0 : const MetaCommentAction* pComment = NULL;
65 :
66 0 : if ( ( rMtf.GetActionSize() >= 2 )
67 0 : && ( rMtf.FirstAction()->GetType() == META_EPS_ACTION )
68 0 : && ( ((const MetaAction*)rMtf.GetAction( 1 ))->GetType() == META_COMMENT_ACTION )
69 0 : && ( ((const MetaCommentAction*)rMtf.GetAction( 1 ))->GetComment() == "EPSReplacementGraphic" ) )
70 0 : pComment = (const MetaCommentAction*)rMtf.GetAction( 1 );
71 :
72 0 : return pComment;
73 : }
74 :
75 : class SvXMLGraphicInputStream:
76 : public cppu::WeakImplHelper1<XInputStream>, private boost::noncopyable
77 : {
78 : private:
79 :
80 : virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
81 : virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
82 : virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
83 : virtual sal_Int32 SAL_CALL available() throw(NotConnectedException, RuntimeException, std::exception) SAL_OVERRIDE;
84 : virtual void SAL_CALL closeInput() throw(NotConnectedException, RuntimeException, std::exception) SAL_OVERRIDE;
85 :
86 : private:
87 :
88 : ::utl::TempFile maTmp;
89 : Reference< XInputStream > mxStmWrapper;
90 :
91 : public:
92 :
93 : SvXMLGraphicInputStream( const OUString& rGraphicId );
94 : virtual ~SvXMLGraphicInputStream();
95 :
96 0 : bool Exists() const { return mxStmWrapper.is(); }
97 : };
98 :
99 0 : SvXMLGraphicInputStream::SvXMLGraphicInputStream( const OUString& rGraphicId )
100 : {
101 0 : GraphicObject aGrfObject( OUStringToOString(rGraphicId, RTL_TEXTENCODING_ASCII_US) );
102 :
103 0 : maTmp.EnableKillingFile();
104 :
105 0 : if( aGrfObject.GetType() != GRAPHIC_NONE )
106 : {
107 0 : SvStream* pStm = ::utl::UcbStreamHelper::CreateStream( maTmp.GetURL(), STREAM_WRITE | STREAM_TRUNC );
108 :
109 0 : if( pStm )
110 : {
111 0 : Graphic aGraphic( (Graphic&) aGrfObject.GetGraphic() );
112 0 : const GfxLink aGfxLink( aGraphic.GetLink() );
113 0 : sal_Bool bRet = sal_False;
114 :
115 0 : if( aGfxLink.GetDataSize() && aGfxLink.GetData() )
116 : {
117 0 : pStm->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
118 0 : bRet = ( pStm->GetError() == 0 );
119 : }
120 : else
121 : {
122 0 : if( aGraphic.GetType() == GRAPHIC_BITMAP )
123 : {
124 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
125 0 : OUString aFormat;
126 :
127 0 : if( aGraphic.IsAnimated() )
128 0 : aFormat = "gif";
129 : else
130 0 : aFormat = "png";
131 :
132 0 : bRet = ( rFilter.ExportGraphic( aGraphic, "", *pStm, rFilter.GetExportFormatNumberForShortName( aFormat ) ) == 0 );
133 : }
134 0 : else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE )
135 : {
136 0 : pStm->SetVersion( SOFFICE_FILEFORMAT_8 );
137 0 : pStm->SetCompressMode( COMPRESSMODE_ZBITMAP );
138 0 : ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( *pStm );
139 0 : bRet = ( pStm->GetError() == 0 );
140 : }
141 : }
142 :
143 0 : if( bRet )
144 : {
145 0 : pStm->Seek( 0 );
146 0 : mxStmWrapper = new ::utl::OInputStreamWrapper( pStm, true );
147 : }
148 : else
149 0 : delete pStm;
150 : }
151 0 : }
152 0 : }
153 :
154 0 : SvXMLGraphicInputStream::~SvXMLGraphicInputStream()
155 : {
156 0 : }
157 :
158 0 : sal_Int32 SAL_CALL SvXMLGraphicInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
159 : throw( NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception )
160 : {
161 0 : if( !mxStmWrapper.is() )
162 0 : throw NotConnectedException();
163 :
164 0 : return mxStmWrapper->readBytes( rData, nBytesToRead );
165 : }
166 :
167 0 : sal_Int32 SAL_CALL SvXMLGraphicInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
168 : throw( NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception )
169 : {
170 0 : if( !mxStmWrapper.is() )
171 0 : throw NotConnectedException() ;
172 :
173 0 : return mxStmWrapper->readSomeBytes( rData, nMaxBytesToRead );
174 : }
175 :
176 0 : void SAL_CALL SvXMLGraphicInputStream::skipBytes( sal_Int32 nBytesToSkip )
177 : throw( NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception )
178 : {
179 0 : if( !mxStmWrapper.is() )
180 0 : throw NotConnectedException() ;
181 :
182 0 : mxStmWrapper->skipBytes( nBytesToSkip );
183 0 : }
184 :
185 0 : sal_Int32 SAL_CALL SvXMLGraphicInputStream::available() throw( NotConnectedException, RuntimeException, std::exception )
186 : {
187 0 : if( !mxStmWrapper.is() )
188 0 : throw NotConnectedException() ;
189 :
190 0 : return mxStmWrapper->available();
191 : }
192 :
193 0 : void SAL_CALL SvXMLGraphicInputStream::closeInput() throw( NotConnectedException, RuntimeException, std::exception )
194 : {
195 0 : if( !mxStmWrapper.is() )
196 0 : throw NotConnectedException() ;
197 :
198 0 : mxStmWrapper->closeInput();
199 0 : }
200 :
201 : class SvXMLGraphicOutputStream:
202 : public cppu::WeakImplHelper1<XOutputStream>, private boost::noncopyable
203 : {
204 : private:
205 :
206 : // XOutputStream
207 : virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& rData ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
208 : virtual void SAL_CALL flush() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
209 : virtual void SAL_CALL closeOutput() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
210 :
211 : private:
212 :
213 : ::utl::TempFile* mpTmp;
214 : SvStream* mpOStm;
215 : Reference< XOutputStream > mxStmWrapper;
216 : GraphicObject maGrfObj;
217 : sal_Bool mbClosed;
218 :
219 : public:
220 :
221 : SvXMLGraphicOutputStream();
222 : virtual ~SvXMLGraphicOutputStream();
223 :
224 0 : bool Exists() const { return mxStmWrapper.is(); }
225 : const GraphicObject& GetGraphicObject();
226 : };
227 :
228 0 : SvXMLGraphicOutputStream::SvXMLGraphicOutputStream() :
229 0 : mpTmp( new ::utl::TempFile ),
230 0 : mbClosed( sal_False )
231 : {
232 0 : mpTmp->EnableKillingFile();
233 :
234 0 : mpOStm = ::utl::UcbStreamHelper::CreateStream( mpTmp->GetURL(), STREAM_WRITE | STREAM_TRUNC );
235 :
236 0 : if( mpOStm )
237 0 : mxStmWrapper = new ::utl::OOutputStreamWrapper( *mpOStm );
238 0 : }
239 :
240 0 : SvXMLGraphicOutputStream::~SvXMLGraphicOutputStream()
241 : {
242 0 : delete mpTmp;
243 0 : delete mpOStm;
244 0 : }
245 :
246 0 : void SAL_CALL SvXMLGraphicOutputStream::writeBytes( const Sequence< sal_Int8 >& rData )
247 : throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception )
248 : {
249 0 : if( !mxStmWrapper.is() )
250 0 : throw NotConnectedException() ;
251 :
252 0 : mxStmWrapper->writeBytes( rData );
253 0 : }
254 :
255 0 : void SAL_CALL SvXMLGraphicOutputStream::flush()
256 : throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception )
257 : {
258 0 : if( !mxStmWrapper.is() )
259 0 : throw NotConnectedException() ;
260 :
261 0 : mxStmWrapper->flush();
262 0 : }
263 :
264 0 : void SAL_CALL SvXMLGraphicOutputStream::closeOutput()
265 : throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception )
266 : {
267 0 : if( !mxStmWrapper.is() )
268 0 : throw NotConnectedException() ;
269 :
270 0 : mxStmWrapper->closeOutput();
271 0 : mxStmWrapper.clear();
272 :
273 0 : mbClosed = sal_True;
274 0 : }
275 :
276 0 : const GraphicObject& SvXMLGraphicOutputStream::GetGraphicObject()
277 : {
278 0 : if( mbClosed && ( maGrfObj.GetType() == GRAPHIC_NONE ) && mpOStm )
279 : {
280 0 : Graphic aGraphic;
281 :
282 0 : mpOStm->Seek( 0 );
283 0 : sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
284 0 : sal_uInt16 pDeterminedFormat = GRFILTER_FORMAT_DONTKNOW;
285 0 : GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *mpOStm ,nFormat,&pDeterminedFormat );
286 :
287 0 : if (pDeterminedFormat == GRFILTER_FORMAT_DONTKNOW)
288 : {
289 : //Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format
290 : //unzip them and try again
291 :
292 : sal_uInt8 sFirstBytes[ 2 ];
293 :
294 0 : mpOStm->Seek( STREAM_SEEK_TO_END );
295 0 : sal_uIntPtr nStreamLen = mpOStm->Tell();
296 0 : mpOStm->Seek( 0 );
297 :
298 0 : if ( !nStreamLen )
299 : {
300 0 : SvLockBytes* pLockBytes = mpOStm->GetLockBytes();
301 0 : if ( pLockBytes )
302 0 : pLockBytes->SetSynchronMode( true );
303 :
304 0 : mpOStm->Seek( STREAM_SEEK_TO_END );
305 0 : nStreamLen = mpOStm->Tell();
306 0 : mpOStm->Seek( 0 );
307 : }
308 0 : if( nStreamLen >= 2 )
309 : {
310 : //read two byte
311 0 : mpOStm->Read( sFirstBytes, 2 );
312 :
313 0 : if( sFirstBytes[0] == 0x1f && sFirstBytes[1] == 0x8b )
314 : {
315 0 : SvMemoryStream* pDest = new SvMemoryStream;
316 0 : ZCodec aZCodec( 0x8000, 0x8000 );
317 0 : aZCodec.BeginCompression(ZCODEC_GZ_LIB);
318 0 : mpOStm->Seek( 0 );
319 0 : aZCodec.Decompress( *mpOStm, *pDest );
320 :
321 0 : if (aZCodec.EndCompression() && pDest )
322 : {
323 0 : pDest->Seek( STREAM_SEEK_TO_END );
324 0 : sal_uIntPtr nStreamLen_ = pDest->Tell();
325 0 : if (nStreamLen_)
326 : {
327 0 : pDest->Seek(0L);
328 0 : GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *pDest ,nFormat,&pDeterminedFormat );
329 : }
330 : }
331 0 : delete pDest;
332 : }
333 : }
334 : }
335 :
336 0 : maGrfObj = aGraphic;
337 0 : if( maGrfObj.GetType() != GRAPHIC_NONE )
338 : {
339 0 : delete mpOStm, mpOStm = NULL;
340 0 : delete mpTmp, mpTmp = NULL;
341 0 : }
342 : }
343 :
344 0 : return maGrfObj;
345 : }
346 :
347 : }
348 :
349 0 : SvXMLGraphicHelper::SvXMLGraphicHelper( SvXMLGraphicHelperMode eCreateMode ) :
350 : ::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver,
351 0 : ::com::sun::star::document::XBinaryStreamResolver >( maMutex )
352 : {
353 0 : Init( NULL, eCreateMode, false );
354 0 : }
355 :
356 0 : SvXMLGraphicHelper::SvXMLGraphicHelper()
357 : : ::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver,
358 : ::com::sun::star::document::XBinaryStreamResolver >( maMutex )
359 : , meCreateMode(GRAPHICHELPER_MODE_READ)
360 0 : , mbDirect(false)
361 : {
362 0 : }
363 :
364 0 : SvXMLGraphicHelper::~SvXMLGraphicHelper()
365 : {
366 0 : }
367 :
368 0 : void SAL_CALL SvXMLGraphicHelper::disposing()
369 : {
370 0 : }
371 :
372 0 : bool SvXMLGraphicHelper::ImplGetStreamNames( const OUString& rURLStr,
373 : OUString& rPictureStorageName,
374 : OUString& rPictureStreamName )
375 : {
376 0 : OUString aURLStr( rURLStr );
377 0 : sal_Bool bRet = sal_False;
378 :
379 0 : if( !aURLStr.isEmpty() )
380 : {
381 0 : aURLStr = aURLStr.getToken( comphelper::string::getTokenCount(aURLStr, ':') - 1, ':' );
382 :
383 0 : const sal_uInt32 nTokenCount = comphelper::string::getTokenCount(aURLStr, '/');
384 :
385 0 : if( 1 == nTokenCount )
386 : {
387 0 : rPictureStorageName = XML_GRAPHICSTORAGE_NAME;
388 0 : rPictureStreamName = aURLStr;
389 : }
390 : else
391 0 : SvXMLEmbeddedObjectHelper::splitObjectURL(aURLStr, rPictureStorageName, rPictureStreamName);
392 :
393 0 : bRet = !rPictureStreamName.isEmpty();
394 : SAL_WARN_IF(!bRet, "svx", "SvXMLGraphicHelper::ImplInsertGraphicURL: invalid scheme: " << rURLStr);
395 : }
396 :
397 0 : return bRet;
398 : }
399 :
400 0 : uno::Reference < embed::XStorage > SvXMLGraphicHelper::ImplGetGraphicStorage( const OUString& rStorageName )
401 : {
402 0 : uno::Reference < embed::XStorage > xRetStorage;
403 0 : if( mxRootStorage.is() )
404 : {
405 : try
406 : {
407 0 : xRetStorage = mxRootStorage->openStorageElement(
408 0 : maCurStorageName = rStorageName,
409 0 : ( GRAPHICHELPER_MODE_WRITE == meCreateMode )
410 : ? embed::ElementModes::READWRITE
411 0 : : embed::ElementModes::READ );
412 : }
413 0 : catch ( uno::Exception& )
414 : {
415 : }
416 : //#i43196# try again to open the storage element - this time readonly
417 0 : if(!xRetStorage.is())
418 : {
419 : try
420 : {
421 0 : xRetStorage = mxRootStorage->openStorageElement( maCurStorageName = rStorageName, embed::ElementModes::READ );
422 : }
423 0 : catch ( uno::Exception& )
424 : {
425 : }
426 : }
427 : }
428 :
429 0 : return xRetStorage;
430 : }
431 :
432 0 : SvxGraphicHelperStream_Impl SvXMLGraphicHelper::ImplGetGraphicStream( const OUString& rPictureStorageName,
433 : const OUString& rPictureStreamName,
434 : bool bTruncate )
435 : {
436 0 : SvxGraphicHelperStream_Impl aRet;
437 0 : aRet.xStorage = ImplGetGraphicStorage( rPictureStorageName );
438 :
439 0 : if( aRet.xStorage.is() )
440 : {
441 0 : sal_Int32 nMode = embed::ElementModes::READ;
442 0 : if ( GRAPHICHELPER_MODE_WRITE == meCreateMode )
443 : {
444 0 : nMode = embed::ElementModes::READWRITE;
445 0 : if ( bTruncate )
446 0 : nMode |= embed::ElementModes::TRUNCATE;
447 : }
448 :
449 0 : aRet.xStream = aRet.xStorage->openStreamElement( rPictureStreamName, nMode );
450 0 : if( aRet.xStream.is() && ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) )
451 : {
452 0 : OUString aPropName( "UseCommonStoragePasswordEncryption" );
453 0 : uno::Reference < beans::XPropertySet > xProps( aRet.xStream, uno::UNO_QUERY );
454 0 : xProps->setPropertyValue( aPropName, uno::makeAny( sal_True) );
455 : }
456 : }
457 :
458 0 : return aRet;
459 : }
460 :
461 0 : OUString SvXMLGraphicHelper::ImplGetGraphicMimeType( const OUString& rFileName ) const
462 : {
463 : struct XMLGraphicMimeTypeMapper
464 : {
465 : const char* pExt;
466 : const char* pMimeType;
467 : };
468 :
469 : static const XMLGraphicMimeTypeMapper aMapper[] =
470 : {
471 : { "gif", "image/gif" },
472 : { "png", "image/png" },
473 : { "jpg", "image/jpeg" },
474 : { "tif", "image/tiff" },
475 : { "svg", "image/svg+xml" }
476 : };
477 :
478 0 : OUString aMimeType;
479 :
480 0 : if( ( rFileName.getLength() >= 4 ) && ( rFileName[ rFileName.getLength() - 4 ] == '.' ) )
481 : {
482 0 : const OString aExt(OUStringToOString(rFileName.copy(rFileName.getLength() - 3),
483 0 : RTL_TEXTENCODING_ASCII_US));
484 :
485 0 : for( long i = 0, nCount = sizeof (aMapper) / sizeof (aMapper[0]); ( i < nCount ) && aMimeType.isEmpty(); i++ )
486 0 : if( strcmp(aExt.getStr(), aMapper[ i ].pExt) == 0 )
487 0 : aMimeType = OUString( aMapper[ i ].pMimeType, strlen( aMapper[ i ].pMimeType ), RTL_TEXTENCODING_ASCII_US );
488 : }
489 :
490 0 : return aMimeType;
491 : }
492 :
493 0 : Graphic SvXMLGraphicHelper::ImplReadGraphic( const OUString& rPictureStorageName,
494 : const OUString& rPictureStreamName )
495 : {
496 0 : Graphic aGraphic;
497 0 : SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, false ) );
498 0 : if( aStream.xStream.is() )
499 : {
500 0 : SvStream* pStream = utl::UcbStreamHelper::CreateStream( aStream.xStream );
501 0 : GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *pStream );
502 0 : delete pStream;
503 : }
504 :
505 0 : return aGraphic;
506 : }
507 :
508 0 : bool SvXMLGraphicHelper::ImplWriteGraphic( const OUString& rPictureStorageName,
509 : const OUString& rPictureStreamName,
510 : const OUString& rGraphicId,
511 : bool bUseGfxLink )
512 : {
513 0 : GraphicObject aGrfObject( OUStringToOString(rGraphicId, RTL_TEXTENCODING_ASCII_US) );
514 0 : sal_Bool bRet = sal_False;
515 :
516 0 : if( aGrfObject.GetType() != GRAPHIC_NONE )
517 : {
518 0 : SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, false ) );
519 0 : if( aStream.xStream.is() )
520 : {
521 0 : Graphic aGraphic( (Graphic&) aGrfObject.GetGraphic() );
522 0 : const GfxLink aGfxLink( aGraphic.GetLink() );
523 0 : const OUString aMimeType( ImplGetGraphicMimeType( rPictureStreamName ) );
524 0 : uno::Any aAny;
525 0 : uno::Reference < beans::XPropertySet > xProps( aStream.xStream, uno::UNO_QUERY );
526 :
527 : // set stream properties (MediaType/Compression)
528 0 : if( !aMimeType.isEmpty() )
529 : {
530 0 : aAny <<= aMimeType;
531 0 : xProps->setPropertyValue( "MediaType", aAny );
532 : }
533 :
534 0 : const sal_Bool bCompressed = aMimeType.isEmpty() || aMimeType == "image/tiff" || aMimeType == "image/svg+xml";
535 0 : aAny <<= bCompressed;
536 0 : xProps->setPropertyValue( "Compressed", aAny );
537 :
538 0 : SvStream* pStream = utl::UcbStreamHelper::CreateStream( aStream.xStream );
539 0 : if( bUseGfxLink && aGfxLink.GetDataSize() && aGfxLink.GetData() )
540 0 : pStream->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
541 : else
542 : {
543 0 : if( aGraphic.GetType() == GRAPHIC_BITMAP )
544 : {
545 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
546 0 : OUString aFormat;
547 :
548 0 : if( aGraphic.IsAnimated() )
549 0 : aFormat = "gif";
550 : else
551 0 : aFormat = "png";
552 :
553 : bRet = ( rFilter.ExportGraphic( aGraphic, "", *pStream,
554 0 : rFilter.GetExportFormatNumberForShortName( aFormat ) ) == 0 );
555 : }
556 0 : else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE )
557 : {
558 0 : pStream->SetVersion( SOFFICE_FILEFORMAT_8 );
559 0 : pStream->SetCompressMode( COMPRESSMODE_ZBITMAP );
560 :
561 : // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
562 0 : GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() );
563 0 : const MetaCommentAction* pComment = ImplCheckForEPS( rMtf );
564 0 : if ( pComment )
565 : {
566 0 : sal_uInt32 nSize = pComment->GetDataSize();
567 0 : const sal_uInt8* pData = pComment->GetData();
568 0 : if ( nSize && pData )
569 0 : pStream->Write( pData, nSize );
570 :
571 0 : const MetaEPSAction* pAct = ( (const MetaEPSAction*)rMtf.FirstAction() );
572 0 : const GfxLink& rLink = pAct->GetLink();
573 :
574 0 : pStream->Write( rLink.GetData(), rLink.GetDataSize() );
575 : }
576 : else
577 0 : rMtf.Write( *pStream );
578 :
579 0 : bRet = ( pStream->GetError() == 0 );
580 : }
581 : }
582 : uno::Reference < embed::XTransactedObject > xStorage(
583 0 : aStream.xStorage, uno::UNO_QUERY);
584 0 : delete pStream;
585 0 : aStream.xStream->getOutputStream()->closeOutput();
586 0 : if( xStorage.is() )
587 0 : xStorage->commit();
588 0 : }
589 : }
590 :
591 0 : return bRet;
592 : }
593 :
594 0 : void SvXMLGraphicHelper::ImplInsertGraphicURL( const OUString& rURLStr, sal_uInt32 nInsertPos, OUString& rRequestedFileName )
595 : {
596 0 : OUString aURLString( rURLStr );
597 0 : OUString aPictureStorageName, aPictureStreamName;
598 0 : if( ( maURLSet.find( aURLString ) != maURLSet.end() ) )
599 : {
600 0 : for (URLPairVector::const_iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() ); aIter != aEnd ; ++aIter)
601 : {
602 0 : if( aURLString == (*aIter).first )
603 : {
604 0 : maGrfURLs[ nInsertPos ].second = (*aIter).second;
605 0 : break;
606 : }
607 : }
608 : }
609 0 : else if( ImplGetStreamNames( aURLString, aPictureStorageName, aPictureStreamName ) )
610 : {
611 0 : URLPair& rURLPair = maGrfURLs[ nInsertPos ];
612 :
613 0 : if( GRAPHICHELPER_MODE_READ == meCreateMode )
614 : {
615 0 : const GraphicObject aObj( ImplReadGraphic( aPictureStorageName, aPictureStreamName ) );
616 :
617 0 : if( aObj.GetType() != GRAPHIC_NONE )
618 : {
619 0 : maGrfObjs.push_back( aObj );
620 0 : OUString aBaseURL( XML_GRAPHICOBJECT_URL_BASE );
621 :
622 0 : rURLPair.second = aBaseURL;
623 0 : rURLPair.second += OStringToOUString(aObj.GetUniqueID(),
624 0 : RTL_TEXTENCODING_ASCII_US);
625 : }
626 : else
627 0 : rURLPair.second = "";
628 : }
629 : else
630 : {
631 0 : const OUString aGraphicObjectId( aPictureStreamName );
632 0 : const OString aAsciiObjectID(OUStringToOString(aGraphicObjectId, RTL_TEXTENCODING_ASCII_US));
633 0 : const GraphicObject aGrfObject( aAsciiObjectID );
634 0 : if( aGrfObject.GetType() != GRAPHIC_NONE )
635 : {
636 0 : OUString aStreamName( aGraphicObjectId );
637 0 : Graphic aGraphic( (Graphic&) aGrfObject.GetGraphic() );
638 0 : const GfxLink aGfxLink( aGraphic.GetLink() );
639 0 : OUString aExtension;
640 0 : bool bUseGfxLink( true );
641 :
642 0 : if( aGfxLink.GetDataSize() )
643 : {
644 0 : switch( aGfxLink.GetType() )
645 : {
646 0 : case( GFX_LINK_TYPE_EPS_BUFFER ): aExtension = ".eps"; break;
647 0 : case( GFX_LINK_TYPE_NATIVE_GIF ): aExtension = ".gif"; break;
648 : // #i15508# added BMP type for better exports (checked, works)
649 0 : case( GFX_LINK_TYPE_NATIVE_BMP ): aExtension = ".bmp"; break;
650 0 : case( GFX_LINK_TYPE_NATIVE_JPG ): aExtension = ".jpg"; break;
651 0 : case( GFX_LINK_TYPE_NATIVE_PNG ): aExtension = ".png"; break;
652 0 : case( GFX_LINK_TYPE_NATIVE_TIF ): aExtension = ".tif"; break;
653 0 : case( GFX_LINK_TYPE_NATIVE_WMF ): aExtension = ".wmf"; break;
654 0 : case( GFX_LINK_TYPE_NATIVE_MET ): aExtension = ".met"; break;
655 0 : case( GFX_LINK_TYPE_NATIVE_PCT ): aExtension = ".pct"; break;
656 : case( GFX_LINK_TYPE_NATIVE_SVG ):
657 : // backward-compat kludge: since no released OOo
658 : // version to date can handle svg properly, wrap it up
659 : // into an svm. slight catch22 here, since strict ODF
660 : // conformance _recommends_ svg - then again, most old
661 : // ODF consumers are believed to be OOo
662 0 : if( SvtSaveOptions().GetODFDefaultVersion() <= SvtSaveOptions::ODFVER_012 )
663 : {
664 0 : bUseGfxLink = false;
665 0 : aExtension = ".svm";
666 : }
667 : else
668 0 : aExtension = ".svg";
669 0 : break;
670 :
671 : default:
672 0 : aExtension = ".grf";
673 0 : break;
674 : }
675 : }
676 : else
677 : {
678 0 : if( aGrfObject.GetType() == GRAPHIC_BITMAP )
679 : {
680 0 : if( aGrfObject.IsAnimated() )
681 0 : aExtension = ".gif";
682 : else
683 0 : aExtension = ".png";
684 : }
685 0 : else if( aGrfObject.GetType() == GRAPHIC_GDIMETAFILE )
686 : {
687 : // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
688 0 : GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() );
689 0 : if ( ImplCheckForEPS( rMtf ) )
690 0 : aExtension = ".eps";
691 : else
692 0 : aExtension = ".svm";
693 : }
694 : }
695 :
696 0 : OUString aURLEntry;
697 0 : const OUString sPictures( "Pictures/" );
698 :
699 0 : if ( !rRequestedFileName.isEmpty() )
700 : {
701 0 : aURLEntry = sPictures;
702 0 : aURLEntry += rRequestedFileName;
703 0 : aURLEntry += aExtension;
704 :
705 0 : URLPairVector::const_iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() );
706 0 : for ( ; aIter != aEnd; ++aIter )
707 : {
708 0 : if( aURLEntry == (*aIter).second )
709 0 : break;
710 : }
711 0 : if ( aIter == aEnd )
712 0 : aStreamName = rRequestedFileName;
713 : }
714 :
715 0 : aStreamName += aExtension;
716 :
717 0 : if( mbDirect && !aStreamName.isEmpty() )
718 0 : ImplWriteGraphic( aPictureStorageName, aStreamName, aGraphicObjectId, bUseGfxLink );
719 :
720 0 : rURLPair.second = sPictures;
721 0 : rURLPair.second += aStreamName;
722 0 : }
723 : #if OSL_DEBUG_LEVEL > 0
724 : else
725 : {
726 : OStringBuffer sMessage("graphic object with ID '");
727 : sMessage.append(aAsciiObjectID).
728 : append("' has an unknown type");
729 : OSL_ENSURE( false, sMessage.getStr() );
730 : }
731 : #endif
732 : }
733 :
734 0 : maURLSet.insert( aURLString );
735 0 : }
736 0 : }
737 :
738 0 : void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage,
739 : SvXMLGraphicHelperMode eCreateMode,
740 : bool bDirect )
741 : {
742 0 : mxRootStorage = rXMLStorage;
743 0 : meCreateMode = eCreateMode;
744 0 : mbDirect = ( ( GRAPHICHELPER_MODE_READ == meCreateMode ) ? bDirect : sal_True );
745 0 : }
746 :
747 0 : SvXMLGraphicHelper* SvXMLGraphicHelper::Create( const uno::Reference < embed::XStorage >& rXMLStorage,
748 : SvXMLGraphicHelperMode eCreateMode,
749 : bool bDirect )
750 : {
751 0 : SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper;
752 :
753 0 : pThis->acquire();
754 0 : pThis->Init( rXMLStorage, eCreateMode, bDirect );
755 :
756 0 : return pThis;
757 : }
758 :
759 0 : SvXMLGraphicHelper* SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode eCreateMode )
760 : {
761 0 : SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper;
762 :
763 0 : pThis->acquire();
764 0 : pThis->Init( NULL, eCreateMode, false );
765 :
766 0 : return pThis;
767 : }
768 :
769 0 : void SvXMLGraphicHelper::Destroy( SvXMLGraphicHelper* pSvXMLGraphicHelper )
770 : {
771 0 : if( pSvXMLGraphicHelper )
772 : {
773 0 : pSvXMLGraphicHelper->dispose();
774 0 : pSvXMLGraphicHelper->release();
775 : }
776 0 : }
777 :
778 : // XGraphicObjectResolver
779 0 : OUString SAL_CALL SvXMLGraphicHelper::resolveGraphicObjectURL( const OUString& rURL )
780 : throw(uno::RuntimeException, std::exception)
781 : {
782 0 : ::osl::MutexGuard aGuard( maMutex );
783 0 : const sal_Int32 nIndex = maGrfURLs.size();
784 :
785 0 : OUString aURL( rURL );
786 0 : OUString aUserData;
787 0 : OUString aRequestedFileName;
788 :
789 0 : sal_Int32 nUser = rURL.indexOf( '?', 0 );
790 0 : if ( nUser >= 0 )
791 : {
792 0 : aURL = rURL.copy( 0, nUser );
793 0 : nUser++;
794 0 : aUserData = rURL.copy( nUser, rURL.getLength() - nUser );
795 : }
796 0 : if ( !aUserData.isEmpty() )
797 : {
798 0 : sal_Int32 nIndex2 = 0;
799 0 : do
800 : {
801 0 : OUString aToken = aUserData.getToken( 0, ';', nIndex2 );
802 0 : sal_Int32 n = aToken.indexOf( '=' );
803 0 : if ( ( n > 0 ) && ( ( n + 1 ) < aToken.getLength() ) )
804 : {
805 0 : OUString aParam( aToken.copy( 0, n ) );
806 0 : OUString aValue( aToken.copy( n + 1, aToken.getLength() - ( n + 1 ) ) );
807 :
808 0 : const OUString sRequestedName( "requestedName" );
809 0 : if ( aParam.match( sRequestedName ) )
810 0 : aRequestedFileName = aValue;
811 0 : }
812 : }
813 0 : while ( nIndex2 >= 0 );
814 : }
815 :
816 0 : maGrfURLs.push_back( ::std::make_pair( aURL, OUString() ) );
817 0 : ImplInsertGraphicURL( aURL, nIndex, aRequestedFileName );
818 :
819 0 : return maGrfURLs[ nIndex ].second;
820 : }
821 :
822 : // XBinaryStreamResolver
823 0 : Reference< XInputStream > SAL_CALL SvXMLGraphicHelper::getInputStream( const OUString& rURL )
824 : throw( RuntimeException, std::exception )
825 : {
826 0 : Reference< XInputStream > xRet;
827 0 : OUString aPictureStorageName, aGraphicId;
828 :
829 :
830 0 : if( ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) &&
831 0 : ImplGetStreamNames( rURL, aPictureStorageName, aGraphicId ) )
832 : {
833 0 : SvXMLGraphicInputStream* pInputStream = new SvXMLGraphicInputStream( aGraphicId );
834 :
835 0 : if( pInputStream->Exists() )
836 0 : xRet = pInputStream;
837 : else
838 0 : delete pInputStream;
839 : }
840 :
841 0 : return xRet;
842 : }
843 :
844 0 : Reference< XOutputStream > SAL_CALL SvXMLGraphicHelper::createOutputStream()
845 : throw( RuntimeException, std::exception )
846 : {
847 0 : Reference< XOutputStream > xRet;
848 :
849 0 : if( GRAPHICHELPER_MODE_READ == meCreateMode )
850 : {
851 0 : SvXMLGraphicOutputStream* pOutputStream = new SvXMLGraphicOutputStream;
852 :
853 0 : if( pOutputStream->Exists() )
854 0 : maGrfStms.push_back( xRet = pOutputStream );
855 : else
856 0 : delete pOutputStream;
857 : }
858 :
859 0 : return xRet;
860 : }
861 :
862 0 : OUString SAL_CALL SvXMLGraphicHelper::resolveOutputStream( const Reference< XOutputStream >& rxBinaryStream )
863 : throw( RuntimeException, std::exception )
864 : {
865 0 : OUString aRet;
866 :
867 0 : if( ( GRAPHICHELPER_MODE_READ == meCreateMode ) && rxBinaryStream.is() )
868 : {
869 0 : if( ::std::find( maGrfStms.begin(), maGrfStms.end(), rxBinaryStream ) != maGrfStms.end() )
870 : {
871 0 : SvXMLGraphicOutputStream* pOStm = static_cast< SvXMLGraphicOutputStream* >( rxBinaryStream.get() );
872 :
873 0 : if( pOStm )
874 : {
875 0 : const GraphicObject& rGrfObj = pOStm->GetGraphicObject();
876 : const OUString aId(OStringToOUString(
877 0 : rGrfObj.GetUniqueID(), RTL_TEXTENCODING_ASCII_US));
878 :
879 0 : if( !aId.isEmpty() )
880 : {
881 0 : aRet = XML_GRAPHICOBJECT_URL_BASE;
882 0 : aRet += aId;
883 0 : }
884 : }
885 : }
886 : }
887 :
888 0 : return aRet;
889 : }
890 :
891 : // for instantiation via service manager
892 : namespace {
893 :
894 : namespace impl
895 : {
896 : typedef ::cppu::WeakComponentImplHelper4<
897 : lang::XInitialization,
898 : document::XGraphicObjectResolver,
899 : document::XBinaryStreamResolver,
900 : lang::XServiceInfo >
901 : SvXMLGraphicImportExportHelper_Base;
902 0 : class MutexContainer
903 : {
904 : public:
905 : virtual ~MutexContainer();
906 :
907 : protected:
908 : mutable ::osl::Mutex m_aMutex;
909 : };
910 0 : MutexContainer::~MutexContainer()
911 0 : {}
912 : } // namespace impl
913 :
914 0 : class SvXMLGraphicImportExportHelper :
915 : public impl::MutexContainer,
916 : public impl::SvXMLGraphicImportExportHelper_Base
917 : {
918 : public:
919 : SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode );
920 :
921 : protected:
922 : // is called from WeakComponentImplHelper when XComponent::dispose() was
923 : // called from outside
924 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
925 :
926 : // ____ XInitialization ____
927 : // one argument is allowed, which is the XStorage
928 : virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
929 : throw (Exception,
930 : RuntimeException, std::exception) SAL_OVERRIDE;
931 :
932 : // ____ XGraphicObjectResolver ____
933 : virtual OUString SAL_CALL resolveGraphicObjectURL( const OUString& aURL )
934 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
935 :
936 : // ____ XBinaryStreamResolver ____
937 : virtual Reference< io::XInputStream > SAL_CALL getInputStream( const OUString& aURL )
938 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
939 : virtual Reference< io::XOutputStream > SAL_CALL createOutputStream()
940 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
941 : virtual OUString SAL_CALL resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
942 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
943 :
944 : // ____ XServiceInfo ____
945 : virtual OUString SAL_CALL getImplementationName()
946 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
947 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName )
948 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
949 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
950 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
951 :
952 : private:
953 : SvXMLGraphicHelperMode m_eGraphicHelperMode;
954 : Reference< XGraphicObjectResolver > m_xGraphicObjectResolver;
955 : Reference< XBinaryStreamResolver > m_xBinaryStreamResolver;
956 : };
957 :
958 0 : SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ) :
959 : impl::SvXMLGraphicImportExportHelper_Base( m_aMutex ),
960 0 : m_eGraphicHelperMode( eMode )
961 0 : {}
962 :
963 0 : void SAL_CALL SvXMLGraphicImportExportHelper::disposing()
964 : {
965 0 : Reference< XComponent > xComp( m_xGraphicObjectResolver, UNO_QUERY );
966 : OSL_ASSERT( xComp.is());
967 0 : if( xComp.is())
968 0 : xComp->dispose();
969 : // m_xBinaryStreamResolver is a reference to the same object => don't call
970 : // dispose() again
971 0 : }
972 :
973 : // ____ XInitialization ____
974 0 : void SAL_CALL SvXMLGraphicImportExportHelper::initialize(
975 : const Sequence< Any >& aArguments )
976 : throw (Exception, RuntimeException, std::exception)
977 : {
978 0 : Reference< embed::XStorage > xStorage;
979 0 : if( aArguments.getLength() > 0 )
980 0 : aArguments[0] >>= xStorage;
981 :
982 0 : SvXMLGraphicHelper * pHelper( SvXMLGraphicHelper::Create( xStorage, m_eGraphicHelperMode ));
983 0 : m_xGraphicObjectResolver.set( pHelper );
984 0 : m_xBinaryStreamResolver.set( pHelper );
985 : // SvXMLGraphicHelper::Create calls acquire. Since we have two references
986 : // now it is safe (and necessary) to undo this acquire
987 0 : pHelper->release();
988 0 : }
989 :
990 : // ____ XGraphicObjectResolver ____
991 0 : OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const OUString& aURL )
992 : throw (uno::RuntimeException, std::exception)
993 : {
994 0 : return m_xGraphicObjectResolver->resolveGraphicObjectURL( aURL );
995 : }
996 :
997 :
998 : // ____ XBinaryStreamResolver ____
999 0 : Reference< io::XInputStream > SAL_CALL SvXMLGraphicImportExportHelper::getInputStream( const OUString& aURL )
1000 : throw (uno::RuntimeException, std::exception)
1001 : {
1002 0 : return m_xBinaryStreamResolver->getInputStream( aURL );
1003 : }
1004 0 : Reference< io::XOutputStream > SAL_CALL SvXMLGraphicImportExportHelper::createOutputStream()
1005 : throw (uno::RuntimeException, std::exception)
1006 : {
1007 0 : return m_xBinaryStreamResolver->createOutputStream();
1008 : }
1009 0 : OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
1010 : throw (uno::RuntimeException, std::exception)
1011 : {
1012 0 : return m_xBinaryStreamResolver->resolveOutputStream( aBinaryStream );
1013 : }
1014 :
1015 : // ____ XServiceInfo ____
1016 0 : OUString SAL_CALL SvXMLGraphicImportExportHelper::getImplementationName()
1017 : throw (uno::RuntimeException, std::exception)
1018 : {
1019 0 : if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ )
1020 0 : return OUString("com.sun.star.comp.Svx.GraphicImportHelper");
1021 0 : return OUString("com.sun.star.comp.Svx.GraphicExportHelper");
1022 : }
1023 :
1024 0 : sal_Bool SAL_CALL SvXMLGraphicImportExportHelper::supportsService( const OUString& ServiceName )
1025 : throw (uno::RuntimeException, std::exception)
1026 : {
1027 0 : return cppu::supportsService(this, ServiceName);
1028 : }
1029 :
1030 0 : Sequence< OUString > SAL_CALL SvXMLGraphicImportExportHelper::getSupportedServiceNames()
1031 : throw (uno::RuntimeException, std::exception)
1032 : {
1033 : // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service
1034 0 : Sequence< OUString > aSupportedServiceNames( 2 );
1035 0 : aSupportedServiceNames[0] = "com.sun.star.document.GraphicObjectResolver";
1036 0 : aSupportedServiceNames[1] = "com.sun.star.document.BinaryStreamResolver";
1037 0 : return aSupportedServiceNames;
1038 : }
1039 :
1040 : }
1041 :
1042 : /** Create this with createInstanceWithArguments. service name
1043 : "com.sun.star.comp.Svx.GraphicImportHelper", one argument which is the
1044 : XStorage. Without arguments no helper class is created. With an empty
1045 : argument the helper class is created and initialized like in the CTOR to
1046 : SvXMLGraphicHelper that only gets the create mode.
1047 :
1048 : You should call dispose after you no longer need this component.
1049 :
1050 : uses eCreateMode == GRAPHICHELPER_MODE_READ, bDirect == sal_True in
1051 : SvXMLGraphicHelper
1052 : */
1053 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1054 0 : com_sun_star_comp_Svx_GraphicImportHelper_get_implementation(
1055 : css::uno::XComponentContext *,
1056 : css::uno::Sequence<css::uno::Any> const &)
1057 : {
1058 0 : return cppu::acquire(new SvXMLGraphicImportExportHelper(GRAPHICHELPER_MODE_READ));
1059 : }
1060 :
1061 : /** Create this with createInstanceWithArguments. service name
1062 : "com.sun.star.comp.Svx.GraphicExportHelper", one argument which is the
1063 : XStorage. Without arguments no helper class is created. With an empty
1064 : argument the helper class is created and initialized like in the CTOR to
1065 : SvXMLGraphicHelper that only gets the create mode
1066 :
1067 : To write the Pictures stream, you have to call dispose at this component.
1068 : Make sure you call dipose before you commit the parent storage.
1069 :
1070 : uses eCreateMode == GRAPHICHELPER_MODE_WRITE, bDirect == sal_True in
1071 : SvXMLGraphicHelper
1072 : */
1073 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1074 0 : com_sun_star_comp_Svx_GraphicExportHelper_get_implementation(
1075 : css::uno::XComponentContext *,
1076 : css::uno::Sequence<css::uno::Any> const &)
1077 : {
1078 0 : return cppu::acquire(new SvXMLGraphicImportExportHelper(GRAPHICHELPER_MODE_WRITE));
1079 : }
1080 :
1081 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|