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