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