1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basctl.hxx" 30 #include <accessibledialogcontrolshape.hxx> 31 #include <baside3.hxx> 32 #include <dlgeddef.hxx> 33 #include <dlgedview.hxx> 34 #include <dlgedobj.hxx> 35 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 36 #include <com/sun/star/accessibility/AccessibleRole.hpp> 37 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 38 #include <unotools/accessiblestatesethelper.hxx> 39 #include <unotools/accessiblerelationsethelper.hxx> 40 #include <toolkit/awt/vclxfont.hxx> 41 #include <toolkit/helper/externallock.hxx> 42 #include <toolkit/helper/convert.hxx> 43 #include <toolkit/helper/vclunohelper.hxx> 44 #include <vcl/svapp.hxx> 45 46 using namespace ::com::sun::star; 47 using namespace ::com::sun::star::uno; 48 using namespace ::com::sun::star::lang; 49 using namespace ::com::sun::star::beans; 50 using namespace ::com::sun::star::accessibility; 51 using namespace ::comphelper; 52 53 54 // ----------------------------------------------------------------------------- 55 // class AccessibleDialogControlShape 56 // ----------------------------------------------------------------------------- 57 58 AccessibleDialogControlShape::AccessibleDialogControlShape( DialogWindow* pDialogWindow, DlgEdObj* pDlgEdObj ) 59 :AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() ) 60 ,m_pDialogWindow( pDialogWindow ) 61 ,m_pDlgEdObj( pDlgEdObj ) 62 { 63 m_pExternalLock = static_cast< VCLExternalSolarLock* >( getExternalLock() ); 64 65 if ( m_pDlgEdObj ) 66 m_xControlModel = Reference< XPropertySet >( m_pDlgEdObj->GetUnoControlModel(), UNO_QUERY ); 67 68 if ( m_xControlModel.is() ) 69 m_xControlModel->addPropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) ); 70 71 m_bFocused = IsFocused(); 72 m_bSelected = IsSelected(); 73 m_aBounds = GetBounds(); 74 } 75 76 // ----------------------------------------------------------------------------- 77 78 AccessibleDialogControlShape::~AccessibleDialogControlShape() 79 { 80 if ( m_xControlModel.is() ) 81 m_xControlModel->removePropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) ); 82 83 delete m_pExternalLock; 84 m_pExternalLock = NULL; 85 } 86 87 // ----------------------------------------------------------------------------- 88 89 sal_Bool AccessibleDialogControlShape::IsFocused() 90 { 91 sal_Bool bFocused = sal_False; 92 if ( m_pDialogWindow ) 93 { 94 SdrView* pSdrView = m_pDialogWindow->GetView(); 95 if ( pSdrView && pSdrView->IsObjMarked( m_pDlgEdObj ) && pSdrView->GetMarkedObjectList().GetMarkCount() == 1 ) 96 bFocused = sal_True; 97 } 98 99 return bFocused; 100 } 101 102 // ----------------------------------------------------------------------------- 103 104 sal_Bool AccessibleDialogControlShape::IsSelected() 105 { 106 sal_Bool bSelected = sal_False; 107 if ( m_pDialogWindow ) 108 { 109 SdrView* pSdrView = m_pDialogWindow->GetView(); 110 if ( pSdrView ) 111 bSelected = pSdrView->IsObjMarked( m_pDlgEdObj ); 112 } 113 114 return bSelected; 115 } 116 117 // ----------------------------------------------------------------------------- 118 119 void AccessibleDialogControlShape::SetFocused( sal_Bool bFocused ) 120 { 121 if ( m_bFocused != bFocused ) 122 { 123 Any aOldValue, aNewValue; 124 if ( m_bFocused ) 125 aOldValue <<= AccessibleStateType::FOCUSED; 126 else 127 aNewValue <<= AccessibleStateType::FOCUSED; 128 m_bFocused = bFocused; 129 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 130 } 131 } 132 133 // ----------------------------------------------------------------------------- 134 135 void AccessibleDialogControlShape::SetSelected( sal_Bool bSelected ) 136 { 137 if ( m_bSelected != bSelected ) 138 { 139 Any aOldValue, aNewValue; 140 if ( m_bSelected ) 141 aOldValue <<= AccessibleStateType::SELECTED; 142 else 143 aNewValue <<= AccessibleStateType::SELECTED; 144 m_bSelected = bSelected; 145 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 146 } 147 } 148 149 // ----------------------------------------------------------------------------- 150 151 awt::Rectangle AccessibleDialogControlShape::GetBounds() 152 { 153 awt::Rectangle aBounds( 0, 0, 0, 0 ); 154 if ( m_pDlgEdObj ) 155 { 156 // get the bounding box of the shape in logic units 157 Rectangle aRect = m_pDlgEdObj->GetSnapRect(); 158 159 if ( m_pDialogWindow ) 160 { 161 // transform coordinates relative to the parent 162 MapMode aMap = m_pDialogWindow->GetMapMode(); 163 Point aOrg = aMap.GetOrigin(); 164 aRect.Move( aOrg.X(), aOrg.Y() ); 165 166 // convert logic units to pixel 167 aRect = m_pDialogWindow->LogicToPixel( aRect, MapMode(MAP_100TH_MM) ); 168 169 // clip the shape's bounding box with the bounding box of its parent 170 Rectangle aParentRect( Point( 0, 0 ), m_pDialogWindow->GetSizePixel() ); 171 aRect = aRect.GetIntersection( aParentRect ); 172 aBounds = AWTRectangle( aRect ); 173 } 174 } 175 176 return aBounds; 177 } 178 179 // ----------------------------------------------------------------------------- 180 181 void AccessibleDialogControlShape::SetBounds( const awt::Rectangle& aBounds ) 182 { 183 if ( m_aBounds.X != aBounds.X || m_aBounds.Y != aBounds.Y || m_aBounds.Width != aBounds.Width || m_aBounds.Height != aBounds.Height ) 184 { 185 m_aBounds = aBounds; 186 NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any() ); 187 } 188 } 189 190 // ----------------------------------------------------------------------------- 191 192 Window* AccessibleDialogControlShape::GetWindow() const 193 { 194 Window* pWindow = NULL; 195 if ( m_pDlgEdObj ) 196 { 197 Reference< awt::XControl > xControl( m_pDlgEdObj->GetControl(), UNO_QUERY ); 198 if ( xControl.is() ) 199 pWindow = VCLUnoHelper::GetWindow( xControl->getPeer() ); 200 } 201 202 return pWindow; 203 } 204 205 // ----------------------------------------------------------------------------- 206 207 ::rtl::OUString AccessibleDialogControlShape::GetModelStringProperty( const sal_Char* pPropertyName ) 208 { 209 ::rtl::OUString sReturn; 210 211 try 212 { 213 if ( m_xControlModel.is() ) 214 { 215 ::rtl::OUString sPropertyName( ::rtl::OUString::createFromAscii( pPropertyName ) ); 216 Reference< XPropertySetInfo > xInfo = m_xControlModel->getPropertySetInfo(); 217 if ( xInfo.is() && xInfo->hasPropertyByName( sPropertyName ) ) 218 m_xControlModel->getPropertyValue( sPropertyName ) >>= sReturn; 219 } 220 } 221 catch ( const Exception& ) 222 { 223 OSL_ENSURE( sal_False, "AccessibleDialogControlShape::GetModelStringProperty: caught an exception!" ); 224 } 225 226 return sReturn; 227 } 228 229 // ----------------------------------------------------------------------------- 230 231 void AccessibleDialogControlShape::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 232 { 233 rStateSet.AddState( AccessibleStateType::ENABLED ); 234 235 rStateSet.AddState( AccessibleStateType::VISIBLE ); 236 237 rStateSet.AddState( AccessibleStateType::SHOWING ); 238 239 rStateSet.AddState( AccessibleStateType::FOCUSABLE ); 240 241 if ( IsFocused() ) 242 rStateSet.AddState( AccessibleStateType::FOCUSED ); 243 244 rStateSet.AddState( AccessibleStateType::SELECTABLE ); 245 246 if ( IsSelected() ) 247 rStateSet.AddState( AccessibleStateType::SELECTED ); 248 249 rStateSet.AddState( AccessibleStateType::RESIZABLE ); 250 } 251 252 // ----------------------------------------------------------------------------- 253 // OCommonAccessibleComponent 254 // ----------------------------------------------------------------------------- 255 256 awt::Rectangle AccessibleDialogControlShape::implGetBounds() throw (RuntimeException) 257 { 258 return GetBounds(); 259 } 260 261 // ----------------------------------------------------------------------------- 262 // XInterface 263 // ----------------------------------------------------------------------------- 264 265 IMPLEMENT_FORWARD_XINTERFACE2( AccessibleDialogControlShape, AccessibleExtendedComponentHelper_BASE, AccessibleDialogControlShape_BASE ) 266 267 // ----------------------------------------------------------------------------- 268 // XTypeProvider 269 // ----------------------------------------------------------------------------- 270 271 IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleDialogControlShape, AccessibleExtendedComponentHelper_BASE, AccessibleDialogControlShape_BASE ) 272 273 // ----------------------------------------------------------------------------- 274 // XComponent 275 // ----------------------------------------------------------------------------- 276 277 void AccessibleDialogControlShape::disposing() 278 { 279 AccessibleExtendedComponentHelper_BASE::disposing(); 280 281 m_pDialogWindow = NULL; 282 m_pDlgEdObj = NULL; 283 284 if ( m_xControlModel.is() ) 285 m_xControlModel->removePropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) ); 286 m_xControlModel.clear(); 287 } 288 289 // ----------------------------------------------------------------------------- 290 // XEventListener 291 // ----------------------------------------------------------------------------- 292 293 void AccessibleDialogControlShape::disposing( const lang::EventObject& ) throw (RuntimeException) 294 { 295 if ( m_xControlModel.is() ) 296 m_xControlModel->removePropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) ); 297 m_xControlModel.clear(); 298 } 299 300 // ----------------------------------------------------------------------------- 301 // XPropertyChangeListener 302 // ----------------------------------------------------------------------------- 303 304 void AccessibleDialogControlShape::propertyChange( const beans::PropertyChangeEvent& rEvent ) throw (RuntimeException) 305 { 306 if ( rEvent.PropertyName == DLGED_PROP_NAME ) 307 { 308 NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, rEvent.OldValue, rEvent.NewValue ); 309 } 310 else if ( rEvent.PropertyName == DLGED_PROP_POSITIONX || 311 rEvent.PropertyName == DLGED_PROP_POSITIONY || 312 rEvent.PropertyName == DLGED_PROP_WIDTH || 313 rEvent.PropertyName == DLGED_PROP_HEIGHT ) 314 { 315 SetBounds( GetBounds() ); 316 } 317 else if ( rEvent.PropertyName == DLGED_PROP_BACKGROUNDCOLOR || 318 rEvent.PropertyName == DLGED_PROP_TEXTCOLOR || 319 rEvent.PropertyName == DLGED_PROP_TEXTLINECOLOR ) 320 { 321 NotifyAccessibleEvent( AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any() ); 322 } 323 } 324 325 // ----------------------------------------------------------------------------- 326 // XServiceInfo 327 // ----------------------------------------------------------------------------- 328 329 ::rtl::OUString AccessibleDialogControlShape::getImplementationName() throw (RuntimeException) 330 { 331 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.basctl.AccessibleShape" ); 332 } 333 334 // ----------------------------------------------------------------------------- 335 336 sal_Bool AccessibleDialogControlShape::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) 337 { 338 Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); 339 const ::rtl::OUString* pNames = aNames.getConstArray(); 340 const ::rtl::OUString* pEnd = pNames + aNames.getLength(); 341 for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) 342 ; 343 344 return pNames != pEnd; 345 } 346 347 // ----------------------------------------------------------------------------- 348 349 Sequence< ::rtl::OUString > AccessibleDialogControlShape::getSupportedServiceNames() throw (RuntimeException) 350 { 351 Sequence< ::rtl::OUString > aNames(1); 352 aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.drawing.AccessibleShape" ); 353 return aNames; 354 } 355 356 // ----------------------------------------------------------------------------- 357 // XAccessible 358 // ----------------------------------------------------------------------------- 359 360 Reference< XAccessibleContext > AccessibleDialogControlShape::getAccessibleContext( ) throw (RuntimeException) 361 { 362 OExternalLockGuard aGuard( this ); 363 364 return this; 365 } 366 367 // ----------------------------------------------------------------------------- 368 // XAccessibleContext 369 // ----------------------------------------------------------------------------- 370 371 sal_Int32 AccessibleDialogControlShape::getAccessibleChildCount() throw (RuntimeException) 372 { 373 OExternalLockGuard aGuard( this ); 374 375 return 0; 376 } 377 378 // ----------------------------------------------------------------------------- 379 380 Reference< XAccessible > AccessibleDialogControlShape::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) 381 { 382 OExternalLockGuard aGuard( this ); 383 384 if ( i < 0 || i >= getAccessibleChildCount() ) 385 throw IndexOutOfBoundsException(); 386 387 return Reference< XAccessible >(); 388 } 389 390 // ----------------------------------------------------------------------------- 391 392 Reference< XAccessible > AccessibleDialogControlShape::getAccessibleParent( ) throw (RuntimeException) 393 { 394 OExternalLockGuard aGuard( this ); 395 396 Reference< XAccessible > xParent; 397 if ( m_pDialogWindow ) 398 xParent = m_pDialogWindow->GetAccessible(); 399 400 return xParent; 401 } 402 403 // ----------------------------------------------------------------------------- 404 405 sal_Int32 AccessibleDialogControlShape::getAccessibleIndexInParent( ) throw (RuntimeException) 406 { 407 OExternalLockGuard aGuard( this ); 408 409 sal_Int32 nIndexInParent = -1; 410 Reference< XAccessible > xParent( getAccessibleParent() ); 411 if ( xParent.is() ) 412 { 413 Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); 414 if ( xParentContext.is() ) 415 { 416 for ( sal_Int32 i = 0, nCount = xParentContext->getAccessibleChildCount(); i < nCount; ++i ) 417 { 418 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) ); 419 if ( xChild.is() ) 420 { 421 Reference< XAccessibleContext > xChildContext = xChild->getAccessibleContext(); 422 if ( xChildContext == (XAccessibleContext*)this ) 423 { 424 nIndexInParent = i; 425 break; 426 } 427 } 428 } 429 } 430 } 431 432 return nIndexInParent; 433 } 434 435 // ----------------------------------------------------------------------------- 436 437 sal_Int16 AccessibleDialogControlShape::getAccessibleRole( ) throw (RuntimeException) 438 { 439 OExternalLockGuard aGuard( this ); 440 441 return AccessibleRole::SHAPE; 442 } 443 444 // ----------------------------------------------------------------------------- 445 446 ::rtl::OUString AccessibleDialogControlShape::getAccessibleDescription( ) throw (RuntimeException) 447 { 448 OExternalLockGuard aGuard( this ); 449 450 return GetModelStringProperty( "HelpText" ); 451 } 452 453 // ----------------------------------------------------------------------------- 454 455 ::rtl::OUString AccessibleDialogControlShape::getAccessibleName( ) throw (RuntimeException) 456 { 457 OExternalLockGuard aGuard( this ); 458 459 return GetModelStringProperty( "Name" ); 460 } 461 462 // ----------------------------------------------------------------------------- 463 464 Reference< XAccessibleRelationSet > AccessibleDialogControlShape::getAccessibleRelationSet( ) throw (RuntimeException) 465 { 466 OExternalLockGuard aGuard( this ); 467 468 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 469 Reference< XAccessibleRelationSet > xSet = pRelationSetHelper; 470 return xSet; 471 } 472 473 // ----------------------------------------------------------------------------- 474 475 Reference< XAccessibleStateSet > AccessibleDialogControlShape::getAccessibleStateSet( ) throw (RuntimeException) 476 { 477 OExternalLockGuard aGuard( this ); 478 479 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 480 Reference< XAccessibleStateSet > xSet = pStateSetHelper; 481 482 if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) 483 { 484 FillAccessibleStateSet( *pStateSetHelper ); 485 } 486 else 487 { 488 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 489 } 490 491 return xSet; 492 } 493 494 // ----------------------------------------------------------------------------- 495 496 Locale AccessibleDialogControlShape::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) 497 { 498 OExternalLockGuard aGuard( this ); 499 500 return Application::GetSettings().GetLocale(); 501 } 502 503 // ----------------------------------------------------------------------------- 504 // XAccessibleComponent 505 // ----------------------------------------------------------------------------- 506 507 Reference< XAccessible > AccessibleDialogControlShape::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException) 508 { 509 OExternalLockGuard aGuard( this ); 510 511 return Reference< XAccessible >(); 512 } 513 514 // ----------------------------------------------------------------------------- 515 516 void AccessibleDialogControlShape::grabFocus( ) throw (RuntimeException) 517 { 518 // no focus for shapes 519 } 520 521 // ----------------------------------------------------------------------------- 522 523 sal_Int32 AccessibleDialogControlShape::getForeground( ) throw (RuntimeException) 524 { 525 OExternalLockGuard aGuard( this ); 526 527 sal_Int32 nColor = 0; 528 Window* pWindow = GetWindow(); 529 if ( pWindow ) 530 { 531 if ( pWindow->IsControlForeground() ) 532 nColor = pWindow->GetControlForeground().GetColor(); 533 else 534 { 535 Font aFont; 536 if ( pWindow->IsControlFont() ) 537 aFont = pWindow->GetControlFont(); 538 else 539 aFont = pWindow->GetFont(); 540 nColor = aFont.GetColor().GetColor(); 541 } 542 } 543 544 return nColor; 545 } 546 547 // ----------------------------------------------------------------------------- 548 549 sal_Int32 AccessibleDialogControlShape::getBackground( ) throw (RuntimeException) 550 { 551 OExternalLockGuard aGuard( this ); 552 553 sal_Int32 nColor = 0; 554 Window* pWindow = GetWindow(); 555 if ( pWindow ) 556 { 557 if ( pWindow->IsControlBackground() ) 558 nColor = pWindow->GetControlBackground().GetColor(); 559 else 560 nColor = pWindow->GetBackground().GetColor().GetColor(); 561 } 562 563 return nColor; 564 } 565 566 // ----------------------------------------------------------------------------- 567 // XAccessibleExtendedComponent 568 // ----------------------------------------------------------------------------- 569 570 Reference< awt::XFont > AccessibleDialogControlShape::getFont( ) throw (RuntimeException) 571 { 572 OExternalLockGuard aGuard( this ); 573 574 Reference< awt::XFont > xFont; 575 Window* pWindow = GetWindow(); 576 if ( pWindow ) 577 { 578 Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), UNO_QUERY ); 579 if ( xDev.is() ) 580 { 581 Font aFont; 582 if ( pWindow->IsControlFont() ) 583 aFont = pWindow->GetControlFont(); 584 else 585 aFont = pWindow->GetFont(); 586 VCLXFont* pVCLXFont = new VCLXFont; 587 pVCLXFont->Init( *xDev.get(), aFont ); 588 xFont = pVCLXFont; 589 } 590 } 591 592 return xFont; 593 } 594 595 // ----------------------------------------------------------------------------- 596 597 ::rtl::OUString AccessibleDialogControlShape::getTitledBorderText( ) throw (RuntimeException) 598 { 599 OExternalLockGuard aGuard( this ); 600 601 return ::rtl::OUString(); 602 } 603 604 // ----------------------------------------------------------------------------- 605 606 ::rtl::OUString AccessibleDialogControlShape::getToolTipText( ) throw (RuntimeException) 607 { 608 OExternalLockGuard aGuard( this ); 609 610 ::rtl::OUString sText; 611 Window* pWindow = GetWindow(); 612 if ( pWindow ) 613 sText = pWindow->GetQuickHelpText(); 614 615 return sText; 616 } 617 618 // ----------------------------------------------------------------------------- 619 620