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