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_accessibility.hxx" 30 #include <accessibility/standard/accessiblemenucomponent.hxx> 31 32 #include <toolkit/awt/vclxfont.hxx> 33 #include <toolkit/helper/convert.hxx> 34 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 39 #include <unotools/accessiblestatesethelper.hxx> 40 #include <unotools/accessiblerelationsethelper.hxx> 41 #include <cppuhelper/typeprovider.hxx> 42 #include <comphelper/sequence.hxx> 43 #include <vcl/svapp.hxx> 44 #include <vcl/window.hxx> 45 #include <vcl/menu.hxx> 46 #include <vcl/unohelp2.hxx> 47 48 49 using namespace ::com::sun::star::accessibility; 50 using namespace ::com::sun::star::uno; 51 using namespace ::com::sun::star::lang; 52 using namespace ::com::sun::star; 53 using namespace ::comphelper; 54 55 56 // ----------------------------------------------------------------------------- 57 // class OAccessibleMenuComponent 58 // ----------------------------------------------------------------------------- 59 60 OAccessibleMenuComponent::OAccessibleMenuComponent( Menu* pMenu ) 61 :OAccessibleMenuBaseComponent( pMenu ) 62 { 63 } 64 65 // ----------------------------------------------------------------------------- 66 67 OAccessibleMenuComponent::~OAccessibleMenuComponent() 68 { 69 } 70 71 // ----------------------------------------------------------------------------- 72 73 sal_Bool OAccessibleMenuComponent::IsEnabled() 74 { 75 return sal_True; 76 } 77 78 // ----------------------------------------------------------------------------- 79 80 sal_Bool OAccessibleMenuComponent::IsVisible() 81 { 82 sal_Bool bVisible = sal_False; 83 84 if ( m_pMenu ) 85 bVisible = m_pMenu->IsMenuVisible(); 86 87 return bVisible; 88 } 89 90 // ----------------------------------------------------------------------------- 91 92 void OAccessibleMenuComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 93 { 94 if ( IsEnabled() ) 95 { 96 rStateSet.AddState( AccessibleStateType::ENABLED ); 97 rStateSet.AddState( AccessibleStateType::SENSITIVE ); 98 } 99 100 rStateSet.AddState( AccessibleStateType::FOCUSABLE ); 101 102 if ( IsFocused() ) 103 rStateSet.AddState( AccessibleStateType::FOCUSED ); 104 105 if ( IsVisible() ) 106 { 107 rStateSet.AddState( AccessibleStateType::VISIBLE ); 108 rStateSet.AddState( AccessibleStateType::SHOWING ); 109 } 110 111 rStateSet.AddState( AccessibleStateType::OPAQUE ); 112 } 113 114 // ----------------------------------------------------------------------------- 115 // OCommonAccessibleComponent 116 // ----------------------------------------------------------------------------- 117 118 awt::Rectangle OAccessibleMenuComponent::implGetBounds() throw (RuntimeException) 119 { 120 awt::Rectangle aBounds( 0, 0, 0, 0 ); 121 122 if ( m_pMenu ) 123 { 124 Window* pWindow = m_pMenu->GetWindow(); 125 if ( pWindow ) 126 { 127 // get bounding rectangle of the window in screen coordinates 128 Rectangle aRect = pWindow->GetWindowExtentsRelative( NULL ); 129 aBounds = AWTRectangle( aRect ); 130 131 // get position of the accessible parent in screen coordinates 132 Reference< XAccessible > xParent = getAccessibleParent(); 133 if ( xParent.is() ) 134 { 135 Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY ); 136 if ( xParentComponent.is() ) 137 { 138 awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen(); 139 140 // calculate position of the window relative to the accessible parent 141 aBounds.X -= aParentScreenLoc.X; 142 aBounds.Y -= aParentScreenLoc.Y; 143 } 144 } 145 } 146 } 147 148 return aBounds; 149 } 150 151 // ----------------------------------------------------------------------------- 152 // XInterface 153 // ----------------------------------------------------------------------------- 154 155 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleMenuComponent, OAccessibleMenuBaseComponent, OAccessibleMenuComponent_BASE ) 156 157 // ----------------------------------------------------------------------------- 158 // XTypeProvider 159 // ----------------------------------------------------------------------------- 160 161 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleMenuComponent, OAccessibleMenuBaseComponent, OAccessibleMenuComponent_BASE ) 162 163 // ----------------------------------------------------------------------------- 164 // XAccessibleContext 165 // ----------------------------------------------------------------------------- 166 167 sal_Int32 OAccessibleMenuComponent::getAccessibleChildCount() throw (RuntimeException) 168 { 169 OExternalLockGuard aGuard( this ); 170 171 return GetChildCount(); 172 } 173 174 // ----------------------------------------------------------------------------- 175 176 Reference< XAccessible > OAccessibleMenuComponent::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) 177 { 178 OExternalLockGuard aGuard( this ); 179 180 if ( i < 0 || i >= GetChildCount() ) 181 throw IndexOutOfBoundsException(); 182 183 return GetChild( i ); 184 } 185 186 // ----------------------------------------------------------------------------- 187 188 Reference< XAccessible > OAccessibleMenuComponent::getAccessibleParent( ) throw (RuntimeException) 189 { 190 OExternalLockGuard aGuard( this ); 191 192 Reference< XAccessible > xParent; 193 194 if ( m_pMenu ) 195 { 196 Window* pWindow = m_pMenu->GetWindow(); 197 if ( pWindow ) 198 { 199 Window* pParent = pWindow->GetAccessibleParentWindow(); 200 if ( pParent ) 201 xParent = pParent->GetAccessible(); 202 } 203 } 204 205 return xParent; 206 } 207 208 // ----------------------------------------------------------------------------- 209 210 sal_Int16 OAccessibleMenuComponent::getAccessibleRole( ) throw (RuntimeException) 211 { 212 OExternalLockGuard aGuard( this ); 213 214 return AccessibleRole::UNKNOWN; 215 } 216 217 // ----------------------------------------------------------------------------- 218 219 ::rtl::OUString OAccessibleMenuComponent::getAccessibleDescription( ) throw (RuntimeException) 220 { 221 OExternalLockGuard aGuard( this ); 222 223 ::rtl::OUString sDescription; 224 if ( m_pMenu ) 225 { 226 Window* pWindow = m_pMenu->GetWindow(); 227 if ( pWindow ) 228 sDescription = pWindow->GetAccessibleDescription(); 229 } 230 231 return sDescription; 232 } 233 234 // ----------------------------------------------------------------------------- 235 236 ::rtl::OUString OAccessibleMenuComponent::getAccessibleName( ) throw (RuntimeException) 237 { 238 OExternalLockGuard aGuard( this ); 239 240 return ::rtl::OUString(); 241 } 242 243 // ----------------------------------------------------------------------------- 244 245 Reference< XAccessibleRelationSet > OAccessibleMenuComponent::getAccessibleRelationSet( ) throw (RuntimeException) 246 { 247 OExternalLockGuard aGuard( this ); 248 249 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 250 Reference< XAccessibleRelationSet > xSet = pRelationSetHelper; 251 return xSet; 252 } 253 254 // ----------------------------------------------------------------------------- 255 256 Locale OAccessibleMenuComponent::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) 257 { 258 OExternalLockGuard aGuard( this ); 259 260 return Application::GetSettings().GetLocale(); 261 } 262 263 // ----------------------------------------------------------------------------- 264 // XAccessibleComponent 265 // ----------------------------------------------------------------------------- 266 267 Reference< XAccessible > OAccessibleMenuComponent::getAccessibleAtPoint( const awt::Point& rPoint ) throw (RuntimeException) 268 { 269 OExternalLockGuard aGuard( this ); 270 271 return GetChildAt( rPoint ); 272 } 273 274 // ----------------------------------------------------------------------------- 275 276 awt::Point OAccessibleMenuComponent::getLocationOnScreen( ) throw (RuntimeException) 277 { 278 OExternalLockGuard aGuard( this ); 279 280 awt::Point aPos; 281 282 if ( m_pMenu ) 283 { 284 Window* pWindow = m_pMenu->GetWindow(); 285 if ( pWindow ) 286 { 287 Rectangle aRect = pWindow->GetWindowExtentsRelative( NULL ); 288 aPos = AWTPoint( aRect.TopLeft() ); 289 } 290 } 291 292 return aPos; 293 } 294 295 // ----------------------------------------------------------------------------- 296 297 void OAccessibleMenuComponent::grabFocus( ) throw (RuntimeException) 298 { 299 OExternalLockGuard aGuard( this ); 300 301 if ( m_pMenu ) 302 { 303 Window* pWindow = m_pMenu->GetWindow(); 304 if ( pWindow ) 305 pWindow->GrabFocus(); 306 } 307 } 308 309 // ----------------------------------------------------------------------------- 310 311 sal_Int32 OAccessibleMenuComponent::getForeground( ) throw (RuntimeException) 312 { 313 OExternalLockGuard aGuard( this ); 314 315 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 316 sal_Int32 nColor = rStyleSettings.GetMenuTextColor().GetColor(); 317 318 return nColor; 319 } 320 321 // ----------------------------------------------------------------------------- 322 323 sal_Int32 OAccessibleMenuComponent::getBackground( ) throw (RuntimeException) 324 { 325 OExternalLockGuard aGuard( this ); 326 327 return 0; 328 } 329 330 // ----------------------------------------------------------------------------- 331 // XAccessibleExtendedComponent 332 // ----------------------------------------------------------------------------- 333 334 Reference< awt::XFont > OAccessibleMenuComponent::getFont( ) throw (RuntimeException) 335 { 336 OExternalLockGuard aGuard( this ); 337 338 Reference< awt::XFont > xFont; 339 340 if ( m_pMenu ) 341 { 342 Window* pWindow = m_pMenu->GetWindow(); 343 if ( pWindow ) 344 { 345 Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), UNO_QUERY ); 346 if ( xDev.is() ) 347 { 348 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 349 VCLXFont* pVCLXFont = new VCLXFont; 350 pVCLXFont->Init( *xDev.get(), rStyleSettings.GetMenuFont() ); 351 xFont = pVCLXFont; 352 } 353 } 354 } 355 356 return xFont; 357 } 358 359 // ----------------------------------------------------------------------------- 360 361 ::rtl::OUString OAccessibleMenuComponent::getTitledBorderText( ) throw (RuntimeException) 362 { 363 OExternalLockGuard aGuard( this ); 364 365 return ::rtl::OUString(); 366 } 367 368 // ----------------------------------------------------------------------------- 369 370 ::rtl::OUString OAccessibleMenuComponent::getToolTipText( ) throw (RuntimeException) 371 { 372 OExternalLockGuard aGuard( this ); 373 374 return ::rtl::OUString(); 375 } 376 377 // ----------------------------------------------------------------------------- 378 // XAccessibleSelection 379 // ----------------------------------------------------------------------------- 380 381 void OAccessibleMenuComponent::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 382 { 383 OExternalLockGuard aGuard( this ); 384 385 if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) 386 throw IndexOutOfBoundsException(); 387 388 SelectChild( nChildIndex ); 389 } 390 391 // ----------------------------------------------------------------------------- 392 393 sal_Bool OAccessibleMenuComponent::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 394 { 395 OExternalLockGuard aGuard( this ); 396 397 if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) 398 throw IndexOutOfBoundsException(); 399 400 return IsChildSelected( nChildIndex ); 401 } 402 403 // ----------------------------------------------------------------------------- 404 405 void OAccessibleMenuComponent::clearAccessibleSelection( ) throw (RuntimeException) 406 { 407 OExternalLockGuard aGuard( this ); 408 409 DeSelectAll(); 410 } 411 412 // ----------------------------------------------------------------------------- 413 414 void OAccessibleMenuComponent::selectAllAccessibleChildren( ) throw (RuntimeException) 415 { 416 // This method makes no sense in a menu, and so does nothing. 417 } 418 419 // ----------------------------------------------------------------------------- 420 421 sal_Int32 OAccessibleMenuComponent::getSelectedAccessibleChildCount( ) throw (RuntimeException) 422 { 423 OExternalLockGuard aGuard( this ); 424 425 sal_Int32 nRet = 0; 426 427 for ( sal_Int32 i = 0, nCount = GetChildCount(); i < nCount; i++ ) 428 { 429 if ( IsChildSelected( i ) ) 430 ++nRet; 431 } 432 433 return nRet; 434 } 435 436 // ----------------------------------------------------------------------------- 437 438 Reference< XAccessible > OAccessibleMenuComponent::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 439 { 440 OExternalLockGuard aGuard( this ); 441 442 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) 443 throw IndexOutOfBoundsException(); 444 445 Reference< XAccessible > xChild; 446 447 for ( sal_Int32 i = 0, j = 0, nCount = GetChildCount(); i < nCount; i++ ) 448 { 449 if ( IsChildSelected( i ) && ( j++ == nSelectedChildIndex ) ) 450 { 451 xChild = GetChild( i ); 452 break; 453 } 454 } 455 456 return xChild; 457 } 458 459 // ----------------------------------------------------------------------------- 460 461 void OAccessibleMenuComponent::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 462 { 463 OExternalLockGuard aGuard( this ); 464 465 if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) 466 throw IndexOutOfBoundsException(); 467 468 DeSelectAll(); 469 } 470 471 // ----------------------------------------------------------------------------- 472