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_toolkit.hxx" 30 #include <com/sun/star/awt/XControlContainer.hpp> 31 #include <com/sun/star/awt/WindowAttribute.hpp> 32 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp> 33 #include <com/sun/star/awt/PosSize.hpp> 34 #ifndef _COM_SUN_STAR_LAN_XMULTISERVICEFACTORY_HPP_ 35 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 36 #endif 37 #include <com/sun/star/beans/PropertyValue.hpp> 38 #include <com/sun/star/resource/XStringResourceResolver.hpp> 39 #include <toolkit/controls/unocontrol.hxx> 40 #include <toolkit/helper/vclunohelper.hxx> 41 #include <cppuhelper/typeprovider.hxx> 42 #include <rtl/memory.h> 43 #include <rtl/uuid.h> 44 #include <vos/mutex.hxx> 45 #include <tools/string.hxx> 46 #include <tools/table.hxx> 47 #include <tools/date.hxx> 48 #include <tools/time.hxx> 49 #include <tools/urlobj.hxx> 50 #include <tools/debug.hxx> 51 #include <tools/diagnose_ex.h> 52 #include <vcl/svapp.hxx> 53 #include <vcl/wrkwin.hxx> 54 #include <comphelper/stl_types.hxx> 55 #include <comphelper/processfactory.hxx> 56 #include <toolkit/helper/property.hxx> 57 #include <toolkit/helper/servicenames.hxx> 58 #include <toolkit/helper/vclunohelper.hxx> 59 #include <toolkit/awt/vclxwindow.hxx> 60 #include <vcl/svapp.hxx> 61 #include <vos/mutex.hxx> 62 #include <toolkit/controls/accessiblecontrolcontext.hxx> 63 #include <comphelper/container.hxx> 64 65 #include <algorithm> 66 #include <set> 67 68 using namespace ::com::sun::star; 69 using namespace ::com::sun::star::uno; 70 using namespace ::com::sun::star::awt; 71 using namespace ::com::sun::star::beans; 72 using namespace ::com::sun::star::lang; 73 using namespace ::com::sun::star::util; 74 75 using ::com::sun::star::accessibility::XAccessibleContext; 76 using ::com::sun::star::accessibility::XAccessible; 77 78 struct LanguageDependentProp 79 { 80 const char* pPropName; 81 sal_Int32 nPropNameLength; 82 }; 83 84 static const LanguageDependentProp aLanguageDependentProp[] = 85 { 86 { "Text", 4 }, 87 { "Label", 5 }, 88 { "Title", 5 }, 89 { "HelpText", 8 }, 90 { "CurrencySymbol", 14 }, 91 { "StringItemList", 14 }, 92 { 0, 0 } 93 }; 94 95 static Sequence< ::rtl::OUString> lcl_ImplGetPropertyNames( const Reference< XMultiPropertySet > & rxModel ) 96 { 97 Sequence< ::rtl::OUString> aNames; 98 Reference< XPropertySetInfo > xPSInf = rxModel->getPropertySetInfo(); 99 DBG_ASSERT( xPSInf.is(), "UpdateFromModel: No PropertySetInfo!" ); 100 if ( xPSInf.is() ) 101 { 102 Sequence< Property> aProps = xPSInf->getProperties(); 103 sal_Int32 nLen = aProps.getLength(); 104 aNames = Sequence< ::rtl::OUString>( nLen ); 105 ::rtl::OUString* pNames = aNames.getArray(); 106 const Property* pProps = aProps.getConstArray(); 107 for ( sal_Int32 n = 0; n < nLen; ++n, ++pProps, ++pNames) 108 *pNames = pProps->Name; 109 } 110 return aNames; 111 } 112 113 // ==================================================== 114 class VclListenerLock 115 { 116 private: 117 VCLXWindow* m_pLockWindow; 118 119 public: 120 inline VclListenerLock( VCLXWindow* _pLockWindow ) 121 :m_pLockWindow( _pLockWindow ) 122 { 123 if ( m_pLockWindow ) 124 m_pLockWindow->suspendVclEventListening( ); 125 } 126 inline ~VclListenerLock( ) 127 { 128 if ( m_pLockWindow ) 129 m_pLockWindow->resumeVclEventListening( ); 130 } 131 132 private: 133 VclListenerLock(); // never implemented 134 VclListenerLock( const VclListenerLock& ); // never implemented 135 VclListenerLock& operator=( const VclListenerLock& ); // never implemented 136 }; 137 138 typedef ::std::map< ::rtl::OUString, sal_Int32 > MapString2Int; 139 struct UnoControl_Data 140 { 141 MapString2Int aSuspendedPropertyNotifications; 142 /// true if and only if our model has a property ResourceResolver 143 bool bLocalizationSupport; 144 145 UnoControl_Data() 146 :aSuspendedPropertyNotifications() 147 ,bLocalizationSupport( false ) 148 { 149 } 150 }; 151 152 // ---------------------------------------------------- 153 // class UnoControl 154 // ---------------------------------------------------- 155 DBG_NAME( UnoControl ) 156 UnoControl::UnoControl() 157 :maContext( ::comphelper::getProcessServiceFactory() ) 158 ,maDisposeListeners( *this ) 159 ,maWindowListeners( *this ) 160 ,maFocusListeners( *this ) 161 ,maKeyListeners( *this ) 162 ,maMouseListeners( *this ) 163 ,maMouseMotionListeners( *this ) 164 ,maPaintListeners( *this ) 165 ,maModeChangeListeners( GetMutex() ) 166 ,mpData( new UnoControl_Data ) 167 { 168 DBG_CTOR( UnoControl, NULL ); 169 OSL_ENSURE( false, "UnoControl::UnoControl: not implemented. Well, not really." ); 170 // just implemented to let the various FooImplInheritanceHelper compile, you should use the 171 // version taking a service factory 172 } 173 174 UnoControl::UnoControl( const Reference< XMultiServiceFactory >& i_factory ) 175 : maContext( i_factory ) 176 , maDisposeListeners( *this ) 177 , maWindowListeners( *this ) 178 , maFocusListeners( *this ) 179 , maKeyListeners( *this ) 180 , maMouseListeners( *this ) 181 , maMouseMotionListeners( *this ) 182 , maPaintListeners( *this ) 183 , maModeChangeListeners( GetMutex() ) 184 , mpData( new UnoControl_Data ) 185 { 186 DBG_CTOR( UnoControl, NULL ); 187 mbDisposePeer = sal_True; 188 mbRefeshingPeer = sal_False; 189 mbCreatingPeer = sal_False; 190 mbCreatingCompatiblePeer = sal_False; 191 mbDesignMode = sal_False; 192 } 193 194 UnoControl::~UnoControl() 195 { 196 DELETEZ( mpData ); 197 DBG_DTOR( UnoControl, NULL ); 198 } 199 200 ::rtl::OUString UnoControl::GetComponentServiceName() 201 { 202 return ::rtl::OUString(); 203 } 204 205 Reference< XWindowPeer > UnoControl::ImplGetCompatiblePeer( sal_Bool bAcceptExistingPeer ) 206 { 207 DBG_ASSERT( !mbCreatingCompatiblePeer, "ImplGetCompatiblePeer - rekursive?" ); 208 209 mbCreatingCompatiblePeer = sal_True; 210 211 Reference< XWindowPeer > xCompatiblePeer; 212 213 if ( bAcceptExistingPeer ) 214 xCompatiblePeer = getPeer(); 215 216 if ( !xCompatiblePeer.is() ) 217 { 218 // Peer unsichtbar erzeugen... 219 sal_Bool bVis = maComponentInfos.bVisible; 220 if( bVis ) 221 maComponentInfos.bVisible = sal_False; 222 223 Reference< XWindowPeer > xCurrentPeer = getPeer(); 224 setPeer( NULL ); 225 226 // queryInterface ourself, to allow aggregation 227 Reference< XControl > xMe; 228 OWeakAggObject::queryInterface( ::getCppuType( &xMe ) ) >>= xMe; 229 230 Window* pParentWindow( NULL ); 231 { 232 osl::Guard< vos::IMutex > aGuard( Application::GetSolarMutex() ); 233 pParentWindow = dynamic_cast< Window* >( Application::GetDefaultDevice() ); 234 ENSURE_OR_THROW( pParentWindow != NULL, "could obtain a default parent window!" ); 235 } 236 try 237 { 238 xMe->createPeer( NULL, pParentWindow->GetComponentInterface( sal_True ) ); 239 } 240 catch( const Exception& ) 241 { 242 mbCreatingCompatiblePeer = sal_False; 243 throw; 244 } 245 xCompatiblePeer = getPeer(); 246 setPeer( xCurrentPeer ); 247 248 if ( xCompatiblePeer.is() && mxGraphics.is() ) 249 { 250 Reference< XView > xPeerView( xCompatiblePeer, UNO_QUERY ); 251 if ( xPeerView.is() ) 252 xPeerView->setGraphics( mxGraphics ); 253 } 254 255 if( bVis ) 256 maComponentInfos.bVisible = sal_True; 257 } 258 259 mbCreatingCompatiblePeer = sal_False; 260 261 return xCompatiblePeer; 262 } 263 264 bool UnoControl::ImplCheckLocalize( ::rtl::OUString& _rPossiblyLocalizable ) 265 { 266 if ( !mpData->bLocalizationSupport 267 || ( _rPossiblyLocalizable.getLength() == 0 ) 268 || ( _rPossiblyLocalizable[0] != '&' ) 269 // TODO: make this reasonable. At the moment, everything which by accident starts with a & is considered 270 // localizable, which is probably wrong. 271 ) 272 return false; 273 274 try 275 { 276 Reference< XPropertySet > xPropSet( mxModel, UNO_QUERY_THROW ); 277 Reference< resource::XStringResourceResolver > xStringResourceResolver( 278 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ), 279 UNO_QUERY 280 ); 281 if ( xStringResourceResolver.is() ) 282 { 283 ::rtl::OUString aLocalizationKey( _rPossiblyLocalizable.copy( 1 ) ); 284 _rPossiblyLocalizable = xStringResourceResolver->resolveString( aLocalizationKey ); 285 return true; 286 } 287 } 288 catch( const Exception& ) 289 { 290 DBG_UNHANDLED_EXCEPTION(); 291 } 292 return false; 293 } 294 295 void UnoControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal ) 296 { 297 // since a change made in propertiesChange, we can't be sure that this is called with an valid getPeer(), 298 // this assumption may be false in some (seldom) multi-threading scenarios (cause propertiesChange 299 // releases our mutex before calling here in) 300 // That's why this additional check 301 302 if ( mxVclWindowPeer.is() ) 303 { 304 Any aConvertedValue( rVal ); 305 306 if ( mpData->bLocalizationSupport ) 307 { 308 // We now support a mapping for language dependent properties. This is the 309 // central method to implement it. 310 if (( rPropName.equalsAsciiL( "Text", 4 )) || 311 ( rPropName.equalsAsciiL( "Label", 5 )) || 312 ( rPropName.equalsAsciiL( "Title", 5 )) || 313 ( rPropName.equalsAsciiL( "HelpText", 8 )) || 314 ( rPropName.equalsAsciiL( "CurrencySymbol", 14 )) || 315 ( rPropName.equalsAsciiL( "StringItemList", 14 )) ) 316 { 317 ::rtl::OUString aValue; 318 uno::Sequence< rtl::OUString > aSeqValue; 319 if ( aConvertedValue >>= aValue ) 320 { 321 if ( ImplCheckLocalize( aValue ) ) 322 aConvertedValue <<= aValue; 323 } 324 else if ( aConvertedValue >>= aSeqValue ) 325 { 326 for ( sal_Int32 i = 0; i < aSeqValue.getLength(); i++ ) 327 ImplCheckLocalize( aSeqValue[i] ); 328 aConvertedValue <<= aSeqValue; 329 } 330 } 331 } 332 333 mxVclWindowPeer->setProperty( rPropName, aConvertedValue ); 334 } 335 } 336 337 void UnoControl::PrepareWindowDescriptor( WindowDescriptor& ) 338 { 339 } 340 341 Reference< XWindow > UnoControl::getParentPeer() const 342 { 343 Reference< XWindow > xPeer; 344 if( mxContext.is() ) 345 { 346 Reference< XControl > xContComp( mxContext, UNO_QUERY ); 347 if ( xContComp.is() ) 348 { 349 Reference< XWindowPeer > xP = xContComp->getPeer(); 350 if ( xP.is() ) 351 xP->queryInterface( ::getCppuType((const Reference< XWindow >*)0) ) >>= xPeer; 352 } 353 } 354 return xPeer; 355 } 356 357 void UnoControl::updateFromModel() 358 { 359 // Alle standard Properties werden ausgelesen und in das Peer uebertragen 360 if( getPeer().is() ) 361 { 362 Reference< XMultiPropertySet > xPropSet( mxModel, UNO_QUERY ); 363 if( xPropSet.is() ) 364 { 365 Sequence< ::rtl::OUString> aNames = lcl_ImplGetPropertyNames( xPropSet ); 366 xPropSet->firePropertiesChangeEvent( aNames, this ); 367 } 368 } 369 } 370 371 372 // XTypeProvider 373 IMPL_IMPLEMENTATION_ID( UnoControl ) 374 375 void UnoControl::disposeAccessibleContext() 376 { 377 Reference< XComponent > xContextComp( maAccessibleContext.get(), UNO_QUERY ); 378 if ( xContextComp.is() ) 379 { 380 maAccessibleContext = NULL; 381 try 382 { 383 xContextComp->removeEventListener( this ); 384 xContextComp->dispose(); 385 } 386 catch( const Exception& ) 387 { 388 DBG_ERROR( "UnoControl::disposeAccessibleContext: could not dispose my AccessibleContext!" ); 389 } 390 } 391 } 392 393 void UnoControl::dispose( ) throw(RuntimeException) 394 { 395 Reference< XWindowPeer > xPeer; 396 { 397 ::osl::MutexGuard aGuard( GetMutex() ); 398 if( mbDisposePeer ) 399 { 400 xPeer = mxPeer; 401 } 402 setPeer( NULL ); 403 } 404 if( xPeer.is() ) 405 { 406 xPeer->dispose(); 407 } 408 409 // dispose and release our AccessibleContext 410 disposeAccessibleContext(); 411 412 EventObject aDisposeEvent; 413 aDisposeEvent.Source = static_cast< XAggregation* >( this ); 414 415 maDisposeListeners.disposeAndClear( aDisposeEvent ); 416 maWindowListeners.disposeAndClear( aDisposeEvent ); 417 maFocusListeners.disposeAndClear( aDisposeEvent ); 418 maKeyListeners.disposeAndClear( aDisposeEvent ); 419 maMouseListeners.disposeAndClear( aDisposeEvent ); 420 maMouseMotionListeners.disposeAndClear( aDisposeEvent ); 421 maPaintListeners.disposeAndClear( aDisposeEvent ); 422 maModeChangeListeners.disposeAndClear( aDisposeEvent ); 423 424 // Model wieder freigeben 425 setModel( Reference< XControlModel > () ); 426 setContext( Reference< XInterface > () ); 427 } 428 429 void UnoControl::addEventListener( const Reference< XEventListener >& rxListener ) throw(RuntimeException) 430 { 431 ::osl::MutexGuard aGuard( GetMutex() ); 432 433 maDisposeListeners.addInterface( rxListener ); 434 } 435 436 void UnoControl::removeEventListener( const Reference< XEventListener >& rxListener ) throw(RuntimeException) 437 { 438 ::osl::MutexGuard aGuard( GetMutex() ); 439 440 maDisposeListeners.removeInterface( rxListener ); 441 } 442 443 sal_Bool UnoControl::requiresNewPeer( const ::rtl::OUString& /* _rPropertyName */ ) const 444 { 445 return sal_False; 446 } 447 448 // XPropertiesChangeListener 449 void UnoControl::propertiesChange( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException) 450 { 451 Sequence< PropertyChangeEvent > aEvents( rEvents ); 452 { 453 ::osl::MutexGuard aGuard( GetMutex() ); 454 455 if ( !mpData->aSuspendedPropertyNotifications.empty() ) 456 { 457 // strip the property which we are currently updating (somewhere up the stack) 458 PropertyChangeEvent* pEvents = aEvents.getArray(); 459 PropertyChangeEvent* pEventsEnd = pEvents + aEvents.getLength(); 460 for ( ; pEvents < pEventsEnd; ) 461 if ( mpData->aSuspendedPropertyNotifications.find( pEvents->PropertyName ) != mpData->aSuspendedPropertyNotifications.end() ) 462 { 463 if ( pEvents != pEventsEnd ) 464 ::std::copy( pEvents + 1, pEventsEnd, pEvents ); 465 --pEventsEnd; 466 } 467 else 468 ++pEvents; 469 aEvents.realloc( pEventsEnd - aEvents.getConstArray() ); 470 471 if ( !aEvents.getLength() ) 472 return; 473 } 474 } 475 476 ImplModelPropertiesChanged( aEvents ); 477 } 478 479 void UnoControl::ImplLockPropertyChangeNotification( const ::rtl::OUString& rPropertyName, bool bLock ) 480 { 481 MapString2Int::iterator pos = mpData->aSuspendedPropertyNotifications.find( rPropertyName ); 482 if ( bLock ) 483 { 484 if ( pos == mpData->aSuspendedPropertyNotifications.end() ) 485 pos = mpData->aSuspendedPropertyNotifications.insert( MapString2Int::value_type( rPropertyName, 0 ) ).first; 486 ++pos->second; 487 } 488 else 489 { 490 OSL_ENSURE( pos != mpData->aSuspendedPropertyNotifications.end(), "UnoControl::ImplLockPropertyChangeNotification: property not locked!" ); 491 if ( pos != mpData->aSuspendedPropertyNotifications.end() ) 492 { 493 OSL_ENSURE( pos->second > 0, "UnoControl::ImplLockPropertyChangeNotification: invalid suspension counter!" ); 494 if ( 0 == --pos->second ) 495 mpData->aSuspendedPropertyNotifications.erase( pos ); 496 } 497 } 498 } 499 500 void UnoControl::ImplLockPropertyChangeNotifications( const Sequence< ::rtl::OUString >& rPropertyNames, bool bLock ) 501 { 502 for ( const ::rtl::OUString* pPropertyName = rPropertyNames.getConstArray(); 503 pPropertyName != rPropertyNames.getConstArray() + rPropertyNames.getLength(); 504 ++pPropertyName 505 ) 506 ImplLockPropertyChangeNotification( *pPropertyName, bLock ); 507 } 508 509 void UnoControl::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) 510 { 511 ::osl::ClearableGuard< ::osl::Mutex > aGuard( GetMutex() ); 512 513 if( getPeer().is() ) 514 { 515 DECLARE_STL_VECTOR( PropertyValue, PropertyValueVector); 516 PropertyValueVector aPeerPropertiesToSet; 517 sal_Int32 nIndependentPos = 0; 518 bool bResourceResolverSet( false ); 519 // position where to insert the independent properties into aPeerPropertiesToSet, 520 // dependent ones are inserted at the end of the vector 521 522 sal_Bool bNeedNewPeer = sal_False; 523 // some properties require a re-creation of the peer, 'cause they can't be changed on the fly 524 525 Reference< XControlModel > xOwnModel( getModel(), UNO_QUERY ); 526 // our own model for comparison 527 Reference< XPropertySet > xPS( xOwnModel, UNO_QUERY ); 528 Reference< XPropertySetInfo > xPSI( xPS->getPropertySetInfo(), UNO_QUERY ); 529 OSL_ENSURE( xPSI.is(), "UnoControl::ImplModelPropertiesChanged: should have property set meta data!" ); 530 531 const PropertyChangeEvent* pEvents = rEvents.getConstArray(); 532 533 sal_Int32 nLen = rEvents.getLength(); 534 aPeerPropertiesToSet.reserve(nLen); 535 536 for( sal_Int32 i = 0; i < nLen; ++i, ++pEvents ) 537 { 538 Reference< XControlModel > xModel( pEvents->Source, UNO_QUERY ); 539 sal_Bool bOwnModel = xModel.get() == xOwnModel.get(); 540 if ( !bOwnModel ) 541 continue; 542 543 // Detect changes on our resource resolver which invalidates 544 // automatically some language dependent properties. 545 if ( pEvents->PropertyName.equalsAsciiL( "ResourceResolver", 16 )) 546 { 547 Reference< resource::XStringResourceResolver > xStrResolver; 548 if ( pEvents->NewValue >>= xStrResolver ) 549 bResourceResolverSet = xStrResolver.is(); 550 } 551 552 sal_uInt16 nPType = GetPropertyId( pEvents->PropertyName ); 553 if ( mbDesignMode && mbDisposePeer && !mbRefeshingPeer && !mbCreatingPeer ) 554 { 555 // if we're in design mode, then some properties can change which 556 // require creating a *new* peer (since these properties cannot 557 // be switched at existing peers) 558 if ( nPType ) 559 bNeedNewPeer = ( nPType == BASEPROPERTY_BORDER ) 560 || ( nPType == BASEPROPERTY_MULTILINE ) 561 || ( nPType == BASEPROPERTY_DROPDOWN ) 562 || ( nPType == BASEPROPERTY_HSCROLL ) 563 || ( nPType == BASEPROPERTY_VSCROLL ) 564 || ( nPType == BASEPROPERTY_AUTOHSCROLL ) 565 || ( nPType == BASEPROPERTY_AUTOVSCROLL ) 566 || ( nPType == BASEPROPERTY_ORIENTATION ) 567 || ( nPType == BASEPROPERTY_SPIN ) 568 || ( nPType == BASEPROPERTY_ALIGN ) 569 || ( nPType == BASEPROPERTY_PAINTTRANSPARENT ); 570 else 571 bNeedNewPeer = requiresNewPeer( pEvents->PropertyName ); 572 573 if ( bNeedNewPeer ) 574 break; 575 } 576 577 if ( nPType && ( nLen > 1 ) && DoesDependOnOthers( nPType ) ) 578 { 579 // Properties die von anderen abhaengen erst hinterher einstellen, 580 // weil sie von anderen Properties abhaengig sind, die aber erst spaeter 581 // eingestellt werden, z.B. VALUE nach VALUEMIN/MAX. 582 aPeerPropertiesToSet.push_back(PropertyValue(pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE)); 583 } 584 else 585 { 586 if ( bResourceResolverSet ) 587 { 588 // The resource resolver property change should be one of the first ones. 589 // All language dependent properties are dependent on this property. 590 // As BASEPROPERTY_NATIVE_WIDGET_LOOK is not dependent on resource 591 // resolver. We don't need to handle a special order for these two props. 592 aPeerPropertiesToSet.insert( 593 aPeerPropertiesToSet.begin(), 594 PropertyValue( pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE ) ); 595 ++nIndependentPos; 596 } 597 else if ( nPType == BASEPROPERTY_NATIVE_WIDGET_LOOK ) 598 { 599 // since *a lot* of other properties might be overruled by this one, we need 600 // a special handling: 601 // NativeWidgetLook needs to be set first: If it is set to ON, all other 602 // properties describing the look (e.g. BackgroundColor) are ignored, anyway. 603 // If it is switched OFF, then we need to do it first because else it will 604 // overrule other look-related properties, and re-initialize them from system 605 // defaults. 606 aPeerPropertiesToSet.insert( 607 aPeerPropertiesToSet.begin(), 608 PropertyValue( pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE ) ); 609 ++nIndependentPos; 610 } 611 else 612 { 613 aPeerPropertiesToSet.insert(aPeerPropertiesToSet.begin() + nIndependentPos, 614 PropertyValue(pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE)); 615 ++nIndependentPos; 616 } 617 } 618 } 619 620 Reference< XWindow > xParent = getParentPeer(); 621 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY ); 622 // call createPeer via a interface got from queryInterface, so the aggregating class can intercept it 623 624 DBG_ASSERT( !bNeedNewPeer || xParent.is(), "Need new peer, but don't have a parent!" ); 625 626 // Check if we have to update language dependent properties 627 if ( !bNeedNewPeer && bResourceResolverSet ) 628 { 629 // Add language dependent properties into the peer property set. 630 // Our resource resolver has been changed and we must be sure 631 // that language dependent props use the new resolver. 632 const LanguageDependentProp* pLangDepProp = aLanguageDependentProp; 633 while ( pLangDepProp->pPropName != 0 ) 634 { 635 bool bMustBeInserted( true ); 636 for ( sal_uInt32 i = 0; i < aPeerPropertiesToSet.size(); i++ ) 637 { 638 if ( aPeerPropertiesToSet[i].Name.equalsAsciiL( 639 pLangDepProp->pPropName, pLangDepProp->nPropNameLength )) 640 { 641 bMustBeInserted = false; 642 break; 643 } 644 } 645 646 if ( bMustBeInserted ) 647 { 648 // Add language dependent props at the end 649 ::rtl::OUString aPropName( ::rtl::OUString::createFromAscii( pLangDepProp->pPropName )); 650 if ( xPSI.is() && xPSI->hasPropertyByName( aPropName ) ) 651 { 652 aPeerPropertiesToSet.push_back( 653 PropertyValue( aPropName, 0, xPS->getPropertyValue( aPropName ), PropertyState_DIRECT_VALUE ) ); 654 } 655 } 656 657 ++pLangDepProp; 658 } 659 } 660 aGuard.clear(); 661 662 // clear the guard before creating a new peer - as usual, our peer implementations use the SolarMutex 663 // #82300# - 2000-12-21 - fs@openoffice.org 664 if (bNeedNewPeer && xParent.is()) 665 { 666 vos::OGuard aVclGuard( Application::GetSolarMutex() ); 667 // and now this is the final withdrawal: 668 // With 83561, I have no other idea than locking the SolarMutex here .... 669 // I really hate the fact that VCL is not theadsafe .... 670 // #83561# - 2001-03-01 - fs@openoffice.org 671 672 // Funktioniert beim Container nicht! 673 getPeer()->dispose(); 674 mxPeer.clear(); 675 mxVclWindowPeer = NULL; 676 mbRefeshingPeer = sal_True; 677 Reference< XWindowPeer > xP( xParent, UNO_QUERY ); 678 xThis->createPeer( Reference< XToolkit > (), xP ); 679 mbRefeshingPeer = sal_False; 680 aPeerPropertiesToSet.clear(); 681 } 682 683 // lock the multiplexing of VCL events to our UNO listeners 684 // this is for compatibility reasons: in OOo 1.0.x, changes which were done at the 685 // model did not cause the listeners of the controls/peers to be called 686 // Since the implementations for the listeners changed a lot towards 1.1, this 687 // would not be the case anymore, if we would not do this listener-lock below 688 // #i14703# - 2003-05-23 - fs@openoffice.org 689 Window* pVclPeer = VCLUnoHelper::GetWindow( getPeer() ); 690 VCLXWindow* pPeer = pVclPeer ? pVclPeer->GetWindowPeer() : NULL; 691 VclListenerLock aNoVclEventMultiplexing( pPeer ); 692 693 // setting peer properties may result in an attemp to acquire the solar mutex, 'cause the peers 694 // usually don't have an own mutex but use the SolarMutex instead. 695 // To prevent deadlocks resulting from this, we do this without our own mutex locked 696 // 2000-11-03 - fs@openoffice.org 697 PropertyValueVectorIterator aEnd = aPeerPropertiesToSet.end(); 698 for ( PropertyValueVectorIterator aLoop = aPeerPropertiesToSet.begin(); 699 aLoop != aEnd; 700 ++aLoop 701 ) 702 { 703 ImplSetPeerProperty( aLoop->Name, aLoop->Value ); 704 } 705 } 706 } 707 708 void UnoControl::disposing( const EventObject& rEvt ) throw(RuntimeException) 709 { 710 ::osl::ClearableMutexGuard aGuard( GetMutex() ); 711 // bei "Multible Inheritance" nicht unterschiedliche Typen vergleichen. 712 713 if ( maAccessibleContext.get() == rEvt.Source ) 714 { 715 // just in case the context is disposed, but not released - ensure that we do not re-use it in the future 716 maAccessibleContext = NULL; 717 } 718 else if( mxModel.get() == Reference< XControlModel >(rEvt.Source,UNO_QUERY).get() ) 719 { 720 // #62337# if the model dies, it does not make sense for us to live ... 721 Reference< XControl > xThis = this; 722 723 aGuard.clear(); 724 xThis->dispose(); 725 726 DBG_ASSERT( !mxModel.is(), "UnoControl::disposing: invalid dispose behaviour!" ); 727 mxModel.clear(); 728 } 729 } 730 731 732 void SAL_CALL UnoControl::setOutputSize( const awt::Size& aSize ) throw (RuntimeException) 733 { 734 Reference< XWindow2 > xPeerWindow; 735 { 736 ::osl::MutexGuard aGuard( GetMutex() ); 737 xPeerWindow = xPeerWindow.query( getPeer() ); 738 } 739 740 if ( xPeerWindow.is() ) 741 xPeerWindow->setOutputSize( aSize ); 742 } 743 744 namespace 745 { 746 template < typename RETVALTYPE > 747 RETVALTYPE lcl_askPeer( const uno::Reference< awt::XWindowPeer >& _rxPeer, RETVALTYPE (SAL_CALL XWindow2::*_pMethod)(), RETVALTYPE _aDefault ) 748 { 749 RETVALTYPE aReturn( _aDefault ); 750 751 Reference< XWindow2 > xPeerWindow( _rxPeer, UNO_QUERY ); 752 if ( xPeerWindow.is() ) 753 aReturn = (xPeerWindow.get()->*_pMethod)(); 754 755 return aReturn; 756 } 757 } 758 759 awt::Size SAL_CALL UnoControl::getOutputSize( ) throw (RuntimeException) 760 { 761 return lcl_askPeer( getPeer(), &XWindow2::getOutputSize, awt::Size() ); 762 } 763 764 ::sal_Bool SAL_CALL UnoControl::isVisible( ) throw (RuntimeException) 765 { 766 return lcl_askPeer( getPeer(), &XWindow2::isVisible, maComponentInfos.bVisible ); 767 } 768 769 ::sal_Bool SAL_CALL UnoControl::isActive( ) throw (RuntimeException) 770 { 771 return lcl_askPeer( getPeer(), &XWindow2::isActive, sal_False ); 772 } 773 774 ::sal_Bool SAL_CALL UnoControl::isEnabled( ) throw (RuntimeException) 775 { 776 return lcl_askPeer( getPeer(), &XWindow2::isEnabled, maComponentInfos.bEnable ); 777 } 778 779 ::sal_Bool SAL_CALL UnoControl::hasFocus( ) throw (RuntimeException) 780 { 781 return lcl_askPeer( getPeer(), &XWindow2::hasFocus, sal_False ); 782 } 783 784 // XWindow 785 void UnoControl::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) throw(RuntimeException) 786 { 787 Reference< XWindow > xWindow; 788 { 789 ::osl::MutexGuard aGuard( GetMutex() ); 790 791 if ( Flags & awt::PosSize::X ) 792 maComponentInfos.nX = X; 793 if ( Flags & awt::PosSize::Y ) 794 maComponentInfos.nY = Y; 795 if ( Flags & awt::PosSize::WIDTH ) 796 maComponentInfos.nWidth = Width; 797 if ( Flags & awt::PosSize::HEIGHT ) 798 maComponentInfos.nHeight = Height; 799 maComponentInfos.nFlags |= Flags; 800 801 xWindow = xWindow.query( getPeer() ); 802 } 803 804 if( xWindow.is() ) 805 xWindow->setPosSize( X, Y, Width, Height, Flags ); 806 } 807 808 awt::Rectangle UnoControl::getPosSize( ) throw(RuntimeException) 809 { 810 awt::Rectangle aRect( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight); 811 Reference< XWindow > xWindow; 812 813 { 814 ::osl::MutexGuard aGuard( GetMutex() ); 815 xWindow = xWindow.query( getPeer() ); 816 } 817 818 if( xWindow.is() ) 819 aRect = xWindow->getPosSize(); 820 return aRect; 821 } 822 823 void UnoControl::setVisible( sal_Bool bVisible ) throw(RuntimeException) 824 { 825 Reference< XWindow > xWindow; 826 { 827 ::osl::MutexGuard aGuard( GetMutex() ); 828 829 // Visible status ist Sache der View 830 maComponentInfos.bVisible = bVisible; 831 xWindow = xWindow.query( getPeer() ); 832 } 833 if ( xWindow.is() ) 834 xWindow->setVisible( bVisible ); 835 } 836 837 void UnoControl::setEnable( sal_Bool bEnable ) throw(RuntimeException) 838 { 839 Reference< XWindow > xWindow; 840 { 841 ::osl::MutexGuard aGuard( GetMutex() ); 842 843 // Enable status ist Sache der View 844 maComponentInfos.bEnable = bEnable; 845 xWindow = xWindow.query( getPeer() ); 846 } 847 if ( xWindow.is() ) 848 xWindow->setEnable( bEnable ); 849 } 850 851 void UnoControl::setFocus( ) throw(RuntimeException) 852 { 853 Reference< XWindow > xWindow; 854 { 855 ::osl::MutexGuard aGuard( GetMutex() ); 856 xWindow = xWindow.query( getPeer() ); 857 } 858 if ( xWindow.is() ) 859 xWindow->setFocus(); 860 } 861 862 void UnoControl::addWindowListener( const Reference< XWindowListener >& rxListener ) throw(RuntimeException) 863 { 864 Reference< XWindow > xPeerWindow; 865 { 866 ::osl::MutexGuard aGuard( GetMutex() ); 867 maWindowListeners.addInterface( rxListener ); 868 if ( maWindowListeners.getLength() == 1 ) 869 xPeerWindow = xPeerWindow.query( getPeer() ); 870 } 871 if ( xPeerWindow.is() ) 872 xPeerWindow->addWindowListener( &maWindowListeners ); 873 } 874 875 void UnoControl::removeWindowListener( const Reference< XWindowListener >& rxListener ) throw(RuntimeException) 876 { 877 Reference< XWindow > xPeerWindow; 878 { 879 ::osl::MutexGuard aGuard( GetMutex() ); 880 if ( maWindowListeners.getLength() == 1 ) 881 xPeerWindow = xPeerWindow.query( getPeer() ); 882 maWindowListeners.removeInterface( rxListener ); 883 } 884 if ( xPeerWindow.is() ) 885 xPeerWindow->removeWindowListener( &maWindowListeners ); 886 } 887 888 void UnoControl::addFocusListener( const Reference< XFocusListener >& rxListener ) throw(RuntimeException) 889 { 890 Reference< XWindow > xPeerWindow; 891 { 892 ::osl::MutexGuard aGuard( GetMutex() ); 893 maFocusListeners.addInterface( rxListener ); 894 if ( maFocusListeners.getLength() == 1 ) 895 xPeerWindow = xPeerWindow.query( getPeer() ); 896 } 897 if ( xPeerWindow.is() ) 898 xPeerWindow->addFocusListener( &maFocusListeners ); 899 } 900 901 void UnoControl::removeFocusListener( const Reference< XFocusListener >& rxListener ) throw(RuntimeException) 902 { 903 Reference< XWindow > xPeerWindow; 904 { 905 ::osl::MutexGuard aGuard( GetMutex() ); 906 if ( maFocusListeners.getLength() == 1 ) 907 xPeerWindow = xPeerWindow.query( getPeer() ); 908 maFocusListeners.removeInterface( rxListener ); 909 } 910 if ( xPeerWindow.is() ) 911 xPeerWindow->removeFocusListener( &maFocusListeners ); 912 } 913 914 void UnoControl::addKeyListener( const Reference< XKeyListener >& rxListener ) throw(RuntimeException) 915 { 916 Reference< XWindow > xPeerWindow; 917 { 918 ::osl::MutexGuard aGuard( GetMutex() ); 919 maKeyListeners.addInterface( rxListener ); 920 if ( maKeyListeners.getLength() == 1 ) 921 xPeerWindow = xPeerWindow.query( getPeer() ); 922 } 923 if ( xPeerWindow.is() ) 924 xPeerWindow->addKeyListener( &maKeyListeners); 925 } 926 927 void UnoControl::removeKeyListener( const Reference< XKeyListener >& rxListener ) throw(RuntimeException) 928 { 929 Reference< XWindow > xPeerWindow; 930 { 931 ::osl::MutexGuard aGuard( GetMutex() ); 932 if ( maKeyListeners.getLength() == 1 ) 933 xPeerWindow = xPeerWindow.query( getPeer() ); 934 maKeyListeners.removeInterface( rxListener ); 935 } 936 if ( xPeerWindow.is() ) 937 xPeerWindow->removeKeyListener( &maKeyListeners); 938 } 939 940 void UnoControl::addMouseListener( const Reference< XMouseListener >& rxListener ) throw(RuntimeException) 941 { 942 Reference< XWindow > xPeerWindow; 943 { 944 ::osl::MutexGuard aGuard( GetMutex() ); 945 maMouseListeners.addInterface( rxListener ); 946 if ( maMouseListeners.getLength() == 1 ) 947 xPeerWindow = xPeerWindow.query( getPeer() ); 948 } 949 if ( xPeerWindow.is() ) 950 xPeerWindow->addMouseListener( &maMouseListeners); 951 } 952 953 void UnoControl::removeMouseListener( const Reference< XMouseListener >& rxListener ) throw(RuntimeException) 954 { 955 Reference< XWindow > xPeerWindow; 956 { 957 ::osl::MutexGuard aGuard( GetMutex() ); 958 if ( maMouseListeners.getLength() == 1 ) 959 xPeerWindow = xPeerWindow.query( getPeer() ); 960 maMouseListeners.removeInterface( rxListener ); 961 } 962 if ( xPeerWindow.is() ) 963 xPeerWindow->removeMouseListener( &maMouseListeners ); 964 } 965 966 void UnoControl::addMouseMotionListener( const Reference< XMouseMotionListener >& rxListener ) throw(RuntimeException) 967 { 968 Reference< XWindow > xPeerWindow; 969 { 970 ::osl::MutexGuard aGuard( GetMutex() ); 971 maMouseMotionListeners.addInterface( rxListener ); 972 if ( maMouseMotionListeners.getLength() == 1 ) 973 xPeerWindow = xPeerWindow.query( getPeer() ); 974 } 975 if ( xPeerWindow.is() ) 976 xPeerWindow->addMouseMotionListener( &maMouseMotionListeners); 977 } 978 979 void UnoControl::removeMouseMotionListener( const Reference< XMouseMotionListener >& rxListener ) throw(RuntimeException) 980 { 981 Reference< XWindow > xPeerWindow; 982 { 983 ::osl::MutexGuard aGuard( GetMutex() ); 984 if ( maMouseMotionListeners.getLength() == 1 ) 985 xPeerWindow = xPeerWindow.query( getPeer() ); 986 maMouseMotionListeners.removeInterface( rxListener ); 987 } 988 if ( xPeerWindow.is() ) 989 xPeerWindow->removeMouseMotionListener( &maMouseMotionListeners ); 990 } 991 992 void UnoControl::addPaintListener( const Reference< XPaintListener >& rxListener ) throw(RuntimeException) 993 { 994 Reference< XWindow > xPeerWindow; 995 { 996 ::osl::MutexGuard aGuard( GetMutex() ); 997 maPaintListeners.addInterface( rxListener ); 998 if ( maPaintListeners.getLength() == 1 ) 999 xPeerWindow = xPeerWindow.query( getPeer() ); 1000 } 1001 if ( xPeerWindow.is() ) 1002 xPeerWindow->addPaintListener( &maPaintListeners); 1003 } 1004 1005 void UnoControl::removePaintListener( const Reference< XPaintListener >& rxListener ) throw(RuntimeException) 1006 { 1007 Reference< XWindow > xPeerWindow; 1008 { 1009 ::osl::MutexGuard aGuard( GetMutex() ); 1010 if ( maPaintListeners.getLength() == 1 ) 1011 xPeerWindow = xPeerWindow.query( getPeer() ); 1012 maPaintListeners.removeInterface( rxListener ); 1013 } 1014 if ( xPeerWindow.is() ) 1015 xPeerWindow->removePaintListener( &maPaintListeners ); 1016 } 1017 1018 // XView 1019 sal_Bool UnoControl::setGraphics( const Reference< XGraphics >& rDevice ) throw(RuntimeException) 1020 { 1021 Reference< XView > xView; 1022 { 1023 ::osl::MutexGuard aGuard( GetMutex() ); 1024 1025 mxGraphics = rDevice; 1026 xView = xView.query( getPeer() ); 1027 } 1028 return xView.is() ? xView->setGraphics( rDevice ) : sal_True; 1029 } 1030 1031 Reference< XGraphics > UnoControl::getGraphics( ) throw(RuntimeException) 1032 { 1033 return mxGraphics; 1034 } 1035 1036 awt::Size UnoControl::getSize( ) throw(RuntimeException) 1037 { 1038 ::osl::MutexGuard aGuard( GetMutex() ); 1039 return awt::Size( maComponentInfos.nWidth, maComponentInfos.nHeight ); 1040 } 1041 1042 void UnoControl::draw( sal_Int32 x, sal_Int32 y ) throw(RuntimeException) 1043 { 1044 Reference< XWindowPeer > xDrawPeer; 1045 Reference< XView > xDrawPeerView; 1046 1047 bool bDisposeDrawPeer( false ); 1048 { 1049 ::osl::MutexGuard aGuard( GetMutex() ); 1050 1051 xDrawPeer = ImplGetCompatiblePeer( sal_True ); 1052 bDisposeDrawPeer = xDrawPeer.is() && ( xDrawPeer != getPeer() ); 1053 1054 xDrawPeerView.set( xDrawPeer, UNO_QUERY ); 1055 DBG_ASSERT( xDrawPeerView.is(), "UnoControl::draw: no peer!" ); 1056 } 1057 1058 if ( xDrawPeerView.is() ) 1059 { 1060 Reference< XVclWindowPeer > xWindowPeer; 1061 xWindowPeer.set( xDrawPeer, UNO_QUERY ); 1062 if ( xWindowPeer.is() ) 1063 xWindowPeer->setDesignMode( mbDesignMode ); 1064 xDrawPeerView->draw( x, y ); 1065 } 1066 1067 if ( bDisposeDrawPeer ) 1068 xDrawPeer->dispose(); 1069 } 1070 1071 void UnoControl::setZoom( float fZoomX, float fZoomY ) throw(RuntimeException) 1072 { 1073 Reference< XView > xView; 1074 { 1075 ::osl::MutexGuard aGuard( GetMutex() ); 1076 1077 maComponentInfos.nZoomX = fZoomX; 1078 maComponentInfos.nZoomY = fZoomY; 1079 1080 xView = xView.query( getPeer() ); 1081 } 1082 if ( xView.is() ) 1083 xView->setZoom( fZoomX, fZoomY ); 1084 } 1085 1086 // XControl 1087 void UnoControl::setContext( const Reference< XInterface >& rxContext ) throw(RuntimeException) 1088 { 1089 ::osl::MutexGuard aGuard( GetMutex() ); 1090 1091 mxContext = rxContext; 1092 } 1093 1094 Reference< XInterface > UnoControl::getContext( ) throw(RuntimeException) 1095 { 1096 ::osl::MutexGuard aGuard( GetMutex() ); 1097 1098 return mxContext; 1099 } 1100 1101 void UnoControl::peerCreated() 1102 { 1103 Reference< XWindow > xWindow( getPeer(), UNO_QUERY ); 1104 if ( !xWindow.is() ) 1105 return; 1106 1107 if ( maWindowListeners.getLength() ) 1108 xWindow->addWindowListener( &maWindowListeners ); 1109 1110 if ( maFocusListeners.getLength() ) 1111 xWindow->addFocusListener( &maFocusListeners ); 1112 1113 if ( maKeyListeners.getLength() ) 1114 xWindow->addKeyListener( &maKeyListeners ); 1115 1116 if ( maMouseListeners.getLength() ) 1117 xWindow->addMouseListener( &maMouseListeners ); 1118 1119 if ( maMouseMotionListeners.getLength() ) 1120 xWindow->addMouseMotionListener( &maMouseMotionListeners ); 1121 1122 if ( maPaintListeners.getLength() ) 1123 xWindow->addPaintListener( &maPaintListeners ); 1124 } 1125 1126 void UnoControl::createPeer( const Reference< XToolkit >& rxToolkit, const Reference< XWindowPeer >& rParentPeer ) throw(RuntimeException) 1127 { 1128 ::osl::ClearableMutexGuard aGuard( GetMutex() ); 1129 1130 if ( !mxModel.is() ) 1131 { 1132 RuntimeException aException; 1133 aException.Message = ::rtl::OUString::createFromAscii( "createPeer: no model!" ); 1134 aException.Context = (XAggregation*)(::cppu::OWeakAggObject*)this; 1135 throw( aException ); 1136 } 1137 1138 if( !getPeer().is() ) 1139 { 1140 mbCreatingPeer = sal_True; 1141 1142 WindowClass eType; 1143 Reference< XToolkit > xToolkit = rxToolkit; 1144 if( rParentPeer.is() && mxContext.is() ) 1145 { 1146 // kein TopWindow 1147 if ( !xToolkit.is() ) 1148 xToolkit = rParentPeer->getToolkit(); 1149 Any aAny = OWeakAggObject::queryInterface( ::getCppuType((const Reference< XControlContainer>*)0) ); 1150 Reference< XControlContainer > xC; 1151 aAny >>= xC; 1152 if( xC.is() ) 1153 // Es ist ein Container 1154 eType = WindowClass_CONTAINER; 1155 else 1156 eType = WindowClass_SIMPLE; 1157 } 1158 else 1159 { // Nur richtig, wenn es sich um ein Top Window handelt 1160 if( rParentPeer.is() ) 1161 { 1162 if ( !xToolkit.is() ) 1163 xToolkit = rParentPeer->getToolkit(); 1164 eType = WindowClass_CONTAINER; 1165 } 1166 else 1167 { 1168 if ( !xToolkit.is() ) 1169 xToolkit = VCLUnoHelper::CreateToolkit(); 1170 eType = WindowClass_TOP; 1171 } 1172 } 1173 WindowDescriptor aDescr; 1174 aDescr.Type = eType; 1175 aDescr.WindowServiceName = GetComponentServiceName(); 1176 aDescr.Parent = rParentPeer; 1177 aDescr.Bounds = getPosSize(); 1178 aDescr.WindowAttributes = 0; 1179 1180 // Border 1181 Reference< XPropertySet > xPSet( mxModel, UNO_QUERY ); 1182 Reference< XPropertySetInfo > xInfo = xPSet->getPropertySetInfo(); 1183 1184 Any aVal; 1185 ::rtl::OUString aPropName = GetPropertyName( BASEPROPERTY_BORDER ); 1186 if ( xInfo->hasPropertyByName( aPropName ) ) 1187 { 1188 aVal = xPSet->getPropertyValue( aPropName ); 1189 sal_Int16 n = sal_Int16(); 1190 if ( aVal >>= n ) 1191 { 1192 if ( n ) 1193 aDescr.WindowAttributes |= WindowAttribute::BORDER; 1194 else 1195 aDescr.WindowAttributes |= VclWindowPeerAttribute::NOBORDER; 1196 } 1197 } 1198 1199 // DESKTOP_AS_PARENT 1200 if ( aDescr.Type == WindowClass_TOP ) 1201 { 1202 aPropName = GetPropertyName( BASEPROPERTY_DESKTOP_AS_PARENT ); 1203 if ( xInfo->hasPropertyByName( aPropName ) ) 1204 { 1205 aVal = xPSet->getPropertyValue( aPropName ); 1206 sal_Bool b = sal_Bool(); 1207 if ( ( aVal >>= b ) && b) 1208 aDescr.ParentIndex = -1; 1209 } 1210 } 1211 // Moveable 1212 aPropName = GetPropertyName( BASEPROPERTY_MOVEABLE ); 1213 if ( xInfo->hasPropertyByName( aPropName ) ) 1214 { 1215 aVal = xPSet->getPropertyValue( aPropName ); 1216 sal_Bool b = sal_Bool(); 1217 if ( ( aVal >>= b ) && b) 1218 aDescr.WindowAttributes |= WindowAttribute::MOVEABLE; 1219 } 1220 1221 // Closeable 1222 aPropName = GetPropertyName( BASEPROPERTY_CLOSEABLE ); 1223 if ( xInfo->hasPropertyByName( aPropName ) ) 1224 { 1225 aVal = xPSet->getPropertyValue( aPropName ); 1226 sal_Bool b = sal_Bool(); 1227 if ( ( aVal >>= b ) && b) 1228 aDescr.WindowAttributes |= WindowAttribute::CLOSEABLE; 1229 } 1230 1231 // Dropdown 1232 aPropName = GetPropertyName( BASEPROPERTY_DROPDOWN ); 1233 if ( xInfo->hasPropertyByName( aPropName ) ) 1234 { 1235 aVal = xPSet->getPropertyValue( aPropName ); 1236 sal_Bool b = sal_Bool(); 1237 if ( ( aVal >>= b ) && b) 1238 aDescr.WindowAttributes |= VclWindowPeerAttribute::DROPDOWN; 1239 } 1240 1241 // Spin 1242 aPropName = GetPropertyName( BASEPROPERTY_SPIN ); 1243 if ( xInfo->hasPropertyByName( aPropName ) ) 1244 { 1245 aVal = xPSet->getPropertyValue( aPropName ); 1246 sal_Bool b = sal_Bool(); 1247 if ( ( aVal >>= b ) && b) 1248 aDescr.WindowAttributes |= VclWindowPeerAttribute::SPIN; 1249 } 1250 1251 // HScroll 1252 aPropName = GetPropertyName( BASEPROPERTY_HSCROLL ); 1253 if ( xInfo->hasPropertyByName( aPropName ) ) 1254 { 1255 aVal = xPSet->getPropertyValue( aPropName ); 1256 sal_Bool b = sal_Bool(); 1257 if ( ( aVal >>= b ) && b) 1258 aDescr.WindowAttributes |= VclWindowPeerAttribute::HSCROLL; 1259 } 1260 1261 // VScroll 1262 aPropName = GetPropertyName( BASEPROPERTY_VSCROLL ); 1263 if ( xInfo->hasPropertyByName( aPropName ) ) 1264 { 1265 aVal = xPSet->getPropertyValue( aPropName ); 1266 sal_Bool b = sal_Bool(); 1267 if ( ( aVal >>= b ) && b) 1268 aDescr.WindowAttributes |= VclWindowPeerAttribute::VSCROLL; 1269 } 1270 1271 // AutoHScroll 1272 aPropName = GetPropertyName( BASEPROPERTY_AUTOHSCROLL ); 1273 if ( xInfo->hasPropertyByName( aPropName ) ) 1274 { 1275 aVal = xPSet->getPropertyValue( aPropName ); 1276 sal_Bool b = sal_Bool(); 1277 if ( ( aVal >>= b ) && b) 1278 aDescr.WindowAttributes |= VclWindowPeerAttribute::AUTOHSCROLL; 1279 } 1280 1281 // AutoVScroll 1282 aPropName = GetPropertyName( BASEPROPERTY_AUTOVSCROLL ); 1283 if ( xInfo->hasPropertyByName( aPropName ) ) 1284 { 1285 aVal = xPSet->getPropertyValue( aPropName ); 1286 sal_Bool b = sal_Bool(); 1287 if ( ( aVal >>= b ) && b) 1288 aDescr.WindowAttributes |= VclWindowPeerAttribute::AUTOVSCROLL; 1289 } 1290 1291 //added for issue79712 1292 //NoLabel 1293 aPropName = GetPropertyName( BASEPROPERTY_NOLABEL ); 1294 if ( xInfo->hasPropertyByName( aPropName ) ) 1295 { 1296 aVal = xPSet->getPropertyValue( aPropName ); 1297 sal_Bool b = sal_Bool(); 1298 if ( ( aVal >>=b ) && b ) 1299 aDescr.WindowAttributes |= VclWindowPeerAttribute::NOLABEL; 1300 } 1301 //issue79712 ends 1302 1303 // Align 1304 aPropName = GetPropertyName( BASEPROPERTY_ALIGN ); 1305 if ( xInfo->hasPropertyByName( aPropName ) ) 1306 { 1307 aVal = xPSet->getPropertyValue( aPropName ); 1308 sal_Int16 n = sal_Int16(); 1309 if ( aVal >>= n ) 1310 { 1311 if ( n == PROPERTY_ALIGN_LEFT ) 1312 aDescr.WindowAttributes |= VclWindowPeerAttribute::LEFT; 1313 else if ( n == PROPERTY_ALIGN_CENTER ) 1314 aDescr.WindowAttributes |= VclWindowPeerAttribute::CENTER; 1315 else 1316 aDescr.WindowAttributes |= VclWindowPeerAttribute::RIGHT; 1317 } 1318 } 1319 1320 // Ableitungen die Moeglichkeit geben die Attribute zu manipulieren 1321 PrepareWindowDescriptor(aDescr); 1322 1323 // create the peer 1324 setPeer( xToolkit->createWindow( aDescr ) ); 1325 1326 // release the mutex guard (and work with copies of our members) 1327 // this is necessary as our peer may lock the SolarMutex (actually, all currently known peers do), so calling 1328 // into the peer with our own mutex locked may cause deadlocks 1329 // (We _really_ need peers which do not use the SolarMutex. It's really pissing me off that from time to 1330 // time deadlocks pop up because the low-level components like our peers use a mutex which ususally 1331 // is locked at the top of the stack (it protects the global message looping). This is always dangerous, and 1332 // can not always be solved by tampering with other mutexes. 1333 // Unfortunately, the VCL used in the peers is not threadsafe, and by definition needs a locked SolarMutex.) 1334 // 82300 - 12/21/00 - FS 1335 UnoControlComponentInfos aComponentInfos(maComponentInfos); 1336 sal_Bool bDesignMode(mbDesignMode); 1337 1338 Reference< XGraphics > xGraphics( mxGraphics ); 1339 Reference< XView > xView ( getPeer(), UNO_QUERY ); 1340 Reference< XWindow > xWindow ( getPeer(), UNO_QUERY ); 1341 1342 aGuard.clear(); 1343 1344 // the updateFromModel is done without a locked mutex, too. 1345 // The reason is that the only thing this method does is firing property changes, and this in general has 1346 // to be done without locked mutexes (as every notification to external listeners). 1347 // 82300 - 12/21/00 - FS 1348 updateFromModel(); 1349 1350 xView->setZoom( aComponentInfos.nZoomX, aComponentInfos.nZoomY ); 1351 1352 setPosSize( aComponentInfos.nX, aComponentInfos.nY, aComponentInfos.nWidth, aComponentInfos.nHeight, aComponentInfos.nFlags ); 1353 1354 if( aComponentInfos.bVisible && !bDesignMode ) 1355 // Erst nach dem setzen der Daten anzeigen 1356 xWindow->setVisible( aComponentInfos.bVisible ); 1357 1358 if( !aComponentInfos.bEnable ) 1359 xWindow->setEnable( aComponentInfos.bEnable ); 1360 1361 xView->setGraphics( xGraphics ); 1362 1363 peerCreated(); 1364 1365 mbCreatingPeer = sal_False; 1366 } 1367 } 1368 1369 Reference< XWindowPeer > UnoControl::getPeer() throw(RuntimeException) 1370 { 1371 ::osl::MutexGuard aGuard( GetMutex() ); 1372 return mxPeer; 1373 } 1374 1375 sal_Bool UnoControl::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException) 1376 { 1377 ::osl::MutexGuard aGuard( GetMutex() ); 1378 1379 Reference< XMultiPropertySet > xPropSet( mxModel, UNO_QUERY ); 1380 1381 // query for the XPropertiesChangeListener - our delegator is allowed to overwrite this interface 1382 Reference< XPropertiesChangeListener > xListener; 1383 queryInterface( ::getCppuType( &xListener ) ) >>= xListener; 1384 1385 if( xPropSet.is() ) 1386 xPropSet->removePropertiesChangeListener( xListener ); 1387 1388 mpData->bLocalizationSupport = false; 1389 mxModel = rxModel; 1390 1391 if( mxModel.is() ) 1392 { 1393 try 1394 { 1395 xPropSet.set( mxModel, UNO_QUERY_THROW ); 1396 Reference< XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), UNO_SET_THROW ); 1397 1398 Sequence< ::rtl::OUString> aNames = lcl_ImplGetPropertyNames( xPropSet ); 1399 xPropSet->addPropertiesChangeListener( aNames, xListener ); 1400 1401 mpData->bLocalizationSupport = xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ); 1402 } 1403 catch( const Exception& ) 1404 { 1405 DBG_UNHANDLED_EXCEPTION(); 1406 mxModel.clear(); 1407 } 1408 } 1409 1410 return mxModel.is(); 1411 } 1412 1413 Reference< XControlModel > UnoControl::getModel( ) throw(RuntimeException) 1414 { 1415 return mxModel; 1416 } 1417 1418 Reference< XView > UnoControl::getView( ) throw(RuntimeException) 1419 { 1420 return static_cast< XView* >( this ); 1421 } 1422 1423 void UnoControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException) 1424 { 1425 ModeChangeEvent aModeChangeEvent; 1426 1427 Reference< XWindow > xWindow; 1428 { 1429 ::osl::MutexGuard aGuard( GetMutex() ); 1430 if ( bOn == mbDesignMode ) 1431 return; 1432 1433 // remember this 1434 mbDesignMode = bOn; 1435 xWindow = xWindow.query( getPeer() ); 1436 // dispose our current AccessibleContext, if we have one 1437 // (changing the design mode implies having a new implementation for this context, 1438 // so the old one must be declared DEFUNC) 1439 disposeAccessibleContext(); 1440 1441 aModeChangeEvent.Source = *this; 1442 aModeChangeEvent.NewMode = ::rtl::OUString::createFromAscii( mbDesignMode ? "design" : "alive" ); 1443 } 1444 1445 // ajust the visibility of our window 1446 if ( xWindow.is() ) 1447 xWindow->setVisible( !bOn ); 1448 1449 // and notify our mode listeners 1450 maModeChangeListeners.notifyEach( &XModeChangeListener::modeChanged, aModeChangeEvent ); 1451 } 1452 1453 sal_Bool UnoControl::isDesignMode( ) throw(RuntimeException) 1454 { 1455 return mbDesignMode; 1456 } 1457 1458 sal_Bool UnoControl::isTransparent( ) throw(RuntimeException) 1459 { 1460 return sal_False; 1461 } 1462 1463 // XServiceInfo 1464 ::rtl::OUString UnoControl::getImplementationName( ) throw(RuntimeException) 1465 { 1466 DBG_ERROR( "This method should be overloaded!" ); 1467 return ::rtl::OUString(); 1468 } 1469 1470 sal_Bool UnoControl::supportsService( const ::rtl::OUString& rServiceName ) throw(RuntimeException) 1471 { 1472 ::osl::MutexGuard aGuard( GetMutex() ); 1473 1474 Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); 1475 const ::rtl::OUString* pArray = aSNL.getConstArray(); 1476 const ::rtl::OUString* pArrayEnd = aSNL.getConstArray() + aSNL.getLength(); 1477 for (; pArray != pArrayEnd; ++pArray ) 1478 if( *pArray == rServiceName ) 1479 break; 1480 1481 return pArray != pArrayEnd; 1482 } 1483 1484 Sequence< ::rtl::OUString > UnoControl::getSupportedServiceNames( ) throw(RuntimeException) 1485 { 1486 ::rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) ); 1487 return Sequence< ::rtl::OUString >( &sName, 1 ); 1488 } 1489 1490 // ------------------------------------------------------------------------ 1491 Reference< XAccessibleContext > SAL_CALL UnoControl::getAccessibleContext( ) throw (RuntimeException) 1492 { 1493 // creation of the context will certainly require the SolarMutex ... 1494 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1495 ::osl::MutexGuard aGuard( GetMutex() ); 1496 1497 Reference< XAccessibleContext > xCurrentContext( maAccessibleContext.get(), UNO_QUERY ); 1498 if ( !xCurrentContext.is() ) 1499 { 1500 if ( !mbDesignMode ) 1501 { // in alive mode, use the AccessibleContext of the peer 1502 Reference< XAccessible > xPeerAcc( getPeer(), UNO_QUERY ); 1503 if ( xPeerAcc.is() ) 1504 xCurrentContext = xPeerAcc->getAccessibleContext( ); 1505 } 1506 else 1507 // in design mode, use a fallback 1508 xCurrentContext = ::toolkit::OAccessibleControlContext::create( this ); 1509 1510 DBG_ASSERT( xCurrentContext.is(), "UnoControl::getAccessibleContext: invalid context (invalid peer?)!" ); 1511 maAccessibleContext = xCurrentContext; 1512 1513 // get notified when the context is disposed 1514 Reference< XComponent > xContextComp( xCurrentContext, UNO_QUERY ); 1515 if ( xContextComp.is() ) 1516 xContextComp->addEventListener( this ); 1517 // In an ideal world, this is not necessary - there the object would be released as soon as it has been 1518 // disposed, and thus our weak reference would be empty, too. 1519 // But 'til this ideal world comes (means 'til we do never have any refcount/lifetime bugs anymore), we 1520 // need to listen for disposal and reset our weak reference then. 1521 } 1522 1523 return xCurrentContext; 1524 } 1525 1526 void SAL_CALL UnoControl::addModeChangeListener( const Reference< XModeChangeListener >& _rxListener ) throw (RuntimeException) 1527 { 1528 ::osl::MutexGuard aGuard( GetMutex() ); 1529 maModeChangeListeners.addInterface( _rxListener ); 1530 } 1531 1532 void SAL_CALL UnoControl::removeModeChangeListener( const Reference< XModeChangeListener >& _rxListener ) throw (RuntimeException) 1533 { 1534 ::osl::MutexGuard aGuard( GetMutex() ); 1535 maModeChangeListeners.removeInterface( _rxListener ); 1536 } 1537 1538 void SAL_CALL UnoControl::addModeChangeApproveListener( const Reference< XModeChangeApproveListener >& ) throw (NoSupportException, RuntimeException) 1539 { 1540 throw NoSupportException( ); 1541 } 1542 1543 void SAL_CALL UnoControl::removeModeChangeApproveListener( const Reference< XModeChangeApproveListener >& ) throw (NoSupportException, RuntimeException) 1544 { 1545 throw NoSupportException( ); 1546 } 1547 1548 //---------------------------------------------------------------------------------------------------------------------- 1549 awt::Point SAL_CALL UnoControl::convertPointToLogic( const awt::Point& i_Point, ::sal_Int16 i_TargetUnit ) throw (IllegalArgumentException, RuntimeException) 1550 { 1551 Reference< XUnitConversion > xPeerConversion; 1552 { 1553 ::osl::MutexGuard aGuard( GetMutex() ); 1554 xPeerConversion = xPeerConversion.query( getPeer() ); 1555 } 1556 if ( xPeerConversion.is() ) 1557 return xPeerConversion->convertPointToLogic( i_Point, i_TargetUnit ); 1558 return awt::Point( ); 1559 } 1560 1561 //---------------------------------------------------------------------------------------------------------------------- 1562 awt::Point SAL_CALL UnoControl::convertPointToPixel( const awt::Point& i_Point, ::sal_Int16 i_SourceUnit ) throw (IllegalArgumentException, RuntimeException) 1563 { 1564 Reference< XUnitConversion > xPeerConversion; 1565 { 1566 ::osl::MutexGuard aGuard( GetMutex() ); 1567 xPeerConversion = xPeerConversion.query( getPeer() ); 1568 } 1569 if ( xPeerConversion.is() ) 1570 return xPeerConversion->convertPointToPixel( i_Point, i_SourceUnit ); 1571 return awt::Point( ); 1572 } 1573 1574 //---------------------------------------------------------------------------------------------------------------------- 1575 awt::Size SAL_CALL UnoControl::convertSizeToLogic( const awt::Size& i_Size, ::sal_Int16 i_TargetUnit ) throw (IllegalArgumentException, RuntimeException) 1576 { 1577 Reference< XUnitConversion > xPeerConversion; 1578 { 1579 ::osl::MutexGuard aGuard( GetMutex() ); 1580 xPeerConversion = xPeerConversion.query( getPeer() ); 1581 } 1582 if ( xPeerConversion.is() ) 1583 return xPeerConversion->convertSizeToLogic( i_Size, i_TargetUnit ); 1584 return awt::Size( ); 1585 } 1586 1587 //---------------------------------------------------------------------------------------------------------------------- 1588 awt::Size SAL_CALL UnoControl::convertSizeToPixel( const awt::Size& i_Size, ::sal_Int16 i_SourceUnit ) throw (IllegalArgumentException, RuntimeException) 1589 { 1590 Reference< XUnitConversion > xPeerConversion; 1591 { 1592 ::osl::MutexGuard aGuard( GetMutex() ); 1593 xPeerConversion = xPeerConversion.query( getPeer() ); 1594 } 1595 if ( xPeerConversion.is() ) 1596 return xPeerConversion->convertSizeToPixel( i_Size, i_SourceUnit ); 1597 return awt::Size( ); 1598 } 1599 1600 //---------------------------------------------------------------------------------------------------------------------- 1601 uno::Reference< awt::XStyleSettings > SAL_CALL UnoControl::getStyleSettings() throw (RuntimeException) 1602 { 1603 Reference< awt::XStyleSettingsSupplier > xPeerSupplier; 1604 { 1605 ::osl::MutexGuard aGuard( GetMutex() ); 1606 xPeerSupplier = xPeerSupplier.query( getPeer() ); 1607 } 1608 if ( xPeerSupplier.is() ) 1609 return xPeerSupplier->getStyleSettings(); 1610 return NULL; 1611 } 1612