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