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