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 ); 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 ); 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 723 // #15508# added BMP type for better exports (checked, works) 724 case( GFX_LINK_TYPE_NATIVE_BMP ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".bmp" ) ); break; 725 726 case( GFX_LINK_TYPE_NATIVE_JPG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".jpg" ) ); break; 727 case( GFX_LINK_TYPE_NATIVE_PNG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ); break; 728 case( GFX_LINK_TYPE_NATIVE_TIF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".tif" ) ); break; 729 case( GFX_LINK_TYPE_NATIVE_WMF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".wmf" ) ); break; 730 case( GFX_LINK_TYPE_NATIVE_MET ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".met" ) ); break; 731 case( GFX_LINK_TYPE_NATIVE_PCT ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".pct" ) ); break; 732 case( GFX_LINK_TYPE_NATIVE_SVG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".svg" ) ); break; 733 734 default: 735 aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".grf" ) ); 736 break; 737 } 738 } 739 else 740 { 741 if( aGrfObject.GetType() == GRAPHIC_BITMAP ) 742 { 743 if( aGrfObject.IsAnimated() ) 744 aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) ); 745 else 746 aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ); 747 } 748 else if( aGrfObject.GetType() == GRAPHIC_GDIMETAFILE ) 749 { 750 // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm 751 GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() ); 752 if ( ImplCheckForEPS( rMtf ) ) 753 aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) ); 754 else 755 aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".svm" ) ); 756 } 757 } 758 759 rtl::OUString aURLEntry; 760 const String sPictures( RTL_CONSTASCII_USTRINGPARAM( "Pictures/" ) ); 761 762 if ( rRequestedFileName.getLength() ) 763 { 764 aURLEntry = sPictures; 765 aURLEntry += rRequestedFileName; 766 aURLEntry += aExtension; 767 768 URLPairVector::iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() ); 769 while( aIter != aEnd ) 770 { 771 if( aURLEntry == (*aIter).second ) 772 break; 773 aIter++; 774 } 775 if ( aIter == aEnd ) 776 aStreamName = rRequestedFileName; 777 } 778 779 aStreamName += aExtension; 780 781 if( mbDirect && aStreamName.Len() ) 782 ImplWriteGraphic( aPictureStorageName, aStreamName, aGraphicObjectId ); 783 784 rURLPair.second = sPictures; 785 rURLPair.second += aStreamName; 786 } 787 #if OSL_DEBUG_LEVEL > 0 788 else 789 { 790 ByteString sMessage = "graphic object with ID '"; 791 sMessage += aAsciiObjectID; 792 sMessage += "' has an unknown type"; 793 OSL_ENSURE( false, sMessage.GetBuffer() ); 794 } 795 #endif 796 } 797 798 maURLSet.insert( aURLString ); 799 } 800 } 801 802 // ----------------------------------------------------------------------------- 803 804 void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage, 805 SvXMLGraphicHelperMode eCreateMode, 806 sal_Bool bDirect ) 807 { 808 mxRootStorage = rXMLStorage; 809 meCreateMode = eCreateMode; 810 mbDirect = ( ( GRAPHICHELPER_MODE_READ == meCreateMode ) ? bDirect : sal_True ); 811 } 812 813 // ----------------------------------------------------------------------------- 814 815 SvXMLGraphicHelper* SvXMLGraphicHelper::Create( const uno::Reference < embed::XStorage >& rXMLStorage, 816 SvXMLGraphicHelperMode eCreateMode, 817 sal_Bool bDirect ) 818 { 819 SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper; 820 821 pThis->acquire(); 822 pThis->Init( rXMLStorage, eCreateMode, bDirect ); 823 824 return pThis; 825 } 826 827 // ----------------------------------------------------------------------------- 828 829 SvXMLGraphicHelper* SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode eCreateMode ) 830 { 831 SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper; 832 833 pThis->acquire(); 834 pThis->Init( NULL, eCreateMode, sal_False ); 835 836 return pThis; 837 } 838 839 // ----------------------------------------------------------------------------- 840 841 void SvXMLGraphicHelper::Destroy( SvXMLGraphicHelper* pSvXMLGraphicHelper ) 842 { 843 if( pSvXMLGraphicHelper ) 844 { 845 pSvXMLGraphicHelper->dispose(); 846 pSvXMLGraphicHelper->release(); 847 } 848 } 849 850 // ----------------------------------------------------------------------------- 851 852 // XGraphicObjectResolver 853 ::rtl::OUString SAL_CALL SvXMLGraphicHelper::resolveGraphicObjectURL( const ::rtl::OUString& rURL ) 854 throw(uno::RuntimeException) 855 { 856 ::osl::MutexGuard aGuard( maMutex ); 857 const sal_Int32 nIndex = maGrfURLs.size(); 858 859 rtl::OUString aURL( rURL ); 860 rtl::OUString aUserData; 861 rtl::OUString aRequestedFileName; 862 863 sal_Int32 nUser = rURL.indexOf( '?', 0 ); 864 if ( nUser >= 0 ) 865 { 866 aURL = rtl::OUString( rURL.copy( 0, nUser ) ); 867 nUser++; 868 aUserData = rURL.copy( nUser, rURL.getLength() - nUser ); 869 } 870 if ( aUserData.getLength() ) 871 { 872 sal_Int32 nIndex2 = 0; 873 do 874 { 875 rtl::OUString aToken = aUserData.getToken( 0, ';', nIndex2 ); 876 sal_Int32 n = aToken.indexOf( '=' ); 877 if ( ( n > 0 ) && ( ( n + 1 ) < aToken.getLength() ) ) 878 { 879 rtl::OUString aParam( aToken.copy( 0, n ) ); 880 rtl::OUString aValue( aToken.copy( n + 1, aToken.getLength() - ( n + 1 ) ) ); 881 882 const rtl::OUString sRequestedName( RTL_CONSTASCII_USTRINGPARAM("requestedName") ); 883 if ( aParam.match( sRequestedName ) ) 884 aRequestedFileName = aValue; 885 } 886 } 887 while ( nIndex2 >= 0 ); 888 } 889 890 maGrfURLs.push_back( ::std::make_pair( aURL, ::rtl::OUString() ) ); 891 ImplInsertGraphicURL( aURL, nIndex, aRequestedFileName ); 892 893 return maGrfURLs[ nIndex ].second; 894 } 895 896 // ----------------------------------------------------------------------------- 897 898 // XBinaryStreamResolver 899 Reference< XInputStream > SAL_CALL SvXMLGraphicHelper::getInputStream( const ::rtl::OUString& rURL ) 900 throw( RuntimeException ) 901 { 902 Reference< XInputStream > xRet; 903 ::rtl::OUString aPictureStorageName, aGraphicId; 904 905 906 if( ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) && 907 ImplGetStreamNames( rURL, aPictureStorageName, aGraphicId ) ) 908 { 909 SvXMLGraphicInputStream* pInputStream = new SvXMLGraphicInputStream( aGraphicId ); 910 911 if( pInputStream->Exists() ) 912 xRet = pInputStream; 913 else 914 delete pInputStream; 915 } 916 917 return xRet; 918 } 919 920 // ----------------------------------------------------------------------------- 921 922 Reference< XOutputStream > SAL_CALL SvXMLGraphicHelper::createOutputStream() 923 throw( RuntimeException ) 924 { 925 Reference< XOutputStream > xRet; 926 927 if( GRAPHICHELPER_MODE_READ == meCreateMode ) 928 { 929 SvXMLGraphicOutputStream* pOutputStream = new SvXMLGraphicOutputStream; 930 931 if( pOutputStream->Exists() ) 932 maGrfStms.push_back( xRet = pOutputStream ); 933 else 934 delete pOutputStream; 935 } 936 937 return xRet; 938 } 939 940 // ----------------------------------------------------------------------------- 941 942 ::rtl::OUString SAL_CALL SvXMLGraphicHelper::resolveOutputStream( const Reference< XOutputStream >& rxBinaryStream ) 943 throw( RuntimeException ) 944 { 945 ::rtl::OUString aRet; 946 947 if( ( GRAPHICHELPER_MODE_READ == meCreateMode ) && rxBinaryStream.is() ) 948 { 949 if( ::std::find( maGrfStms.begin(), maGrfStms.end(), rxBinaryStream ) != maGrfStms.end() ) 950 { 951 SvXMLGraphicOutputStream* pOStm = static_cast< SvXMLGraphicOutputStream* >( rxBinaryStream.get() ); 952 953 if( pOStm ) 954 { 955 const GraphicObject& rGrfObj = pOStm->GetGraphicObject(); 956 const ::rtl::OUString aId( ::rtl::OUString::createFromAscii( rGrfObj.GetUniqueID().GetBuffer() ) ); 957 958 if( aId.getLength() ) 959 { 960 aRet = ::rtl::OUString::createFromAscii( XML_GRAPHICOBJECT_URL_BASE ); 961 aRet += aId; 962 } 963 } 964 } 965 } 966 967 return aRet; 968 } 969 970 971 // -------------------------------------------------------------------------------- 972 973 // for instantiation via service manager 974 namespace svx 975 { 976 977 namespace impl 978 { 979 typedef ::cppu::WeakComponentImplHelper4< 980 lang::XInitialization, 981 document::XGraphicObjectResolver, 982 document::XBinaryStreamResolver, 983 lang::XServiceInfo > 984 SvXMLGraphicImportExportHelper_Base; 985 class MutexContainer 986 { 987 public: 988 virtual ~MutexContainer(); 989 990 protected: 991 mutable ::osl::Mutex m_aMutex; 992 }; 993 MutexContainer::~MutexContainer() 994 {} 995 } // namespace impl 996 997 class SvXMLGraphicImportExportHelper : 998 public impl::MutexContainer, 999 public impl::SvXMLGraphicImportExportHelper_Base 1000 { 1001 public: 1002 SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ); 1003 1004 protected: 1005 // is called from WeakComponentImplHelper when XComponent::dispose() was 1006 // called from outside 1007 virtual void SAL_CALL disposing(); 1008 1009 // ____ XInitialization ____ 1010 // one argument is allowed, which is the XStorage 1011 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) 1012 throw (Exception, 1013 RuntimeException); 1014 1015 // ____ XGraphicObjectResolver ____ 1016 virtual ::rtl::OUString SAL_CALL resolveGraphicObjectURL( const ::rtl::OUString& aURL ) 1017 throw (RuntimeException); 1018 1019 // ____ XBinaryStreamResolver ____ 1020 virtual Reference< io::XInputStream > SAL_CALL getInputStream( const ::rtl::OUString& aURL ) 1021 throw (RuntimeException); 1022 virtual Reference< io::XOutputStream > SAL_CALL createOutputStream() 1023 throw (RuntimeException); 1024 virtual ::rtl::OUString SAL_CALL resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream ) 1025 throw (RuntimeException); 1026 1027 // ____ XServiceInfo ____ 1028 virtual ::rtl::OUString SAL_CALL getImplementationName() 1029 throw (RuntimeException); 1030 virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) 1031 throw (RuntimeException); 1032 virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() 1033 throw (RuntimeException); 1034 1035 private: 1036 SvXMLGraphicHelperMode m_eGraphicHelperMode; 1037 Reference< XGraphicObjectResolver > m_xGraphicObjectResolver; 1038 Reference< XBinaryStreamResolver > m_xBinaryStreamResolver; 1039 }; 1040 1041 SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ) : 1042 impl::SvXMLGraphicImportExportHelper_Base( m_aMutex ), 1043 m_eGraphicHelperMode( eMode ) 1044 {} 1045 1046 void SAL_CALL SvXMLGraphicImportExportHelper::disposing() 1047 { 1048 Reference< XComponent > xComp( m_xGraphicObjectResolver, UNO_QUERY ); 1049 OSL_ASSERT( xComp.is()); 1050 if( xComp.is()) 1051 xComp->dispose(); 1052 // m_xBinaryStreamResolver is a reference to the same object => don't call 1053 // dispose() again 1054 } 1055 1056 // ____ XInitialization ____ 1057 void SAL_CALL SvXMLGraphicImportExportHelper::initialize( 1058 const Sequence< Any >& aArguments ) 1059 throw (Exception, RuntimeException) 1060 { 1061 Reference< embed::XStorage > xStorage; 1062 if( aArguments.getLength() > 0 ) 1063 aArguments[0] >>= xStorage; 1064 1065 SvXMLGraphicHelper * pHelper( SvXMLGraphicHelper::Create( xStorage, m_eGraphicHelperMode )); 1066 m_xGraphicObjectResolver.set( pHelper ); 1067 m_xBinaryStreamResolver.set( pHelper ); 1068 // SvXMLGraphicHelper::Create calls acquire. Since we have two references 1069 // now it is safe (and necessary) to undo this acquire 1070 pHelper->release(); 1071 } 1072 1073 // ____ XGraphicObjectResolver ____ 1074 ::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const ::rtl::OUString& aURL ) 1075 throw (uno::RuntimeException) 1076 { 1077 return m_xGraphicObjectResolver->resolveGraphicObjectURL( aURL ); 1078 } 1079 1080 1081 // ____ XBinaryStreamResolver ____ 1082 Reference< io::XInputStream > SAL_CALL SvXMLGraphicImportExportHelper::getInputStream( const ::rtl::OUString& aURL ) 1083 throw (uno::RuntimeException) 1084 { 1085 return m_xBinaryStreamResolver->getInputStream( aURL ); 1086 } 1087 Reference< io::XOutputStream > SAL_CALL SvXMLGraphicImportExportHelper::createOutputStream() 1088 throw (uno::RuntimeException) 1089 { 1090 return m_xBinaryStreamResolver->createOutputStream(); 1091 } 1092 ::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream ) 1093 throw (uno::RuntimeException) 1094 { 1095 return m_xBinaryStreamResolver->resolveOutputStream( aBinaryStream ); 1096 } 1097 1098 // ____ XServiceInfo ____ 1099 ::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::getImplementationName() 1100 throw (uno::RuntimeException) 1101 { 1102 if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ ) 1103 return SvXMLGraphicImportHelper_getImplementationName(); 1104 return SvXMLGraphicExportHelper_getImplementationName(); 1105 } 1106 ::sal_Bool SAL_CALL SvXMLGraphicImportExportHelper::supportsService( const ::rtl::OUString& ServiceName ) 1107 throw (uno::RuntimeException) 1108 { 1109 Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames()); 1110 const ::rtl::OUString * pBegin = aServiceNames.getConstArray(); 1111 const ::rtl::OUString * pEnd = pBegin + aServiceNames.getLength(); 1112 return (::std::find( pBegin, pEnd, ServiceName ) != pEnd); 1113 } 1114 Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicImportExportHelper::getSupportedServiceNames() 1115 throw (uno::RuntimeException) 1116 { 1117 if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ ) 1118 return SvXMLGraphicImportHelper_getSupportedServiceNames(); 1119 return SvXMLGraphicExportHelper_getSupportedServiceNames(); 1120 } 1121 1122 // import 1123 Reference< XInterface > SAL_CALL SvXMLGraphicImportHelper_createInstance(const Reference< XMultiServiceFactory > & /* rSMgr */ ) 1124 throw( Exception ) 1125 { 1126 return static_cast< XWeak* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_READ )); 1127 } 1128 ::rtl::OUString SAL_CALL SvXMLGraphicImportHelper_getImplementationName() 1129 throw() 1130 { 1131 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicImportHelper" )); 1132 } 1133 Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicImportHelper_getSupportedServiceNames() 1134 throw() 1135 { 1136 // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service 1137 Sequence< ::rtl::OUString > aSupportedServiceNames( 2 ); 1138 aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) ); 1139 aSupportedServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) ); 1140 return aSupportedServiceNames; 1141 } 1142 1143 // export 1144 Reference< XInterface > SAL_CALL SvXMLGraphicExportHelper_createInstance(const Reference< XMultiServiceFactory > & /* rSMgr */ ) 1145 throw( Exception ) 1146 { 1147 return static_cast< XWeak* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_WRITE )); 1148 } 1149 ::rtl::OUString SAL_CALL SvXMLGraphicExportHelper_getImplementationName() 1150 throw() 1151 { 1152 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicExportHelper" )); 1153 } 1154 Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicExportHelper_getSupportedServiceNames() 1155 throw() 1156 { 1157 // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service 1158 Sequence< ::rtl::OUString > aSupportedServiceNames( 2 ); 1159 aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) ); 1160 aSupportedServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) ); 1161 return aSupportedServiceNames; 1162 } 1163 1164 } // namespace svx 1165