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 _ANIMATION 28 #include <unotools/streamwrap.hxx> 29 30 #include <sfx2/lnkbase.hxx> 31 #include <math.h> 32 #include <vcl/salbtype.hxx> 33 #include <sot/formats.hxx> 34 #include <sot/storage.hxx> 35 #include <unotools/ucbstreamhelper.hxx> 36 #include <unotools/localfilehelper.hxx> 37 #include <svl/style.hxx> 38 #include <svtools/filter.hxx> 39 #include <svl/urihelper.hxx> 40 #include <svtools/grfmgr.hxx> 41 #include <vcl/svapp.hxx> 42 43 #include <sfx2/linkmgr.hxx> 44 #include <sfx2/docfile.hxx> 45 #include <svx/svdetc.hxx> 46 #include "svx/svdglob.hxx" 47 #include "svx/svdstr.hrc" 48 #include <svx/svdpool.hxx> 49 #include <svx/svdmodel.hxx> 50 #include <svx/svdpage.hxx> 51 #include <svx/svdmrkv.hxx> 52 #include <svx/svdpagv.hxx> 53 #include "svx/svdviter.hxx" 54 #include <svx/svdview.hxx> 55 #include "svtools/filter.hxx" 56 #include <svx/svdograf.hxx> 57 #include <svx/svdogrp.hxx> 58 #include <svx/xbtmpit.hxx> 59 #include <svx/xflbmtit.hxx> 60 #include <svx/svdundo.hxx> 61 #include "svdfmtf.hxx" 62 #include <svx/sdgcpitm.hxx> 63 #include <editeng/eeitem.hxx> 64 #include <svx/sdr/properties/graphicproperties.hxx> 65 #include <svx/sdr/contact/viewcontactofgraphic.hxx> 66 #include <basegfx/polygon/b2dpolygon.hxx> 67 #include <basegfx/polygon/b2dpolygontools.hxx> 68 #include <osl/thread.hxx> 69 #include <vos/mutex.hxx> 70 #include <drawinglayer/processor2d/objectinfoextractor2d.hxx> 71 #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx> 72 #include <unotools/cacheoptions.hxx> 73 #include <basegfx/matrix/b2dhommatrixtools.hxx> 74 75 using namespace ::com::sun::star::uno; 76 using namespace ::com::sun::star::io; 77 78 // ----------- 79 // - Defines - 80 // ----------- 81 82 #define GRAFSTREAMPOS_INVALID 0xffffffff 83 #define SWAPGRAPHIC_TIMEOUT 5000 84 85 // #122985# it is not correct to se the swap-timeout to a hard-coded 5000ms as it was before. 86 // Added code and experimented what to do as a good compromize, see description 87 sal_uInt32 getCacheTimeInMs() 88 { 89 static bool bSetAtAll(true); 90 91 if(bSetAtAll) 92 { 93 static bool bSetToPreferenceTime(true); 94 95 if(bSetToPreferenceTime) 96 { 97 const SvtCacheOptions aCacheOptions; 98 const sal_Int32 nSeconds(aCacheOptions.GetGraphicManagerObjectReleaseTime()); 99 100 // the default is 10 minutes. The minimum is one minute, thus 60 seconds. When the minimum 101 // should match to the former hard-coded 5 seconds, we have a divisor of 12 to use. For the 102 // default of 10 minutes this would mean 50 seconds. Compared to before this is ten times 103 // more (would allow better navigation by switching through pages) and is controllable 104 // by the user by setting the tools/options/memory/Remove_from_memory_after setting. Seems 105 // to be a good compromize to me. 106 return nSeconds * 1000 / 12; 107 } 108 else 109 { 110 return SWAPGRAPHIC_TIMEOUT; 111 } 112 } 113 114 return 0; 115 } 116 117 // ------------------ 118 // - SdrGraphicLink - 119 // ------------------ 120 121 122 const Graphic ImpLoadLinkedGraphic( const String aFileName, const String aFilterName ) 123 { 124 Graphic aGraphic; 125 126 SfxMedium xMed( aFileName, STREAM_STD_READ, sal_True ); 127 xMed.DownLoad(); 128 129 SvStream* pInStrm = xMed.GetInStream(); 130 if ( pInStrm ) 131 { 132 pInStrm->Seek( STREAM_SEEK_TO_BEGIN ); 133 GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); 134 135 const sal_uInt16 nFilter = aFilterName.Len() && pGF->GetImportFormatCount() 136 ? pGF->GetImportFormatNumber( aFilterName ) 137 : GRFILTER_FORMAT_DONTKNOW; 138 139 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 ); 140 141 // Room for improvment: 142 // As this is a linked graphic the GfxLink is not needed if saving/loading our own format. 143 // But this link is required by some filters to access the native graphic (pdf export/ms export), 144 // there we should create a new service to provide this data if needed 145 aFilterData[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) ); 146 aFilterData[ 0 ].Value = Any( sal_True ); 147 148 // #123042# for e.g SVG the path is needed, so hand it over here. I have no real idea 149 // what consequences this may have; maybe this is not handed over by purpose here. Not 150 // handing it over means that any GraphicFormat that internallv needs a path as base 151 // to interpret included links may fail. 152 // Alternatively the path may be set at the result after this call when it is known 153 // that it is a SVG graphic, but only because noone yet tried to interpret it. 154 pGF->ImportGraphic( aGraphic, aFileName, *pInStrm, nFilter, NULL, 0, &aFilterData ); 155 } 156 return aGraphic; 157 } 158 159 class SdrGraphicUpdater; 160 class SdrGraphicLink : public sfx2::SvBaseLink 161 { 162 SdrGrafObj* pGrafObj; 163 SdrGraphicUpdater* pGraphicUpdater; 164 165 public: 166 SdrGraphicLink(SdrGrafObj* pObj); 167 virtual ~SdrGraphicLink(); 168 169 virtual void Closed(); 170 virtual void DataChanged( const String& rMimeType, 171 const ::com::sun::star::uno::Any & rValue ); 172 void DataChanged( const Graphic& rGraphic ); 173 174 sal_Bool Connect() { return 0 != GetRealObject(); } 175 void UpdateAsynchron(); 176 void RemoveGraphicUpdater(); 177 }; 178 179 class SdrGraphicUpdater : public ::osl::Thread 180 { 181 public: 182 SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& ); 183 virtual ~SdrGraphicUpdater( void ); 184 185 void SAL_CALL Terminate( void ); 186 187 sal_Bool GraphicLinkChanged( const String& rFileName ){ return maFileName != rFileName; }; 188 189 protected: 190 191 /** is called from the inherited create method and acts as the 192 main function of this thread. 193 */ 194 virtual void SAL_CALL run(void); 195 196 /** Called after the thread is terminated via the terminate 197 method. Used to kill the thread by calling delete on this. 198 */ 199 virtual void SAL_CALL onTerminated(void); 200 201 private: 202 203 const String maFileName; 204 const String maFilterName; 205 SdrGraphicLink& mrGraphicLink; 206 207 volatile bool mbIsTerminated; 208 }; 209 210 SdrGraphicUpdater::SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& rGraphicLink ) 211 : maFileName( rFileName ) 212 , maFilterName( rFilterName ) 213 , mrGraphicLink( rGraphicLink ) 214 , mbIsTerminated( sal_False ) 215 { 216 create(); 217 } 218 219 SdrGraphicUpdater::~SdrGraphicUpdater( void ) 220 { 221 } 222 223 void SdrGraphicUpdater::Terminate() 224 { 225 mbIsTerminated = sal_True; 226 } 227 228 void SAL_CALL SdrGraphicUpdater::onTerminated(void) 229 { 230 delete this; 231 } 232 233 void SAL_CALL SdrGraphicUpdater::run(void) 234 { 235 sfx2::LinkManager *linkMgr = mrGraphicLink.GetLinkManager(); 236 Graphic aGraphic; 237 if ( (linkMgr == NULL) || 238 ( !linkMgr->urlIsVendor( maFileName ) && ( linkMgr->GetUserAllowsLinkUpdate(NULL) ) ) ) { 239 aGraphic = ImpLoadLinkedGraphic( maFileName, maFilterName ); 240 } 241 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 242 if ( !mbIsTerminated ) 243 { 244 mrGraphicLink.DataChanged( aGraphic ); 245 mrGraphicLink.RemoveGraphicUpdater(); 246 } 247 } 248 249 // ----------------------------------------------------------------------------- 250 251 SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj) 252 : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB ) 253 , pGrafObj( pObj ) 254 , pGraphicUpdater( NULL ) 255 { 256 SetSynchron( sal_False ); 257 } 258 259 // ----------------------------------------------------------------------------- 260 261 SdrGraphicLink::~SdrGraphicLink() 262 { 263 if ( pGraphicUpdater ) 264 pGraphicUpdater->Terminate(); 265 } 266 267 // ----------------------------------------------------------------------------- 268 269 void SdrGraphicLink::DataChanged( const Graphic& rGraphic ) 270 { 271 pGrafObj->ImpSetLinkedGraphic( rGraphic ); 272 } 273 274 // ----------------------------------------------------------------------------- 275 276 void SdrGraphicLink::RemoveGraphicUpdater() 277 { 278 pGraphicUpdater = NULL; 279 } 280 281 // ----------------------------------------------------------------------------- 282 283 void SdrGraphicLink::DataChanged( const String& rMimeType, 284 const ::com::sun::star::uno::Any & rValue ) 285 { 286 SdrModel* pModel = pGrafObj ? pGrafObj->GetModel() : 0; 287 sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0; 288 289 if( pLinkManager && rValue.hasValue() ) 290 { 291 pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName ); 292 293 Graphic aGraphic; 294 if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic )) 295 { 296 pGrafObj->NbcSetGraphic( aGraphic ); 297 pGrafObj->ActionChanged(); 298 } 299 else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() ) 300 { 301 // broadcasting, to update slidesorter 302 pGrafObj->BroadcastObjectChange(); 303 } 304 } 305 } 306 307 // ----------------------------------------------------------------------------- 308 309 void SdrGraphicLink::Closed() 310 { 311 // Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird. 312 pGrafObj->ForceSwapIn(); 313 pGrafObj->pGraphicLink=NULL; 314 pGrafObj->ReleaseGraphicLink(); 315 SvBaseLink::Closed(); 316 } 317 318 // ----------------------------------------------------------------------------- 319 320 void SdrGraphicLink::UpdateAsynchron() 321 { 322 if( GetObj() ) 323 { 324 if ( pGraphicUpdater ) 325 { 326 if ( pGraphicUpdater->GraphicLinkChanged( pGrafObj->GetFileName() ) ) 327 { 328 pGraphicUpdater->Terminate(); 329 pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this ); 330 } 331 } 332 else 333 pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this ); 334 } 335 } 336 337 // -------------- 338 // - SdrGrafObj - 339 // -------------- 340 341 ////////////////////////////////////////////////////////////////////////////// 342 // BaseProperties section 343 344 sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties() 345 { 346 return new sdr::properties::GraphicProperties(*this); 347 } 348 349 ////////////////////////////////////////////////////////////////////////////// 350 // DrawContact section 351 352 sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact() 353 { 354 return new sdr::contact::ViewContactOfGraphic(*this); 355 } 356 357 ////////////////////////////////////////////////////////////////////////////// 358 // check if SVG and if try to get ObjectInfoPrimitive2D and extract info 359 360 void SdrGrafObj::onGraphicChanged() 361 { 362 String aName; 363 String aTitle; 364 String aDesc; 365 366 if(pGraphic) 367 { 368 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData(); 369 370 if(rSvgDataPtr.get()) 371 { 372 const drawinglayer::primitive2d::Primitive2DSequence aSequence(rSvgDataPtr->getPrimitive2DSequence()); 373 374 if(aSequence.hasElements()) 375 { 376 drawinglayer::geometry::ViewInformation2D aViewInformation2D; 377 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D); 378 379 aProcessor.process(aSequence); 380 381 const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult(); 382 383 if(pResult) 384 { 385 aName = pResult->getName(); 386 aTitle = pResult->getTitle(); 387 aDesc = pResult->getDesc(); 388 } 389 } 390 } 391 } 392 393 if(aName.Len()) 394 { 395 SetName(aName); 396 } 397 398 if(aTitle.Len()) 399 { 400 SetTitle(aTitle); 401 } 402 403 if(aDesc.Len()) 404 { 405 SetDescription(aDesc); 406 } 407 } 408 409 ////////////////////////////////////////////////////////////////////////////// 410 411 TYPEINIT1(SdrGrafObj,SdrRectObj); 412 413 // ----------------------------------------------------------------------------- 414 415 SdrGrafObj::SdrGrafObj() 416 : SdrRectObj(), 417 pGraphicLink ( NULL ), 418 bMirrored ( sal_False ) 419 { 420 pGraphic = new GraphicObject; 421 mpReplacementGraphic = 0; 422 pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() ); 423 onGraphicChanged(); 424 425 // #i118485# Shear allowed and possible now 426 bNoShear = false; 427 428 // #111096# 429 mbGrafAnimationAllowed = sal_True; 430 431 // #i25616# 432 mbLineIsOutsideGeometry = sal_True; 433 mbInsidePaint = sal_False; 434 mbIsPreview = sal_False; 435 436 // #i25616# 437 mbSupportTextIndentingOnLineWidthChange = sal_False; 438 } 439 440 // ----------------------------------------------------------------------------- 441 442 SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect) 443 : SdrRectObj ( rRect ), 444 pGraphicLink ( NULL ), 445 bMirrored ( sal_False ) 446 { 447 pGraphic = new GraphicObject( rGrf ); 448 mpReplacementGraphic = 0; 449 pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() ); 450 onGraphicChanged(); 451 452 // #i118485# Shear allowed and possible now 453 bNoShear = false; 454 455 // #111096# 456 mbGrafAnimationAllowed = sal_True; 457 458 // #i25616# 459 mbLineIsOutsideGeometry = sal_True; 460 mbInsidePaint = sal_False; 461 mbIsPreview = sal_False; 462 463 // #i25616# 464 mbSupportTextIndentingOnLineWidthChange = sal_False; 465 } 466 467 // ----------------------------------------------------------------------------- 468 469 SdrGrafObj::SdrGrafObj( const Graphic& rGrf ) 470 : SdrRectObj(), 471 pGraphicLink ( NULL ), 472 bMirrored ( sal_False ) 473 { 474 pGraphic = new GraphicObject( rGrf ); 475 mpReplacementGraphic = 0; 476 pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() ); 477 onGraphicChanged(); 478 479 // #i118485# Shear allowed and possible now 480 bNoShear = false; 481 482 // #111096# 483 mbGrafAnimationAllowed = sal_True; 484 485 // #i25616# 486 mbLineIsOutsideGeometry = sal_True; 487 mbInsidePaint = sal_False; 488 mbIsPreview = sal_False; 489 490 // #i25616# 491 mbSupportTextIndentingOnLineWidthChange = sal_False; 492 } 493 494 // ----------------------------------------------------------------------------- 495 496 SdrGrafObj::~SdrGrafObj() 497 { 498 delete pGraphic; 499 delete mpReplacementGraphic; 500 ImpLinkAbmeldung(); 501 } 502 503 // ----------------------------------------------------------------------------- 504 505 void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj ) 506 { 507 *pGraphic = rGrfObj; 508 delete mpReplacementGraphic; 509 mpReplacementGraphic = 0; 510 pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() ); 511 pGraphic->SetUserData(); 512 mbIsPreview = sal_False; 513 SetChanged(); 514 BroadcastObjectChange(); 515 onGraphicChanged(); 516 } 517 518 // ----------------------------------------------------------------------------- 519 520 const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const 521 { 522 if(bForceSwapIn) 523 { 524 ForceSwapIn(); 525 } 526 527 return *pGraphic; 528 } 529 530 const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const 531 { 532 if(!mpReplacementGraphic && pGraphic) 533 { 534 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData(); 535 536 if(rSvgDataPtr.get()) 537 { 538 const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement()); 539 } 540 } 541 542 return mpReplacementGraphic; 543 } 544 545 // ----------------------------------------------------------------------------- 546 547 void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf ) 548 { 549 pGraphic->SetGraphic( rGrf ); 550 delete mpReplacementGraphic; 551 mpReplacementGraphic = 0; 552 pGraphic->SetUserData(); 553 mbIsPreview = sal_False; 554 onGraphicChanged(); 555 } 556 557 void SdrGrafObj::SetGraphic( const Graphic& rGrf ) 558 { 559 NbcSetGraphic(rGrf); 560 SetChanged(); 561 BroadcastObjectChange(); 562 } 563 564 // ----------------------------------------------------------------------------- 565 566 const Graphic& SdrGrafObj::GetGraphic() const 567 { 568 ForceSwapIn(); 569 return pGraphic->GetGraphic(); 570 } 571 572 // ----------------------------------------------------------------------------- 573 574 Graphic SdrGrafObj::GetTransformedGraphic( sal_uIntPtr nTransformFlags ) const 575 { 576 // #107947# Refactored most of the code to GraphicObject, where 577 // everybody can use e.g. the cropping functionality 578 579 GraphicType eType = GetGraphicType(); 580 MapMode aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() ); 581 const Size aDestSize( GetLogicRect().GetSize() ); 582 const sal_Bool bMirror = ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR ) != 0; 583 const sal_Bool bRotate = ( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) != 0 ) && 584 ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType ); 585 586 // #104115# Need cropping info earlier 587 ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo(); 588 GraphicAttr aActAttr; 589 590 if( SDRGRAFOBJ_TRANSFORMATTR_NONE != nTransformFlags && 591 GRAPHIC_NONE != eType ) 592 { 593 // actually transform the graphic only in this case. On the 594 // other hand, cropping will always happen 595 aActAttr = aGrafInfo; 596 597 if( bMirror ) 598 { 599 sal_uInt16 nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 ); 600 FASTBOOL bHMirr = nMirrorCase == 2 || nMirrorCase == 4; 601 FASTBOOL bVMirr = nMirrorCase == 3 || nMirrorCase == 4; 602 603 aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) ); 604 } 605 606 if( bRotate ) 607 aActAttr.SetRotation( sal_uInt16(aGeo.nDrehWink / 10) ); 608 } 609 610 // #107947# Delegate to moved code in GraphicObject 611 return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr ); 612 } 613 614 // ----------------------------------------------------------------------------- 615 616 GraphicType SdrGrafObj::GetGraphicType() const 617 { 618 return pGraphic->GetType(); 619 } 620 621 sal_Bool SdrGrafObj::IsAnimated() const 622 { 623 return pGraphic->IsAnimated(); 624 } 625 626 sal_Bool SdrGrafObj::IsEPS() const 627 { 628 return pGraphic->IsEPS(); 629 } 630 631 sal_Bool SdrGrafObj::IsSwappedOut() const 632 { 633 return mbIsPreview ? sal_True : pGraphic->IsSwappedOut(); 634 } 635 636 const MapMode& SdrGrafObj::GetGrafPrefMapMode() const 637 { 638 return pGraphic->GetPrefMapMode(); 639 } 640 641 const Size& SdrGrafObj::GetGrafPrefSize() const 642 { 643 return pGraphic->GetPrefSize(); 644 } 645 646 // ----------------------------------------------------------------------------- 647 648 void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL ) 649 { 650 mbIsPreview = sal_False; 651 if( !rGraphicStreamURL.Len() ) 652 { 653 pGraphic->SetUserData(); 654 } 655 else if( pModel->IsSwapGraphics() ) 656 { 657 pGraphic->SetUserData( rGraphicStreamURL ); 658 659 // set state of graphic object to 'swapped out' 660 if( pGraphic->GetType() == GRAPHIC_NONE ) 661 pGraphic->SetSwapState(); 662 } 663 } 664 665 // ----------------------------------------------------------------------------- 666 667 String SdrGrafObj::GetGrafStreamURL() const 668 { 669 return pGraphic->GetUserData(); 670 } 671 672 // ----------------------------------------------------------------------------- 673 674 void SdrGrafObj::SetFileName(const String& rFileName) 675 { 676 aFileName = rFileName; 677 SetChanged(); 678 } 679 680 // ----------------------------------------------------------------------------- 681 682 void SdrGrafObj::SetFilterName(const String& rFilterName) 683 { 684 aFilterName = rFilterName; 685 SetChanged(); 686 } 687 688 // ----------------------------------------------------------------------------- 689 690 void SdrGrafObj::ForceSwapIn() const 691 { 692 if( mbIsPreview ) 693 { 694 // removing preview graphic 695 const String aUserData( pGraphic->GetUserData() ); 696 697 Graphic aEmpty; 698 pGraphic->SetGraphic( aEmpty ); 699 pGraphic->SetUserData( aUserData ); 700 pGraphic->SetSwapState(); 701 702 const_cast< SdrGrafObj* >( this )->mbIsPreview = sal_False; 703 } 704 if ( pGraphicLink && pGraphic->IsSwappedOut() ) 705 ImpUpdateGraphicLink( sal_False ); 706 else 707 pGraphic->FireSwapInRequest(); 708 709 if( pGraphic->IsSwappedOut() || 710 ( pGraphic->GetType() == GRAPHIC_NONE ) || 711 ( pGraphic->GetType() == GRAPHIC_DEFAULT ) ) 712 { 713 Graphic aDefaultGraphic; 714 aDefaultGraphic.SetDefaultType(); 715 pGraphic->SetGraphic( aDefaultGraphic ); 716 } 717 } 718 719 // ----------------------------------------------------------------------------- 720 721 void SdrGrafObj::ForceSwapOut() const 722 { 723 pGraphic->FireSwapOutRequest(); 724 } 725 726 // ----------------------------------------------------------------------------- 727 728 void SdrGrafObj::ImpLinkAnmeldung() 729 { 730 sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL; 731 732 if( pLinkManager != NULL && pGraphicLink == NULL ) 733 { 734 if( aFileName.Len() ) 735 { 736 pGraphicLink = new SdrGraphicLink( this ); 737 pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL ); 738 pGraphicLink->Connect(); 739 } 740 } 741 } 742 743 // ----------------------------------------------------------------------------- 744 745 void SdrGrafObj::ImpLinkAbmeldung() 746 { 747 sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL; 748 749 if( pLinkManager != NULL && pGraphicLink!=NULL) 750 { 751 // Bei Remove wird *pGraphicLink implizit deleted 752 pLinkManager->Remove( pGraphicLink ); 753 pGraphicLink=NULL; 754 } 755 } 756 757 // ----------------------------------------------------------------------------- 758 759 void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName ) 760 { 761 ImpLinkAbmeldung(); 762 aFileName = rFileName; 763 aFilterName = rFilterName; 764 ImpLinkAnmeldung(); 765 pGraphic->SetUserData(); 766 767 // #92205# A linked graphic is per definition swapped out (has to be loaded) 768 pGraphic->SetSwapState(); 769 } 770 771 // ----------------------------------------------------------------------------- 772 773 void SdrGrafObj::ReleaseGraphicLink() 774 { 775 ImpLinkAbmeldung(); 776 aFileName = String(); 777 aFilterName = String(); 778 } 779 780 // ----------------------------------------------------------------------------- 781 782 void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const 783 { 784 FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj; 785 786 rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 || 787 aGeo.nDrehWink % 18000 == 0 || 788 aGeo.nDrehWink % 27000 == 0; 789 790 rInfo.bResizePropAllowed = sal_True; 791 rInfo.bRotateFreeAllowed = bNoPresGrf; 792 rInfo.bRotate90Allowed = bNoPresGrf; 793 rInfo.bMirrorFreeAllowed = bNoPresGrf; 794 rInfo.bMirror45Allowed = bNoPresGrf; 795 rInfo.bMirror90Allowed = !bEmptyPresObj; 796 rInfo.bTransparenceAllowed = sal_False; 797 rInfo.bGradientAllowed = sal_False; 798 799 // #i118485# Shear allowed and possible now 800 rInfo.bShearAllowed = true; 801 802 rInfo.bEdgeRadiusAllowed=sal_False; 803 rInfo.bCanConvToPath = !IsEPS(); 804 rInfo.bCanConvToPathLineToArea = sal_False; 805 rInfo.bCanConvToPolyLineToArea = sal_False; 806 rInfo.bCanConvToPoly = !IsEPS(); 807 rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary()); 808 } 809 810 // ----------------------------------------------------------------------------- 811 812 sal_uInt16 SdrGrafObj::GetObjIdentifier() const 813 { 814 return sal_uInt16( OBJ_GRAF ); 815 } 816 817 // ----------------------------------------------------------------------------- 818 819 /* The graphic of the GraphicLink will be loaded. If it is called with 820 bAsynchron = true then the graphic will be set later via DataChanged 821 */ 822 sal_Bool SdrGrafObj::ImpUpdateGraphicLink( sal_Bool bAsynchron ) const 823 { 824 sal_Bool bRet = sal_False; 825 if( pGraphicLink ) 826 { 827 sfx2::LinkManager *linkMgr = pGraphicLink->GetLinkManager(); 828 if ( (linkMgr == NULL) || 829 ( !linkMgr->urlIsVendor( aFileName ) && ( linkMgr->GetUserAllowsLinkUpdate(NULL) ) ) ) { 830 if ( bAsynchron ) 831 pGraphicLink->UpdateAsynchron(); 832 else 833 pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aFilterName ) ); 834 } // else links shall not be updated 835 bRet = sal_True; 836 } 837 return bRet; 838 } 839 840 // ----------------------------------------------------------------------------- 841 842 void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic ) 843 { 844 const sal_Bool bIsChanged = GetModel()->IsChanged(); 845 NbcSetGraphic( rGraphic ); 846 ActionChanged(); 847 BroadcastObjectChange(); 848 GetModel()->SetChanged( bIsChanged ); 849 } 850 851 // ----------------------------------------------------------------------------- 852 853 void SdrGrafObj::TakeObjNameSingul(XubString& rName) const 854 { 855 if(pGraphic) 856 { 857 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData(); 858 859 if(rSvgDataPtr.get()) 860 { 861 rName = ImpGetResStr(STR_ObjNameSingulGRAFSVG); 862 } 863 else 864 { 865 switch( pGraphic->GetType() ) 866 { 867 case GRAPHIC_BITMAP: 868 { 869 const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ? 870 ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) : 871 ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) ); 872 873 rName=ImpGetResStr( nId ); 874 } 875 break; 876 877 case GRAPHIC_GDIMETAFILE: 878 rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF ); 879 break; 880 881 case GRAPHIC_NONE: 882 rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE ); 883 break; 884 885 default: 886 rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF ); 887 break; 888 } 889 } 890 891 const String aName(GetName()); 892 893 if( aName.Len() ) 894 { 895 rName.AppendAscii( " '" ); 896 rName += aName; 897 rName += sal_Unicode( '\'' ); 898 } 899 } 900 } 901 902 // ----------------------------------------------------------------------------- 903 904 void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const 905 { 906 if(pGraphic) 907 { 908 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData(); 909 910 if(rSvgDataPtr.get()) 911 { 912 rName = ImpGetResStr(STR_ObjNamePluralGRAFSVG); 913 } 914 else 915 { 916 switch( pGraphic->GetType() ) 917 { 918 case GRAPHIC_BITMAP: 919 { 920 const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ? 921 ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) : 922 ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) ); 923 924 rName=ImpGetResStr( nId ); 925 } 926 break; 927 928 case GRAPHIC_GDIMETAFILE: 929 rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF ); 930 break; 931 932 case GRAPHIC_NONE: 933 rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE ); 934 break; 935 936 default: 937 rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF ); 938 break; 939 } 940 } 941 942 const String aName(GetName()); 943 944 if( aName.Len() ) 945 { 946 rName.AppendAscii( " '" ); 947 rName += aName; 948 rName += sal_Unicode( '\'' ); 949 } 950 } 951 } 952 953 // ----------------------------------------------------------------------------- 954 955 SdrObject* SdrGrafObj::getFullDragClone() const 956 { 957 // call parent 958 SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone()); 959 960 // #i103116# the full drag clone leads to problems 961 // with linked graphics, so reset the link in this 962 // temporary interaction object and load graphic 963 if(pRetval && IsLinkedGraphic()) 964 { 965 pRetval->ForceSwapIn(); 966 pRetval->ReleaseGraphicLink(); 967 } 968 969 return pRetval; 970 } 971 972 void SdrGrafObj::operator=( const SdrObject& rObj ) 973 { 974 SdrRectObj::operator=( rObj ); 975 976 const SdrGrafObj& rGraf = (SdrGrafObj&) rObj; 977 978 pGraphic->SetGraphic( rGraf.GetGraphic(), &rGraf.GetGraphicObject() ); 979 aCropRect = rGraf.aCropRect; 980 aFileName = rGraf.aFileName; 981 aFilterName = rGraf.aFilterName; 982 bMirrored = rGraf.bMirrored; 983 984 if( rGraf.pGraphicLink != NULL) 985 { 986 SetGraphicLink( aFileName, aFilterName ); 987 } 988 989 ImpSetAttrToGrafInfo(); 990 } 991 992 // ----------------------------------------------------------------------------- 993 // #i25616# 994 995 basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const 996 { 997 if(mbInsidePaint) 998 { 999 basegfx::B2DPolyPolygon aRetval; 1000 1001 // take grown rectangle 1002 const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2); 1003 const Rectangle aGrownRect( 1004 aRect.Left() - nHalfLineWidth, 1005 aRect.Top() - nHalfLineWidth, 1006 aRect.Right() + nHalfLineWidth, 1007 aRect.Bottom() + nHalfLineWidth); 1008 1009 XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius())); 1010 aRetval.append(aXPoly.getB2DPolygon()); 1011 1012 return aRetval; 1013 } 1014 else 1015 { 1016 // call parent 1017 return SdrRectObj::TakeXorPoly(); 1018 } 1019 } 1020 1021 // ----------------------------------------------------------------------------- 1022 1023 sal_uInt32 SdrGrafObj::GetHdlCount() const 1024 { 1025 return 8L; 1026 } 1027 1028 // ----------------------------------------------------------------------------- 1029 1030 SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const 1031 { 1032 return SdrRectObj::GetHdl( nHdlNum + 1L ); 1033 } 1034 1035 // ----------------------------------------------------------------------------- 1036 1037 void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) 1038 { 1039 SdrRectObj::NbcResize( rRef, xFact, yFact ); 1040 1041 FASTBOOL bMirrX = xFact.GetNumerator() < 0; 1042 FASTBOOL bMirrY = yFact.GetNumerator() < 0; 1043 1044 if( bMirrX != bMirrY ) 1045 bMirrored = !bMirrored; 1046 } 1047 1048 // ----------------------------------------------------------------------------- 1049 1050 void SdrGrafObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs) 1051 { 1052 SdrRectObj::NbcRotate(rRef,nWink,sn,cs); 1053 } 1054 1055 // ----------------------------------------------------------------------------- 1056 1057 void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2) 1058 { 1059 SdrRectObj::NbcMirror(rRef1,rRef2); 1060 bMirrored = !bMirrored; 1061 } 1062 1063 // ----------------------------------------------------------------------------- 1064 1065 void SdrGrafObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear) 1066 { 1067 // #i118485# Call Shear now, old version redirected to rotate 1068 SdrRectObj::NbcShear(rRef, nWink, tn, bVShear); 1069 } 1070 1071 // ----------------------------------------------------------------------------- 1072 1073 void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect) 1074 { 1075 SdrRectObj::NbcSetSnapRect(rRect); 1076 } 1077 1078 // ----------------------------------------------------------------------------- 1079 1080 void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect) 1081 { 1082 //int bChg=rRect.GetSize()!=aRect.GetSize(); 1083 SdrRectObj::NbcSetLogicRect(rRect); 1084 } 1085 1086 // ----------------------------------------------------------------------------- 1087 1088 SdrObjGeoData* SdrGrafObj::NewGeoData() const 1089 { 1090 return new SdrGrafObjGeoData; 1091 } 1092 1093 // ----------------------------------------------------------------------------- 1094 1095 void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const 1096 { 1097 SdrRectObj::SaveGeoData(rGeo); 1098 SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo; 1099 rGGeo.bMirrored=bMirrored; 1100 } 1101 1102 // ----------------------------------------------------------------------------- 1103 1104 void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo) 1105 { 1106 //long nDrehMerk = aGeo.nDrehWink; 1107 //long nShearMerk = aGeo.nShearWink; 1108 //int bMirrMerk = bMirrored; 1109 Size aSizMerk( aRect.GetSize() ); 1110 1111 SdrRectObj::RestGeoData(rGeo); 1112 SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo; 1113 bMirrored=rGGeo.bMirrored; 1114 } 1115 1116 // ----------------------------------------------------------------------------- 1117 1118 void SdrGrafObj::SetPage( SdrPage* pNewPage ) 1119 { 1120 FASTBOOL bRemove = pNewPage == NULL && pPage != NULL; 1121 FASTBOOL bInsert = pNewPage != NULL && pPage == NULL; 1122 1123 if( bRemove ) 1124 { 1125 // hier kein SwapIn noetig, weil wenn nicht geladen, dann auch nicht animiert. 1126 if( pGraphic->IsAnimated()) 1127 pGraphic->StopAnimation(); 1128 1129 if( pGraphicLink != NULL ) 1130 ImpLinkAbmeldung(); 1131 } 1132 1133 if(!pModel && !GetStyleSheet() && pNewPage->GetModel()) 1134 { 1135 // #119287# Set default StyleSheet for SdrGrafObj here, it is different from 'Default'. This 1136 // needs to be done before the style 'Default' is set from the :SetModel() call which is triggered 1137 // from the following :SetPage(). 1138 // TTTT: Needs to be moved in branch aw080 due to having a SdrModel from the beginning, is at this 1139 // place for convenience currently (works in both versions, is not in the way) 1140 SfxStyleSheet* pSheet = pNewPage->GetModel()->GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj(); 1141 1142 if(pSheet) 1143 { 1144 SetStyleSheet(pSheet, false); 1145 } 1146 else 1147 { 1148 SetMergedItem(XFillStyleItem(XFILL_NONE)); 1149 SetMergedItem(XLineStyleItem(XLINE_NONE)); 1150 } 1151 } 1152 1153 SdrRectObj::SetPage( pNewPage ); 1154 1155 if(aFileName.Len() && bInsert) 1156 ImpLinkAnmeldung(); 1157 } 1158 1159 // ----------------------------------------------------------------------------- 1160 1161 void SdrGrafObj::SetModel( SdrModel* pNewModel ) 1162 { 1163 FASTBOOL bChg = pNewModel != pModel; 1164 1165 if( bChg ) 1166 { 1167 if( pGraphic->HasUserData() ) 1168 { 1169 ForceSwapIn(); 1170 pGraphic->SetUserData(); 1171 } 1172 1173 if( pGraphicLink != NULL ) 1174 ImpLinkAbmeldung(); 1175 } 1176 1177 // Model umsetzen 1178 SdrRectObj::SetModel(pNewModel); 1179 1180 if( bChg && aFileName.Len() ) 1181 ImpLinkAnmeldung(); 1182 } 1183 1184 // ----------------------------------------------------------------------------- 1185 1186 void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/) 1187 { 1188 // #111096# 1189 // use new graf animation 1190 SetGrafAnimationAllowed(sal_True); 1191 } 1192 1193 // ----------------------------------------------------------------------------- 1194 1195 void SdrGrafObj::StopAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/) 1196 { 1197 // #111096# 1198 // use new graf animation 1199 SetGrafAnimationAllowed(sal_False); 1200 } 1201 1202 // ----------------------------------------------------------------------------- 1203 1204 FASTBOOL SdrGrafObj::HasGDIMetaFile() const 1205 { 1206 return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE ); 1207 } 1208 1209 // ----------------------------------------------------------------------------- 1210 1211 const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const 1212 { 1213 DBG_ERROR( "Invalid return value! Don't use it! (KA)" ); 1214 return &GetGraphic().GetGDIMetaFile(); 1215 } 1216 1217 // ----------------------------------------------------------------------------- 1218 1219 bool SdrGrafObj::isEmbeddedSvg() const 1220 { 1221 return GRAPHIC_BITMAP == GetGraphicType() && GetGraphic().getSvgData().get(); 1222 } 1223 1224 GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedSvg() const 1225 { 1226 GDIMetaFile aRetval; 1227 1228 if(isEmbeddedSvg() && GetModel()) 1229 { 1230 VirtualDevice aOut; 1231 const Rectangle aBoundRect(GetCurrentBoundRect()); 1232 const MapMode aMap(GetModel()->GetScaleUnit(), Point(), GetModel()->GetScaleFraction(), GetModel()->GetScaleFraction()); 1233 1234 aOut.EnableOutput(false); 1235 aOut.SetMapMode(aMap); 1236 aRetval.Record(&aOut); 1237 SingleObjectPainter(aOut); 1238 aRetval.Stop(); 1239 aRetval.WindStart(); 1240 aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top()); 1241 aRetval.SetPrefMapMode(aMap); 1242 aRetval.SetPrefSize(aBoundRect.GetSize()); 1243 } 1244 1245 return aRetval; 1246 } 1247 1248 SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const 1249 { 1250 SdrObject* pRetval = NULL; 1251 GraphicType aGraphicType(GetGraphicType()); 1252 GDIMetaFile aMtf; 1253 1254 if(isEmbeddedSvg()) 1255 { 1256 // Embedded Svg 1257 // There is currently no helper to create SdrObjects from primitives (even if I'm thinking 1258 // about writing one for some time). To get the roundtrip to SdrObjects it is necessary to 1259 // use the old converter path over the MetaFile mechanism. Create Metafile from Svg 1260 // primitives here pretty directly 1261 aMtf = getMetafileFromEmbeddedSvg(); 1262 aGraphicType = GRAPHIC_GDIMETAFILE; 1263 } 1264 else if(GRAPHIC_GDIMETAFILE == aGraphicType) 1265 { 1266 aMtf = GetTransformedGraphic(SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile(); 1267 } 1268 1269 switch(aGraphicType) 1270 { 1271 case GRAPHIC_GDIMETAFILE: 1272 { 1273 // NUR die aus dem MetaFile erzeugbaren Objekte in eine Gruppe packen und zurueckliefern 1274 ImpSdrGDIMetaFileImport aFilter(*GetModel(), GetLayer(), aRect); 1275 SdrObjGroup* pGrp = new SdrObjGroup(); 1276 sal_uInt32 nInsAnz = aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0); 1277 1278 if(nInsAnz) 1279 { 1280 { 1281 // copy transformation 1282 GeoStat aGeoStat(GetGeoStat()); 1283 1284 if(aGeoStat.nShearWink) 1285 { 1286 aGeoStat.RecalcTan(); 1287 pGrp->NbcShear(aRect.TopLeft(), aGeoStat.nShearWink, aGeoStat.nTan, false); 1288 } 1289 1290 if(aGeoStat.nDrehWink) 1291 { 1292 aGeoStat.RecalcSinCos(); 1293 pGrp->NbcRotate(aRect.TopLeft(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos); 1294 } 1295 } 1296 1297 pRetval = pGrp; 1298 pGrp->NbcSetLayer(GetLayer()); 1299 pGrp->SetModel(GetModel()); 1300 1301 if(bAddText) 1302 { 1303 pRetval = ImpConvertAddText(pRetval, bBezier); 1304 } 1305 1306 // convert all children 1307 if( pRetval ) 1308 { 1309 SdrObject* pHalfDone = pRetval; 1310 pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText); 1311 SdrObject::Free( pHalfDone ); // resulting object is newly created 1312 1313 if( pRetval ) 1314 { 1315 // flatten subgroups. As we call 1316 // DoConvertToPolyObj() on the resulting group 1317 // objects, subgroups can exist (e.g. text is 1318 // a group object for every line). 1319 SdrObjList* pList = pRetval->GetSubList(); 1320 if( pList ) 1321 pList->FlattenGroups(); 1322 } 1323 } 1324 } 1325 else 1326 { 1327 delete pGrp; 1328 } 1329 1330 // #i118485# convert line and fill 1331 SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false); 1332 1333 if(pLineFill) 1334 { 1335 if(pRetval) 1336 { 1337 pGrp = dynamic_cast< SdrObjGroup* >(pRetval); 1338 1339 if(!pGrp) 1340 { 1341 pGrp = new SdrObjGroup(); 1342 1343 pGrp->NbcSetLayer(GetLayer()); 1344 pGrp->SetModel(GetModel()); 1345 pGrp->GetSubList()->NbcInsertObject(pRetval); 1346 } 1347 1348 pGrp->GetSubList()->NbcInsertObject(pLineFill, 0); 1349 } 1350 else 1351 { 1352 pRetval = pLineFill; 1353 } 1354 } 1355 1356 break; 1357 } 1358 case GRAPHIC_BITMAP: 1359 { 1360 // Grundobjekt kreieren und Fuellung ergaenzen 1361 pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText); 1362 1363 // Bitmap als Attribut retten 1364 if(pRetval) 1365 { 1366 // Bitmap als Fuellung holen 1367 SfxItemSet aSet(GetObjectItemSet()); 1368 1369 aSet.Put(XFillStyleItem(XFILL_BITMAP)); 1370 const BitmapEx aBitmapEx(GetTransformedGraphic().GetBitmapEx()); 1371 aSet.Put(XFillBitmapItem(String(), Graphic(aBitmapEx))); 1372 aSet.Put(XFillBmpTileItem(false)); 1373 1374 pRetval->SetMergedItemSet(aSet); 1375 } 1376 break; 1377 } 1378 case GRAPHIC_NONE: 1379 case GRAPHIC_DEFAULT: 1380 { 1381 pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText); 1382 break; 1383 } 1384 } 1385 1386 return pRetval; 1387 } 1388 1389 // ----------------------------------------------------------------------------- 1390 1391 void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 1392 { 1393 SetXPolyDirty(); 1394 SdrRectObj::Notify( rBC, rHint ); 1395 ImpSetAttrToGrafInfo(); 1396 } 1397 1398 void SdrGrafObj::ImpSetAttrToGrafInfo() 1399 { 1400 const SfxItemSet& rSet = GetObjectItemSet(); 1401 const sal_uInt16 nTrans = ( (SdrGrafTransparenceItem&) rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue(); 1402 const SdrGrafCropItem& rCrop = (const SdrGrafCropItem&) rSet.Get( SDRATTR_GRAFCROP ); 1403 1404 aGrafInfo.SetLuminance( ( (SdrGrafLuminanceItem&) rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() ); 1405 aGrafInfo.SetContrast( ( (SdrGrafContrastItem&) rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() ); 1406 aGrafInfo.SetChannelR( ( (SdrGrafRedItem&) rSet.Get( SDRATTR_GRAFRED ) ).GetValue() ); 1407 aGrafInfo.SetChannelG( ( (SdrGrafGreenItem&) rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() ); 1408 aGrafInfo.SetChannelB( ( (SdrGrafBlueItem&) rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() ); 1409 aGrafInfo.SetGamma( ( (SdrGrafGamma100Item&) rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 ); 1410 aGrafInfo.SetTransparency( (sal_uInt8) FRound( Min( nTrans, (sal_uInt16) 100 ) * 2.55 ) ); 1411 aGrafInfo.SetInvert( ( (SdrGrafInvertItem&) rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() ); 1412 aGrafInfo.SetDrawMode( ( (SdrGrafModeItem&) rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() ); 1413 aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() ); 1414 1415 SetXPolyDirty(); 1416 SetRectsDirty(); 1417 } 1418 1419 // ----------------------------------------------------------------------------- 1420 1421 void SdrGrafObj::ImpSetGrafInfoToAttr() 1422 { 1423 SetObjectItem( SdrGrafLuminanceItem( aGrafInfo.GetLuminance() ) ); 1424 SetObjectItem( SdrGrafContrastItem( aGrafInfo.GetContrast() ) ); 1425 SetObjectItem( SdrGrafRedItem( aGrafInfo.GetChannelR() ) ); 1426 SetObjectItem( SdrGrafGreenItem( aGrafInfo.GetChannelG() ) ); 1427 SetObjectItem( SdrGrafBlueItem( aGrafInfo.GetChannelB() ) ); 1428 SetObjectItem( SdrGrafGamma100Item( FRound( aGrafInfo.GetGamma() * 100.0 ) ) ); 1429 SetObjectItem( SdrGrafTransparenceItem( (sal_uInt16) FRound( aGrafInfo.GetTransparency() / 2.55 ) ) ); 1430 SetObjectItem( SdrGrafInvertItem( aGrafInfo.IsInvert() ) ); 1431 SetObjectItem( SdrGrafModeItem( aGrafInfo.GetDrawMode() ) ); 1432 SetObjectItem( SdrGrafCropItem( aGrafInfo.GetLeftCrop(), aGrafInfo.GetTopCrop(), aGrafInfo.GetRightCrop(), aGrafInfo.GetBottomCrop() ) ); 1433 } 1434 1435 // ----------------------------------------------------------------------------- 1436 1437 void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly ) 1438 { 1439 Size aSize; 1440 Size aMaxSize( rMaxRect.GetSize() ); 1441 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL ) 1442 aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM ); 1443 else 1444 aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(), 1445 pGraphic->GetPrefMapMode(), 1446 MapMode( MAP_100TH_MM ) ); 1447 1448 if( aSize.Height() != 0 && aSize.Width() != 0 ) 1449 { 1450 Point aPos( rMaxRect.TopLeft() ); 1451 1452 // Falls Grafik zu gross, wird die Grafik 1453 // in die Seite eingepasst 1454 if ( (!bShrinkOnly || 1455 ( aSize.Height() > aMaxSize.Height() ) || 1456 ( aSize.Width() > aMaxSize.Width() ) )&& 1457 aSize.Height() && aMaxSize.Height() ) 1458 { 1459 float fGrfWH = (float)aSize.Width() / 1460 (float)aSize.Height(); 1461 float fWinWH = (float)aMaxSize.Width() / 1462 (float)aMaxSize.Height(); 1463 1464 // Grafik an Pagesize anpassen (skaliert) 1465 if ( fGrfWH < fWinWH ) 1466 { 1467 aSize.Width() = (long)(aMaxSize.Height() * fGrfWH); 1468 aSize.Height()= aMaxSize.Height(); 1469 } 1470 else if ( fGrfWH > 0.F ) 1471 { 1472 aSize.Width() = aMaxSize.Width(); 1473 aSize.Height()= (long)(aMaxSize.Width() / fGrfWH); 1474 } 1475 1476 aPos = rMaxRect.Center(); 1477 } 1478 1479 if( bShrinkOnly ) 1480 aPos = aRect.TopLeft(); 1481 1482 aPos.X() -= aSize.Width() / 2; 1483 aPos.Y() -= aSize.Height() / 2; 1484 SetLogicRect( Rectangle( aPos, aSize ) ); 1485 } 1486 } 1487 1488 // ----------------------------------------------------------------------------- 1489 1490 IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO ) 1491 { 1492 SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE; 1493 1494 if( pO->IsInSwapOut() ) 1495 { 1496 if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 ) 1497 { 1498 // test if this object is visualized from someone 1499 // ## test only if there are VOCs other than the preview renderer 1500 if(!GetViewContact().HasViewObjectContacts(true)) 1501 { 1502 const sal_uIntPtr nSwapMode = pModel->GetSwapGraphicsMode(); 1503 1504 if( ( pGraphic->HasUserData() || pGraphicLink ) && 1505 ( nSwapMode & SDR_SWAPGRAPHICSMODE_PURGE ) ) 1506 { 1507 pRet = GRFMGR_AUTOSWAPSTREAM_LINK; 1508 } 1509 else if( nSwapMode & SDR_SWAPGRAPHICSMODE_TEMP ) 1510 { 1511 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP; 1512 pGraphic->SetUserData(); 1513 } 1514 1515 // #i102380# 1516 sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact()); 1517 1518 if(pVC) 1519 { 1520 pVC->flushGraphicObjects(); 1521 } 1522 } 1523 } 1524 } 1525 else if( pO->IsInSwapIn() ) 1526 { 1527 // kann aus dem original Doc-Stream nachgeladen werden... 1528 if( pModel != NULL ) 1529 { 1530 if( pGraphic->HasUserData() ) 1531 { 1532 SdrDocumentStreamInfo aStreamInfo; 1533 1534 aStreamInfo.mbDeleteAfterUse = sal_False; 1535 aStreamInfo.maUserData = pGraphic->GetUserData(); 1536 1537 SvStream* pStream = pModel->GetDocumentStream( aStreamInfo ); 1538 1539 if( pStream != NULL ) 1540 { 1541 Graphic aGraphic; 1542 1543 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL; 1544 1545 if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true)) 1546 { 1547 pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 ); 1548 1549 const com::sun::star::awt::Size aPreviewSizeHint( 64, 64 ); 1550 const sal_Bool bAllowPartialStreamRead = sal_True; 1551 // create <GfxLink> instance also for previews in order to avoid that its corresponding 1552 // data is cleared in the graphic cache entry in case that the preview data equals the complete graphic data 1553 const sal_Bool bCreateNativeLink = sal_True; 1554 (*pFilterData)[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "PreviewSizeHint" ) ); 1555 (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint; 1556 (*pFilterData)[ 1 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "AllowPartialStreamRead" ) ); 1557 (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead; 1558 (*pFilterData)[ 2 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) ); 1559 (*pFilterData)[ 2 ].Value <<= bCreateNativeLink; 1560 1561 mbIsPreview = sal_True; 1562 } 1563 1564 if(!GraphicFilter::GetGraphicFilter()->ImportGraphic( 1565 aGraphic, aStreamInfo.maUserData, *pStream, 1566 GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData)) 1567 { 1568 const String aUserData( pGraphic->GetUserData() ); 1569 1570 pGraphic->SetGraphic( aGraphic ); 1571 pGraphic->SetUserData( aUserData ); 1572 1573 // #142146# Graphic successfully swapped in. 1574 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED; 1575 } 1576 delete pFilterData; 1577 1578 pStream->ResetError(); 1579 1580 if( aStreamInfo.mbDeleteAfterUse || aStreamInfo.mxStorageRef.is() ) 1581 { 1582 if ( aStreamInfo.mxStorageRef.is() ) 1583 { 1584 aStreamInfo.mxStorageRef->dispose(); 1585 aStreamInfo.mxStorageRef = 0; 1586 } 1587 1588 delete pStream; 1589 } 1590 } 1591 } 1592 else if( !ImpUpdateGraphicLink( sal_False ) ) 1593 { 1594 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP; 1595 } 1596 else 1597 { 1598 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED; 1599 } 1600 } 1601 else 1602 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP; 1603 } 1604 1605 return (long)(void*) pRet; 1606 } 1607 1608 // ----------------------------------------------------------------------------- 1609 1610 // #111096# 1611 // Access to GrafAnimationAllowed flag 1612 sal_Bool SdrGrafObj::IsGrafAnimationAllowed() const 1613 { 1614 return mbGrafAnimationAllowed; 1615 } 1616 1617 void SdrGrafObj::SetGrafAnimationAllowed(sal_Bool bNew) 1618 { 1619 if(mbGrafAnimationAllowed != bNew) 1620 { 1621 mbGrafAnimationAllowed = bNew; 1622 ActionChanged(); 1623 } 1624 } 1625 1626 // #i25616# 1627 sal_Bool SdrGrafObj::IsObjectTransparent() const 1628 { 1629 if(((const SdrGrafTransparenceItem&)GetObjectItem(SDRATTR_GRAFTRANSPARENCE)).GetValue() 1630 || pGraphic->IsTransparent()) 1631 { 1632 return sal_True; 1633 } 1634 1635 return sal_False; 1636 } 1637 1638 Reference< XInputStream > SdrGrafObj::getInputStream() 1639 { 1640 Reference< XInputStream > xStream; 1641 1642 if( pModel ) 1643 { 1644 // if( !pGraphic->HasUserData() ) 1645 // pGraphic->SwapOut(); 1646 1647 // kann aus dem original Doc-Stream nachgeladen werden... 1648 if( pGraphic->HasUserData() ) 1649 { 1650 SdrDocumentStreamInfo aStreamInfo; 1651 1652 aStreamInfo.mbDeleteAfterUse = sal_False; 1653 aStreamInfo.maUserData = pGraphic->GetUserData(); 1654 1655 SvStream* pStream = pModel->GetDocumentStream( aStreamInfo ); 1656 1657 if( pStream ) 1658 xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) ); 1659 } 1660 else if( pGraphic && GetGraphic().IsLink() ) 1661 { 1662 Graphic aGraphic( GetGraphic() ); 1663 GfxLink aLink( aGraphic.GetLink() ); 1664 sal_uInt32 nSize = aLink.GetDataSize(); 1665 const void* pSourceData = (const void*)aLink.GetData(); 1666 if( nSize && pSourceData ) 1667 { 1668 sal_uInt8 * pBuffer = new sal_uInt8[ nSize ]; 1669 if( pBuffer ) 1670 { 1671 memcpy( pBuffer, pSourceData, nSize ); 1672 1673 SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, STREAM_READ ); 1674 pStream->ObjectOwnsMemory( sal_True ); 1675 xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) ); 1676 } 1677 } 1678 } 1679 1680 if( !xStream.is() && aFileName.Len() ) 1681 { 1682 SvFileStream* pStream = new SvFileStream( aFileName, STREAM_READ ); 1683 if( pStream ) 1684 xStream.set( new utl::OInputStreamWrapper( pStream ) ); 1685 } 1686 } 1687 1688 return xStream; 1689 } 1690 1691 // moved crop handle creation here; this is the object type using them 1692 void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const 1693 { 1694 basegfx::B2DHomMatrix aMatrix; 1695 basegfx::B2DPolyPolygon aPolyPolygon; 1696 1697 // get object transformation 1698 TRGetBaseGeometry(aMatrix, aPolyPolygon); 1699 1700 // part of object transformation correction, but used later, so defined outside next scope 1701 double fShearX(0.0), fRotate(0.0); 1702 1703 { // TTTT correct shear, it comes currently mirrored from TRGetBaseGeometry, can be removed with aw080 1704 basegfx::B2DTuple aScale; 1705 basegfx::B2DTuple aTranslate; 1706 1707 aMatrix.decompose(aScale, aTranslate, fRotate, fShearX); 1708 1709 if(!basegfx::fTools::equalZero(fShearX)) 1710 { 1711 // shearX is used, correct it 1712 fShearX = -fShearX; 1713 } 1714 1715 aMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 1716 aScale, 1717 fShearX, 1718 fRotate, 1719 aTranslate); 1720 } 1721 1722 // get crop values 1723 const SdrGrafCropItem& rCrop = static_cast< const SdrGrafCropItem& >(GetMergedItem(SDRATTR_GRAFCROP)); 1724 1725 if(rCrop.GetLeft() || rCrop.GetTop() || rCrop.GetRight() ||rCrop.GetBottom()) 1726 { 1727 // decompose object transformation to have current translate and scale 1728 basegfx::B2DVector aScale, aTranslate; 1729 double fRotate, fShearX; 1730 1731 aMatrix.decompose(aScale, aTranslate, fRotate, fShearX); 1732 1733 if(!aScale.equalZero()) 1734 { 1735 // get crop scale 1736 const basegfx::B2DVector aCropScaleFactor( 1737 GetGraphicObject().calculateCropScaling( 1738 aScale.getX(), 1739 aScale.getY(), 1740 rCrop.GetLeft(), 1741 rCrop.GetTop(), 1742 rCrop.GetRight(), 1743 rCrop.GetBottom())); 1744 1745 // apply crop scale 1746 const double fCropLeft(rCrop.GetLeft() * aCropScaleFactor.getX()); 1747 const double fCropTop(rCrop.GetTop() * aCropScaleFactor.getY()); 1748 const double fCropRight(rCrop.GetRight() * aCropScaleFactor.getX()); 1749 const double fCropBottom(rCrop.GetBottom() * aCropScaleFactor.getY()); 1750 basegfx::B2DHomMatrix aMatrixForCropViewHdl(aMatrix); 1751 1752 if(IsMirrored()) 1753 { 1754 // create corrected new matrix, TTTT can be removed with aw080 1755 // the old mirror only can mirror horizontally; the vertical mirror 1756 // is faked by using the horizontal and 180 degree rotation. Since 1757 // the object can be rotated differently from 180 degree, this is 1758 // not safe to detect. Just correct horizontal mirror (which is 1759 // in IsMirrored()) and keep the rotation angle 1760 // caution: Do not modify aMatrix, it is used below to calculate 1761 // the exact handle positions 1762 basegfx::B2DHomMatrix aPreMultiply; 1763 1764 // mirrored X, apply 1765 aPreMultiply.translate(-0.5, 0.0); 1766 aPreMultiply.scale(-1.0, 1.0); 1767 aPreMultiply.translate(0.5, 0.0); 1768 1769 aMatrixForCropViewHdl = aMatrixForCropViewHdl * aPreMultiply; 1770 } 1771 1772 rTarget.AddHdl( 1773 new SdrCropViewHdl( 1774 aMatrixForCropViewHdl, 1775 GetGraphicObject().GetGraphic(), 1776 fCropLeft, 1777 fCropTop, 1778 fCropRight, 1779 fCropBottom)); 1780 } 1781 } 1782 1783 basegfx::B2DPoint aPos; 1784 1785 aPos = aMatrix * basegfx::B2DPoint(0.0, 0.0); 1786 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPLFT, fShearX, fRotate)); 1787 aPos = aMatrix * basegfx::B2DPoint(0.5, 0.0); 1788 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPPER, fShearX, fRotate)); 1789 aPos = aMatrix * basegfx::B2DPoint(1.0, 0.0); 1790 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPRGT, fShearX, fRotate)); 1791 aPos = aMatrix * basegfx::B2DPoint(0.0, 0.5); 1792 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LEFT , fShearX, fRotate)); 1793 aPos = aMatrix * basegfx::B2DPoint(1.0, 0.5); 1794 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_RIGHT, fShearX, fRotate)); 1795 aPos = aMatrix * basegfx::B2DPoint(0.0, 1.0); 1796 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWLFT, fShearX, fRotate)); 1797 aPos = aMatrix * basegfx::B2DPoint(0.5, 1.0); 1798 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LOWER, fShearX, fRotate)); 1799 aPos = aMatrix * basegfx::B2DPoint(1.0, 1.0); 1800 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWRGT, fShearX, fRotate)); 1801 } 1802 1803 // eof 1804