1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 #include <svx/sdr/contact/viewcontactofunocontrol.hxx> 31 #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx> 32 #include <com/sun/star/container/XChild.hpp> 33 #include <com/sun/star/awt/XWindow.hpp> 34 #include <com/sun/star/awt/PosSize.hpp> 35 #include <com/sun/star/beans/XPropertySet.hpp> 36 #include <com/sun/star/io/XPersistObject.hpp> 37 #include <com/sun/star/io/XOutputStream.hpp> 38 #include <com/sun/star/io/XInputStream.hpp> 39 #include <com/sun/star/io/XActiveDataSink.hpp> 40 #include <com/sun/star/io/XActiveDataSource.hpp> 41 #include <com/sun/star/io/XObjectOutputStream.hpp> 42 #include <com/sun/star/io/XObjectInputStream.hpp> 43 #include <com/sun/star/util/XCloneable.hpp> 44 #include <comphelper/processfactory.hxx> 45 #include <comphelper/types.hxx> 46 #include <vcl/pdfextoutdevdata.hxx> 47 #include <svx/svdouno.hxx> 48 #include <svx/svdpagv.hxx> 49 #include <svx/svdmodel.hxx> 50 #include "svx/svdglob.hxx" // Stringcache 51 #include "svx/svdstr.hrc" // Objektname 52 #include <svx/svdetc.hxx> 53 #include <svx/svdview.hxx> 54 #include <svx/svdorect.hxx> 55 #include "svx/svdviter.hxx" 56 #include <rtl/ref.hxx> 57 #include <set> 58 #include <memory> 59 #include <svx/sdrpagewindow.hxx> 60 #include <svx/sdrpaintwindow.hxx> 61 #include <tools/diagnose_ex.h> 62 #include <svx/svdograf.hxx> 63 64 using namespace ::com::sun::star; 65 using namespace ::sdr::contact; 66 67 //************************************************************ 68 // Defines 69 //************************************************************ 70 71 //************************************************************ 72 // Hilfsklasse SdrControlEventListenerImpl 73 //************************************************************ 74 #include <com/sun/star/lang/XEventListener.hpp> 75 76 #include <cppuhelper/implbase1.hxx> 77 78 // ============================================================================= 79 class SdrControlEventListenerImpl : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener > 80 { 81 protected: 82 SdrUnoObj* pObj; 83 84 public: 85 SdrControlEventListenerImpl(SdrUnoObj* _pObj) 86 : pObj(_pObj) 87 {} 88 89 // XEventListener 90 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); 91 92 void StopListening(const uno::Reference< lang::XComponent >& xComp); 93 void StartListening(const uno::Reference< lang::XComponent >& xComp); 94 }; 95 96 // XEventListener 97 void SAL_CALL SdrControlEventListenerImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/) 98 throw(::com::sun::star::uno::RuntimeException) 99 { 100 if (pObj) 101 { 102 pObj->xUnoControlModel = NULL; 103 } 104 } 105 106 void SdrControlEventListenerImpl::StopListening(const uno::Reference< lang::XComponent >& xComp) 107 { 108 if (xComp.is()) 109 xComp->removeEventListener(this); 110 } 111 112 void SdrControlEventListenerImpl::StartListening(const uno::Reference< lang::XComponent >& xComp) 113 { 114 if (xComp.is()) 115 xComp->addEventListener(this); 116 } 117 118 // ============================================================================= 119 struct SAL_DLLPRIVATE SdrUnoObjDataHolder 120 { 121 mutable ::rtl::Reference< SdrControlEventListenerImpl > 122 pEventListener; 123 }; 124 125 // ============================================================================= 126 namespace 127 { 128 void lcl_ensureControlVisibility( SdrView* _pView, const SdrUnoObj* _pObject, bool _bVisible ) 129 { 130 OSL_PRECOND( _pObject, "lcl_ensureControlVisibility: no object -> no survival!" ); 131 132 SdrPageView* pPageView = _pView ? _pView->GetSdrPageView() : NULL; 133 DBG_ASSERT( pPageView, "lcl_ensureControlVisibility: no view found!" ); 134 if ( !pPageView ) 135 return; 136 137 ViewContact& rUnoControlContact( _pObject->GetViewContact() ); 138 139 for ( sal_uInt32 i = 0; i < pPageView->PageWindowCount(); ++i ) 140 { 141 const SdrPageWindow* pPageWindow = pPageView->GetPageWindow( i ); 142 DBG_ASSERT( pPageWindow, "lcl_ensureControlVisibility: invalid PageViewWindow!" ); 143 if ( !pPageWindow ) 144 continue; 145 146 if ( !pPageWindow->HasObjectContact() ) 147 continue; 148 149 ObjectContact& rPageViewContact( pPageWindow->GetObjectContact() ); 150 const ViewObjectContact& rViewObjectContact( rUnoControlContact.GetViewObjectContact( rPageViewContact ) ); 151 const ViewObjectContactOfUnoControl* pUnoControlContact = dynamic_cast< const ViewObjectContactOfUnoControl* >( &rViewObjectContact ); 152 DBG_ASSERT( pUnoControlContact, "lcl_ensureControlVisibility: wrong ViewObjectContact type!" ); 153 if ( !pUnoControlContact ) 154 continue; 155 156 pUnoControlContact->ensureControlVisibility( _bVisible ); 157 } 158 } 159 } 160 161 //************************************************************ 162 // SdrUnoObj 163 //************************************************************ 164 165 TYPEINIT1(SdrUnoObj, SdrRectObj); 166 167 SdrUnoObj::SdrUnoObj(const String& rModelName, sal_Bool _bOwnUnoControlModel) 168 : m_pImpl( new SdrUnoObjDataHolder ), 169 bOwnUnoControlModel( _bOwnUnoControlModel ) 170 { 171 bIsUnoObj = sal_True; 172 173 m_pImpl->pEventListener = new SdrControlEventListenerImpl(this); 174 175 // nur ein owner darf eigenstaendig erzeugen 176 if (rModelName.Len()) 177 CreateUnoControlModel(rModelName); 178 } 179 180 SdrUnoObj::SdrUnoObj(const String& rModelName, 181 const uno::Reference< lang::XMultiServiceFactory >& rxSFac, 182 sal_Bool _bOwnUnoControlModel) 183 : m_pImpl( new SdrUnoObjDataHolder ), 184 bOwnUnoControlModel( _bOwnUnoControlModel ) 185 { 186 bIsUnoObj = sal_True; 187 188 m_pImpl->pEventListener = new SdrControlEventListenerImpl(this); 189 190 // nur ein owner darf eigenstaendig erzeugen 191 if (rModelName.Len()) 192 CreateUnoControlModel(rModelName,rxSFac); 193 } 194 195 SdrUnoObj::~SdrUnoObj() 196 { 197 try 198 { 199 // clean up the control model 200 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY); 201 if (xComp.is()) 202 { 203 // is the control model owned by it's environment? 204 uno::Reference< container::XChild > xContent(xUnoControlModel, uno::UNO_QUERY); 205 if (xContent.is() && !xContent->getParent().is()) 206 xComp->dispose(); 207 else 208 m_pImpl->pEventListener->StopListening(xComp); 209 } 210 } 211 catch( const uno::Exception& ) 212 { 213 OSL_ENSURE( sal_False, "SdrUnoObj::~SdrUnoObj: caught an exception!" ); 214 } 215 delete m_pImpl; 216 } 217 218 void SdrUnoObj::SetModel(SdrModel* pNewModel) 219 { 220 SdrRectObj::SetModel(pNewModel); 221 } 222 223 void SdrUnoObj::SetPage(SdrPage* pNewPage) 224 { 225 SdrRectObj::SetPage(pNewPage); 226 } 227 228 void SdrUnoObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const 229 { 230 rInfo.bRotateFreeAllowed = sal_False; 231 rInfo.bRotate90Allowed = sal_False; 232 rInfo.bMirrorFreeAllowed = sal_False; 233 rInfo.bMirror45Allowed = sal_False; 234 rInfo.bMirror90Allowed = sal_False; 235 rInfo.bTransparenceAllowed = sal_False; 236 rInfo.bGradientAllowed = sal_False; 237 rInfo.bShearAllowed = sal_False; 238 rInfo.bEdgeRadiusAllowed = sal_False; 239 rInfo.bNoOrthoDesired = sal_False; 240 rInfo.bCanConvToPath = sal_False; 241 rInfo.bCanConvToPoly = sal_False; 242 rInfo.bCanConvToPathLineToArea = sal_False; 243 rInfo.bCanConvToPolyLineToArea = sal_False; 244 rInfo.bCanConvToContour = sal_False; 245 } 246 247 sal_uInt16 SdrUnoObj::GetObjIdentifier() const 248 { 249 return sal_uInt16(OBJ_UNO); 250 } 251 252 void SdrUnoObj::SetContextWritingMode( const sal_Int16 _nContextWritingMode ) 253 { 254 try 255 { 256 uno::Reference< beans::XPropertySet > xModelProperties( GetUnoControlModel(), uno::UNO_QUERY_THROW ); 257 xModelProperties->setPropertyValue( 258 ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "ContextWritingMode" ) ), 259 uno::makeAny( _nContextWritingMode ) 260 ); 261 } 262 catch( const uno::Exception& ) 263 { 264 DBG_UNHANDLED_EXCEPTION(); 265 } 266 } 267 268 // ---------------------------------------------------------------------------- 269 namespace 270 { 271 /** helper class to restore graphics at <awt::XView> object after <SdrUnoObj::Paint> 272 273 OD 08.05.2003 #109432# 274 Restoration of graphics necessary to assure that paint on a window 275 276 @author OD 277 */ 278 class RestoreXViewGraphics 279 { 280 private: 281 uno::Reference< awt::XView > m_rXView; 282 uno::Reference< awt::XGraphics > m_rXGraphics; 283 284 public: 285 RestoreXViewGraphics( const uno::Reference< awt::XView >& _rXView ) 286 { 287 m_rXView = _rXView; 288 m_rXGraphics = m_rXView->getGraphics(); 289 } 290 ~RestoreXViewGraphics() 291 { 292 m_rXView->setGraphics( m_rXGraphics ); 293 } 294 }; 295 } 296 297 void SdrUnoObj::TakeObjNameSingul(XubString& rName) const 298 { 299 rName = ImpGetResStr(STR_ObjNameSingulUno); 300 301 String aName( GetName() ); 302 if(aName.Len()) 303 { 304 rName += sal_Unicode(' '); 305 rName += sal_Unicode('\''); 306 rName += aName; 307 rName += sal_Unicode('\''); 308 } 309 } 310 311 void SdrUnoObj::TakeObjNamePlural(XubString& rName) const 312 { 313 rName = ImpGetResStr(STR_ObjNamePluralUno); 314 } 315 316 void SdrUnoObj::operator = (const SdrObject& rObj) 317 { 318 SdrRectObj::operator = (rObj); 319 320 // release the reference to the current control model 321 SetUnoControlModel( NULL ); 322 323 const SdrUnoObj& rUnoObj = dynamic_cast< const SdrUnoObj& >( rObj ); 324 325 aUnoControlModelTypeName = rUnoObj.aUnoControlModelTypeName; 326 aUnoControlTypeName = rUnoObj.aUnoControlTypeName; 327 328 // copy the uno control model 329 const uno::Reference< awt::XControlModel > xSourceControlModel( rUnoObj.GetUnoControlModel(), uno::UNO_QUERY ); 330 if ( xSourceControlModel.is() ) 331 { 332 try 333 { 334 uno::Reference< util::XCloneable > xClone( xSourceControlModel, uno::UNO_QUERY_THROW ); 335 xUnoControlModel.set( xClone->createClone(), uno::UNO_QUERY_THROW ); 336 } 337 catch( const uno::Exception& ) 338 { 339 DBG_UNHANDLED_EXCEPTION(); 340 } 341 } 342 343 // get service name of the control from the control model 344 uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY); 345 if (xSet.is()) 346 { 347 uno::Any aValue( xSet->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl")) ); 348 ::rtl::OUString aStr; 349 350 if( aValue >>= aStr ) 351 aUnoControlTypeName = String(aStr); 352 } 353 354 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY); 355 if (xComp.is()) 356 m_pImpl->pEventListener->StartListening(xComp); 357 } 358 359 void SdrUnoObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) 360 { 361 SdrRectObj::NbcResize(rRef,xFact,yFact); 362 363 if (aGeo.nShearWink!=0 || aGeo.nDrehWink!=0) 364 { 365 // kleine Korrekturen 366 if (aGeo.nDrehWink>=9000 && aGeo.nDrehWink<27000) 367 { 368 aRect.Move(aRect.Left()-aRect.Right(),aRect.Top()-aRect.Bottom()); 369 } 370 371 aGeo.nDrehWink = 0; 372 aGeo.nShearWink = 0; 373 aGeo.nSin = 0.0; 374 aGeo.nCos = 1.0; 375 aGeo.nTan = 0.0; 376 SetRectsDirty(); 377 } 378 } 379 380 // ----------------------------------------------------------------------------- 381 382 bool SdrUnoObj::hasSpecialDrag() const 383 { 384 // no special drag; we have no rounding rect and 385 // do want frame handles 386 return false; 387 } 388 389 bool SdrUnoObj::supportsFullDrag() const 390 { 391 // overloaded to have the possibility to enable/disable in debug and 392 // to ckeck some things out. Current solution is working, so default is 393 // enabled 394 static bool bDoSupportFullDrag(true); 395 396 return bDoSupportFullDrag; 397 } 398 399 SdrObject* SdrUnoObj::getFullDragClone() const 400 { 401 SdrObject* pRetval = 0; 402 static bool bHandleSpecial(false); 403 404 if(bHandleSpecial) 405 { 406 // special handling for SdrUnoObj (FormControl). Create a SdrGrafObj 407 // for drag containing the graphical representation. This does not work too 408 // well, so the default is to simply clone 409 pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect()); 410 } 411 else 412 { 413 // call parent (simply clone) 414 pRetval = SdrRectObj::getFullDragClone(); 415 } 416 417 return pRetval; 418 } 419 420 // ----------------------------------------------------------------------------- 421 void SdrUnoObj::NbcSetLayer( SdrLayerID _nLayer ) 422 { 423 if ( GetLayer() == _nLayer ) 424 { // redundant call -> not interested in doing anything here 425 SdrRectObj::NbcSetLayer( _nLayer ); 426 return; 427 } 428 429 // we need some special handling here in case we're moved from an invisible layer 430 // to a visible one, or vice versa 431 // (relative to a layer. Remember that the visibility of a layer is a view attribute 432 // - the same layer can be visible in one view, and invisible in another view, at the 433 // same time) 434 // 2003-06-03 - #110592# - fs@openoffice.org 435 436 // collect all views in which our old layer is visible 437 ::std::set< SdrView* > aPreviouslyVisible; 438 439 { 440 SdrViewIter aIter( this ); 441 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() ) 442 aPreviouslyVisible.insert( pView ); 443 } 444 445 SdrRectObj::NbcSetLayer( _nLayer ); 446 447 // collect all views in which our new layer is visible 448 ::std::set< SdrView* > aNewlyVisible; 449 450 { 451 SdrViewIter aIter( this ); 452 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() ) 453 { 454 ::std::set< SdrView* >::const_iterator aPrevPos = aPreviouslyVisible.find( pView ); 455 if ( aPreviouslyVisible.end() != aPrevPos ) 456 { // in pView, we were visible _before_ the layer change, and are 457 // visible _after_ the layer change, too 458 // -> we're not interested in this view at all 459 aPreviouslyVisible.erase( aPrevPos ); 460 } 461 else 462 { 463 // in pView, we were visible _before_ the layer change, and are 464 // _not_ visible after the layer change 465 // => remember this view, as our visibility there changed 466 aNewlyVisible.insert( pView ); 467 } 468 } 469 } 470 471 // now aPreviouslyVisible contains all views where we became invisible 472 ::std::set< SdrView* >::const_iterator aLoopViews; 473 for ( aLoopViews = aPreviouslyVisible.begin(); 474 aLoopViews != aPreviouslyVisible.end(); 475 ++aLoopViews 476 ) 477 { 478 lcl_ensureControlVisibility( *aLoopViews, this, false ); 479 } 480 481 // and aNewlyVisible all views where we became visible 482 for ( aLoopViews = aNewlyVisible.begin(); 483 aLoopViews != aNewlyVisible.end(); 484 ++aLoopViews 485 ) 486 { 487 lcl_ensureControlVisibility( *aLoopViews, this, true ); 488 } 489 } 490 491 void SdrUnoObj::CreateUnoControlModel(const String& rModelName) 492 { 493 DBG_ASSERT(!xUnoControlModel.is(), "model already exists"); 494 495 aUnoControlModelTypeName = rModelName; 496 497 uno::Reference< awt::XControlModel > xModel; 498 uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 499 if (aUnoControlModelTypeName.Len() && xFactory.is() ) 500 { 501 xModel = uno::Reference< awt::XControlModel >(xFactory->createInstance( 502 aUnoControlModelTypeName), uno::UNO_QUERY); 503 504 if (xModel.is()) 505 SetChanged(); 506 } 507 508 SetUnoControlModel(xModel); 509 } 510 511 void SdrUnoObj::CreateUnoControlModel(const String& rModelName, 512 const uno::Reference< lang::XMultiServiceFactory >& rxSFac) 513 { 514 DBG_ASSERT(!xUnoControlModel.is(), "model already exists"); 515 516 aUnoControlModelTypeName = rModelName; 517 518 uno::Reference< awt::XControlModel > xModel; 519 if (aUnoControlModelTypeName.Len() && rxSFac.is() ) 520 { 521 xModel = uno::Reference< awt::XControlModel >(rxSFac->createInstance( 522 aUnoControlModelTypeName), uno::UNO_QUERY); 523 524 if (xModel.is()) 525 SetChanged(); 526 } 527 528 SetUnoControlModel(xModel); 529 } 530 531 void SdrUnoObj::SetUnoControlModel( const uno::Reference< awt::XControlModel >& xModel) 532 { 533 if (xUnoControlModel.is()) 534 { 535 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY); 536 if (xComp.is()) 537 m_pImpl->pEventListener->StopListening(xComp); 538 } 539 540 xUnoControlModel = xModel; 541 542 // control model muss servicename des controls enthalten 543 if (xUnoControlModel.is()) 544 { 545 uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY); 546 if (xSet.is()) 547 { 548 uno::Any aValue( xSet->getPropertyValue(String("DefaultControl", gsl_getSystemTextEncoding())) ); 549 ::rtl::OUString aStr; 550 if( aValue >>= aStr ) 551 aUnoControlTypeName = String(aStr); 552 } 553 554 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY); 555 if (xComp.is()) 556 m_pImpl->pEventListener->StartListening(xComp); 557 } 558 559 // invalidate all ViewObject contacts 560 ViewContactOfUnoControl* pVC = NULL; 561 if ( impl_getViewContact( pVC ) ) 562 { 563 // flushViewObjectContacts() removes all existing VOCs for the local DrawHierarchy. This 564 // is always allowed since they will be re-created on demand (and with the changed model) 565 GetViewContact().flushViewObjectContacts(true); 566 } 567 } 568 569 //------------------------------------------------------------------------ 570 uno::Reference< awt::XControl > SdrUnoObj::GetUnoControl(const SdrView& _rView, const OutputDevice& _rOut) const 571 { 572 uno::Reference< awt::XControl > xControl; 573 574 SdrPageView* pPageView = _rView.GetSdrPageView(); 575 OSL_ENSURE( GetPage() == pPageView->GetPage(), "SdrUnoObj::GetUnoControl: This object is not displayed in that particular view!" ); 576 if ( GetPage() != pPageView->GetPage() ) 577 return NULL; 578 579 SdrPageWindow* pPageWindow = pPageView ? pPageView->FindPageWindow( _rOut ) : NULL; 580 OSL_ENSURE( pPageWindow, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" ); 581 if ( !pPageWindow ) 582 return NULL; 583 584 ViewObjectContact& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow->GetObjectContact() ) ); 585 ViewObjectContactOfUnoControl* pUnoContact = dynamic_cast< ViewObjectContactOfUnoControl* >( &rViewObjectContact ); 586 OSL_ENSURE( pUnoContact, "SdrUnoObj::GetUnoControl: wrong contact type!" ); 587 if ( pUnoContact ) 588 xControl = pUnoContact->getControl(); 589 590 return xControl; 591 } 592 593 //------------------------------------------------------------------------ 594 uno::Reference< awt::XControl > SdrUnoObj::GetTemporaryControlForWindow( 595 const Window& _rWindow, uno::Reference< awt::XControlContainer >& _inout_ControlContainer ) const 596 { 597 uno::Reference< awt::XControl > xControl; 598 599 ViewContactOfUnoControl* pVC = NULL; 600 if ( impl_getViewContact( pVC ) ) 601 xControl = pVC->getTemporaryControlForWindow( _rWindow, _inout_ControlContainer ); 602 603 return xControl; 604 } 605 606 //------------------------------------------------------------------------ 607 bool SdrUnoObj::impl_getViewContact( ViewContactOfUnoControl*& _out_rpContact ) const 608 { 609 ViewContact& rViewContact( GetViewContact() ); 610 _out_rpContact = dynamic_cast< ViewContactOfUnoControl* >( &rViewContact ); 611 DBG_ASSERT( _out_rpContact, "SdrUnoObj::impl_getViewContact: could not find my ViewContact!" ); 612 return ( _out_rpContact != NULL ); 613 } 614 615 //------------------------------------------------------------------------ 616 ::sdr::contact::ViewContact* SdrUnoObj::CreateObjectSpecificViewContact() 617 { 618 return new ::sdr::contact::ViewContactOfUnoControl( *this ); 619 } 620 621 // ----------------------------------------------------------------------------- 622 // eof 623