1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #define ENABLE_BYTESTRING_STREAM_OPERATORS 32 33 #include <com/sun/star/lang/XUnoTunnel.hpp> 34 #include <sfx2/objsh.hxx> 35 #include <sfx2/docfac.hxx> 36 37 #include <comphelper/classids.hxx> 38 #include <unotools/pathoptions.hxx> 39 40 #include <tools/rcid.h> 41 #include <tools/vcompat.hxx> 42 #include <vcl/virdev.hxx> 43 #include <svl/itempool.hxx> 44 #include <svx/fmmodel.hxx> 45 #include <svx/fmview.hxx> 46 #include <svx/fmpage.hxx> 47 #include "gallery.hrc" 48 #include "svx/galmisc.hxx" 49 #include "galobj.hxx" 50 #include <vcl/salbtype.hxx> // FRound 51 #include <vcl/svapp.hxx> 52 53 #include "gallerydrawmodel.hxx" 54 55 using namespace ::com::sun::star; 56 57 // ------------- 58 // - SgaObject - 59 // ------------- 60 61 SgaObject::SgaObject() : 62 bIsValid ( sal_False ), 63 bIsThumbBmp ( sal_True ) 64 { 65 } 66 67 // ------------------------------------------------------------------------ 68 69 sal_Bool SgaObject::CreateThumb( const Graphic& rGraphic ) 70 { 71 sal_Bool bRet = sal_False; 72 73 if( rGraphic.GetType() == GRAPHIC_BITMAP ) 74 { 75 BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); 76 Size aBmpSize( aBmpEx.GetSizePixel() ); 77 78 if( aBmpSize.Width() && aBmpSize.Height() ) 79 { 80 const Color aWhite( COL_WHITE ); 81 82 if( aBmpEx.GetPrefMapMode().GetMapUnit() != MAP_PIXEL && 83 aBmpEx.GetPrefSize().Width() > 0 && 84 aBmpEx.GetPrefSize().Height() > 0 ) 85 { 86 Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MAP_100TH_MM ) ); 87 88 if( aLogSize.Width() > 0 && aLogSize.Height() > 0 ) 89 { 90 double fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height(); 91 double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height(); 92 93 if( fFactorPix > fFactorLog ) 94 aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog ); 95 else 96 aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog ); 97 98 aBmpEx.SetSizePixel( aBmpSize ); 99 } 100 } 101 102 aThumbBmp = aBmpEx.GetBitmap( &aWhite ); 103 104 if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) ) 105 { 106 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); 107 bRet = sal_True; 108 } 109 else 110 { 111 const float fFactor = (float) aBmpSize.Width() / aBmpSize.Height(); 112 const Size aNewSize( Max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ), 113 Max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) ); 114 115 if( aThumbBmp.Scale( (double) aNewSize.Width() / aBmpSize.Width(), 116 (double) aNewSize.Height() / aBmpSize.Height(), BMP_SCALE_INTERPOLATE ) ) 117 { 118 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); 119 bRet = sal_True; 120 } 121 } 122 } 123 } 124 else if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) 125 { 126 const Size aPrefSize( rGraphic.GetPrefSize() ); 127 const double fFactor = (double)aPrefSize.Width() / (double)aPrefSize.Height(); 128 Size aSize( S_THUMB, S_THUMB ); 129 if ( fFactor < 1.0 ) 130 aSize.Width() = (sal_Int32)( S_THUMB * fFactor ); 131 else 132 aSize.Height() = (sal_Int32)( S_THUMB / fFactor ); 133 134 const GraphicConversionParameters aParameters(aSize); 135 aThumbBmp = rGraphic.GetBitmap(aParameters); 136 137 if( !aThumbBmp.IsEmpty() ) 138 { 139 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); 140 bRet = sal_True; 141 } 142 } 143 144 return bRet; 145 } 146 147 // ------------------------------------------------------------------------ 148 149 void SgaObject::WriteData( SvStream& rOut, const String& rDestDir ) const 150 { 151 static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' ); 152 153 rOut << nInventor << (sal_uInt16) 0x0004 << GetVersion() << (sal_uInt16) GetObjKind(); 154 rOut << bIsThumbBmp; 155 156 if( bIsThumbBmp ) 157 { 158 const sal_uInt16 nOldCompressMode = rOut.GetCompressMode(); 159 const sal_uIntPtr nOldVersion = rOut.GetVersion(); 160 161 rOut.SetCompressMode( COMPRESSMODE_ZBITMAP ); 162 rOut.SetVersion( SOFFICE_FILEFORMAT_50 ); 163 164 rOut << aThumbBmp; 165 166 rOut.SetVersion( nOldVersion ); 167 rOut.SetCompressMode( nOldCompressMode ); 168 } 169 else 170 rOut << aThumbMtf; 171 172 String aURLWithoutDestDir = String(aURL.GetMainURL( INetURLObject::NO_DECODE )); 173 aURLWithoutDestDir.SearchAndReplace(rDestDir, String()); 174 rOut << ByteString( aURLWithoutDestDir, RTL_TEXTENCODING_UTF8 ); 175 } 176 177 // ------------------------------------------------------------------------ 178 179 void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion ) 180 { 181 ByteString aTmpStr; 182 sal_uInt32 nTmp32; 183 sal_uInt16 nTmp16; 184 185 rIn >> nTmp32 >> nTmp16 >> rReadVersion >> nTmp16 >> bIsThumbBmp; 186 187 if( bIsThumbBmp ) 188 rIn >> aThumbBmp; 189 else 190 rIn >> aThumbMtf; 191 192 rIn >> aTmpStr; aURL = INetURLObject( String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ) ); 193 } 194 195 // ------------------------------------------------------------------------ 196 197 const String SgaObject::GetTitle() const 198 { 199 String aReturnValue( aTitle ); 200 if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) ) 201 { 202 if ( aReturnValue.GetTokenCount( ':' ) == 3 ) 203 { 204 String aPrivateInd ( aReturnValue.GetToken( 0, ':' ) ); 205 String aResourceName( aReturnValue.GetToken( 1, ':' ) ); 206 sal_Int32 nResId ( aReturnValue.GetToken( 2, ':' ).ToInt32() ); 207 if ( aReturnValue.GetToken( 0, ':' ).EqualsAscii( "private" ) && 208 aResourceName.Len() && ( nResId > 0 ) && ( nResId < 0x10000 ) ) 209 { 210 ByteString aMgrName( aResourceName, RTL_TEXTENCODING_UTF8 ); 211 ResMgr* pResMgr = ResMgr::CreateResMgr( aMgrName.GetBuffer(), 212 Application::GetSettings().GetUILocale() ); 213 if ( pResMgr ) 214 { 215 ResId aResId( (sal_uInt16)nResId, *pResMgr ); 216 aResId.SetRT( RSC_STRING ); 217 if ( pResMgr->IsAvailable( aResId ) ) 218 { 219 aReturnValue = String( aResId ); 220 } 221 delete pResMgr; 222 } 223 } 224 } 225 } 226 return aReturnValue; 227 } 228 229 // ------------------------------------------------------------------------ 230 231 void SgaObject::SetTitle( const String& rTitle ) 232 { 233 aTitle = rTitle; 234 } 235 236 // ------------------------------------------------------------------------ 237 238 SvStream& operator<<( SvStream& rOut, const SgaObject& rObj ) 239 { 240 rObj.WriteData( rOut, String() ); 241 return rOut; 242 } 243 244 // ------------------------------------------------------------------------ 245 246 SvStream& operator>>( SvStream& rIn, SgaObject& rObj ) 247 { 248 sal_uInt16 nReadVersion; 249 250 rObj.ReadData( rIn, nReadVersion ); 251 rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE ); 252 253 return rIn; 254 } 255 256 // ---------------- 257 // - SgaObjectBmp - 258 // ---------------- 259 260 SgaObjectBmp::SgaObjectBmp() 261 { 262 } 263 264 // ------------------------------------------------------------------------ 265 266 SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL ) 267 { 268 Graphic aGraphic; 269 String aFilter; 270 271 if ( SGA_IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) ) 272 Init( aGraphic, rURL ); 273 } 274 275 // ------------------------------------------------------------------------ 276 277 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL, const String& ) 278 { 279 if( FileExists( rURL ) ) 280 Init( rGraphic, rURL ); 281 } 282 283 // ------------------------------------------------------------------------ 284 285 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL ) 286 { 287 aURL = rURL; 288 bIsValid = CreateThumb( rGraphic ); 289 } 290 291 // ------------------------------------------------------------------------ 292 293 void SgaObjectBmp::WriteData( SvStream& rOut, const String& rDestDir ) const 294 { 295 String aDummyStr; 296 char aDummy[ 10 ]; 297 298 // Version setzen 299 SgaObject::WriteData( rOut, rDestDir ); 300 rOut.Write( aDummy, 10 ); 301 rOut << ByteString( aDummyStr, RTL_TEXTENCODING_UTF8 ) << ByteString( aTitle, RTL_TEXTENCODING_UTF8 ); 302 } 303 304 // ------------------------------------------------------------------------ 305 306 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion ) 307 { 308 ByteString aTmpStr; 309 310 SgaObject::ReadData( rIn, rReadVersion ); 311 rIn.SeekRel( 10 ); // 16, 16, 32, 16 312 rIn >> aTmpStr; // dummy 313 314 if( rReadVersion >= 5 ) 315 { 316 rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ); 317 } 318 } 319 320 // ------------------ 321 // - SgaObjectSound - 322 // ------------------ 323 DBG_NAME(SgaObjectSound) 324 325 SgaObjectSound::SgaObjectSound() : 326 eSoundType( SOUND_STANDARD ) 327 { 328 DBG_CTOR(SgaObjectSound,NULL); 329 330 } 331 332 // ------------------------------------------------------------------------ 333 334 SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) : 335 eSoundType( SOUND_STANDARD ) 336 { 337 DBG_CTOR(SgaObjectSound,NULL); 338 339 if( FileExists( rURL ) ) 340 { 341 aURL = rURL; 342 aThumbBmp = Bitmap( Size( 1, 1 ), 1 ); 343 bIsValid = sal_True; 344 } 345 else 346 bIsValid = sal_False; 347 } 348 349 // ------------------------------------------------------------------------ 350 351 SgaObjectSound::~SgaObjectSound() 352 { 353 354 DBG_DTOR(SgaObjectSound,NULL); 355 } 356 357 // ------------------------------------------------------------------------ 358 359 Bitmap SgaObjectSound::GetThumbBmp() const 360 { 361 sal_uInt16 nId; 362 363 switch( eSoundType ) 364 { 365 case( SOUND_COMPUTER ): nId = RID_SVXBMP_GALLERY_SOUND_1; break; 366 case( SOUND_MISC ): nId = RID_SVXBMP_GALLERY_SOUND_2; break; 367 case( SOUND_MUSIC ): nId = RID_SVXBMP_GALLERY_SOUND_3; break; 368 case( SOUND_NATURE ): nId = RID_SVXBMP_GALLERY_SOUND_4; break; 369 case( SOUND_SPEECH ): nId = RID_SVXBMP_GALLERY_SOUND_5; break; 370 case( SOUND_TECHNIC ): nId = RID_SVXBMP_GALLERY_SOUND_6; break; 371 case( SOUND_ANIMAL ): nId = RID_SVXBMP_GALLERY_SOUND_7; break; 372 373 // standard 374 default: 375 nId = RID_SVXBMP_GALLERY_MEDIA; 376 break; 377 } 378 379 const BitmapEx aBmpEx( GAL_RESID( nId ) ); 380 const Color aTransColor( COL_WHITE ); 381 382 return aBmpEx.GetBitmap( &aTransColor ); 383 } 384 385 // ------------------------------------------------------------------------ 386 387 void SgaObjectSound::WriteData( SvStream& rOut, const String& rDestDir ) const 388 { 389 SgaObject::WriteData( rOut, rDestDir ); 390 rOut << (sal_uInt16) eSoundType << ByteString( aTitle, RTL_TEXTENCODING_UTF8 ); 391 } 392 393 // ------------------------------------------------------------------------ 394 395 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion ) 396 { 397 SgaObject::ReadData( rIn, rReadVersion ); 398 399 if( rReadVersion >= 5 ) 400 { 401 ByteString aTmpStr; 402 sal_uInt16 nTmp16; 403 404 rIn >> nTmp16; eSoundType = (GalSoundType) nTmp16; 405 406 if( rReadVersion >= 6 ) 407 { 408 rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ); 409 } 410 } 411 } 412 413 // ----------------- 414 // - SgaObjectAnim - 415 // ----------------- 416 417 SgaObjectAnim::SgaObjectAnim() 418 { 419 } 420 421 // ------------------------------------------------------------------------ 422 423 SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic, 424 const INetURLObject& rURL, 425 const String& ) 426 { 427 aURL = rURL; 428 bIsValid = CreateThumb( rGraphic ); 429 } 430 431 // ----------------- 432 // - SgaObjectINet - 433 // ----------------- 434 435 SgaObjectINet::SgaObjectINet() 436 { 437 } 438 439 // ------------------------------------------------------------------------ 440 441 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL, const String& rFormatName ) : 442 SgaObjectAnim ( rGraphic, rURL, rFormatName ) 443 { 444 } 445 446 // ------------------- 447 // - SgaObjectSvDraw - 448 // ------------------- 449 450 SgaObjectSvDraw::SgaObjectSvDraw() 451 { 452 } 453 454 // ------------------------------------------------------------------------ 455 456 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL ) 457 { 458 aURL = rURL; 459 bIsValid = CreateThumb( rModel ); 460 } 461 462 // ------------------------------------------------------------------------ 463 DBG_NAME(SvxGalleryDrawModel) 464 465 SvxGalleryDrawModel::SvxGalleryDrawModel() 466 : mpFormModel( 0 ) 467 { 468 DBG_CTOR(SvxGalleryDrawModel,NULL); 469 470 const String sFactoryURL(RTL_CONSTASCII_USTRINGPARAM("sdraw")); 471 472 mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL ); 473 474 if( mxDoc.Is() ) 475 { 476 mxDoc->DoInitNew(0); 477 478 uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY ); 479 if( xTunnel.is() ) 480 { 481 mpFormModel = dynamic_cast< FmFormModel* >( 482 reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId()))); 483 if( mpFormModel ) 484 { 485 mpFormModel->InsertPage( mpFormModel->AllocPage( false ) ); 486 } 487 } 488 } 489 } 490 491 // ------------------------------------------------------------------------ 492 493 SvxGalleryDrawModel::~SvxGalleryDrawModel() 494 { 495 if( mxDoc.Is() ) 496 mxDoc->DoClose(); 497 498 DBG_DTOR(SvxGalleryDrawModel,NULL); 499 } 500 501 // ------------------------------------------------------------------------ 502 503 SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL ) 504 { 505 SvxGalleryDrawModel aModel; 506 507 if( aModel.GetModel() ) 508 { 509 if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) ) 510 { 511 aURL = rURL; 512 bIsValid = CreateThumb( *aModel.GetModel() ); 513 } 514 } 515 } 516 517 // ------------------------------------------------------------------------ 518 519 sal_Bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel ) 520 { 521 Graphic aGraphic; 522 ImageMap aImageMap; 523 sal_Bool bRet = sal_False; 524 525 if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) ) 526 bRet = SgaObject::CreateThumb( aGraphic ); 527 else 528 { 529 VirtualDevice aVDev; 530 531 aVDev.SetOutputSizePixel( Size( S_THUMB*2, S_THUMB*2 ) ); 532 533 bRet = DrawCentered( &aVDev, rModel ); 534 if( bRet ) 535 { 536 aThumbBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() ); 537 538 Size aMS( 2, 2 ); 539 BmpFilterParam aParam( aMS ); 540 aThumbBmp.Filter( BMP_FILTER_MOSAIC, &aParam ); 541 aThumbBmp.Scale( Size( S_THUMB, S_THUMB ) ); 542 543 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); 544 } 545 } 546 547 return bRet; 548 } 549 550 // ------------------------------------------------------------------------ 551 552 sal_Bool SgaObjectSvDraw::DrawCentered( OutputDevice* pOut, const FmFormModel& rModel ) 553 { 554 const FmFormPage* pPage = static_cast< const FmFormPage* >( rModel.GetPage( 0 ) ); 555 sal_Bool bRet = sal_False; 556 557 if( pOut && pPage ) 558 { 559 const Rectangle aObjRect( pPage->GetAllObjBoundRect() ); 560 const Size aOutSizePix( pOut->GetOutputSizePixel() ); 561 562 if( aObjRect.GetWidth() && aObjRect.GetHeight() && aOutSizePix.Width() > 2 && aOutSizePix.Height() > 2 ) 563 { 564 FmFormView aView( const_cast< FmFormModel* >( &rModel ), pOut ); 565 MapMode aMap( rModel.GetScaleUnit() ); 566 Rectangle aDrawRectPix( Point( 1, 1 ), Size( aOutSizePix.Width() - 2, aOutSizePix.Height() - 2 ) ); 567 const double fFactor = (double) aObjRect.GetWidth() / aObjRect.GetHeight(); 568 Fraction aFrac( FRound( fFactor < 1. ? aDrawRectPix.GetWidth() * fFactor : aDrawRectPix.GetWidth() ), 569 pOut->LogicToPixel( aObjRect.GetSize(), aMap ).Width() ); 570 571 aMap.SetScaleX( aFrac ); 572 aMap.SetScaleY( aFrac ); 573 574 const Size aDrawSize( pOut->PixelToLogic( aDrawRectPix.GetSize(), aMap ) ); 575 Point aOrigin( pOut->PixelToLogic( aDrawRectPix.TopLeft(), aMap ) ); 576 577 aOrigin.X() += ( ( aDrawSize.Width() - aObjRect.GetWidth() ) >> 1 ) - aObjRect.Left(); 578 aOrigin.Y() += ( ( aDrawSize.Height() - aObjRect.GetHeight() ) >> 1 ) - aObjRect.Top(); 579 aMap.SetOrigin( aOrigin ); 580 581 aView.SetPageVisible( sal_False ); 582 aView.SetBordVisible( sal_False ); 583 aView.SetGridVisible( sal_False ); 584 aView.SetHlplVisible( sal_False ); 585 aView.SetGlueVisible( sal_False ); 586 587 pOut->Push(); 588 pOut->SetMapMode( aMap ); 589 aView.ShowSdrPage( const_cast< FmFormPage* >( pPage )); 590 aView.CompleteRedraw( pOut, Rectangle( pOut->PixelToLogic( Point() ), pOut->GetOutputSize() ) ); 591 pOut->Pop(); 592 593 bRet = sal_True; 594 } 595 } 596 597 return bRet; 598 } 599 600 // ------------------------------------------------------------------------ 601 602 void SgaObjectSvDraw::WriteData( SvStream& rOut, const String& rDestDir ) const 603 { 604 SgaObject::WriteData( rOut, rDestDir ); 605 rOut << ByteString( aTitle, RTL_TEXTENCODING_UTF8 ); 606 } 607 608 // ------------------------------------------------------------------------ 609 610 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion ) 611 { 612 SgaObject::ReadData( rIn, rReadVersion ); 613 614 if( rReadVersion >= 5 ) 615 { 616 ByteString aTmpStr; 617 rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ); 618 } 619 } 620