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