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