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/accessiblemenuitemcomponent.hxx> 31 32 33 #include <accessibility/helper/accresmgr.hxx> 34 #include <accessibility/helper/accessiblestrings.hrc> 35 #include <toolkit/awt/vclxwindows.hxx> 36 #include <toolkit/helper/externallock.hxx> 37 #include <toolkit/helper/convert.hxx> 38 39 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 40 #include <com/sun/star/accessibility/AccessibleRole.hpp> 41 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 42 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> 43 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> 44 45 #include <unotools/accessiblestatesethelper.hxx> 46 #include <unotools/accessiblerelationsethelper.hxx> 47 #include <cppuhelper/typeprovider.hxx> 48 #include <comphelper/sequence.hxx> 49 #include <comphelper/accessibletexthelper.hxx> 50 #include <vcl/svapp.hxx> 51 #include <vcl/window.hxx> 52 #include <vcl/menu.hxx> 53 #include <vcl/unohelp2.hxx> 54 55 56 using namespace ::com::sun::star::accessibility; 57 using namespace ::com::sun::star::uno; 58 using namespace ::com::sun::star::beans; 59 using namespace ::com::sun::star::lang; 60 using namespace ::com::sun::star; 61 using namespace ::comphelper; 62 63 64 // ----------------------------------------------------------------------------- 65 // class OAccessibleMenuItemComponent 66 // ----------------------------------------------------------------------------- 67 68 OAccessibleMenuItemComponent::OAccessibleMenuItemComponent( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu ) 69 :OAccessibleMenuBaseComponent( pMenu ) 70 ,m_pParent( pParent ) 71 ,m_nItemPos( nItemPos ) 72 { 73 m_sAccessibleName = GetAccessibleName(); 74 m_sItemText = GetItemText(); 75 } 76 77 // ----------------------------------------------------------------------------- 78 79 OAccessibleMenuItemComponent::~OAccessibleMenuItemComponent() 80 { 81 } 82 83 // ----------------------------------------------------------------------------- 84 85 sal_Bool OAccessibleMenuItemComponent::IsEnabled() 86 { 87 OExternalLockGuard aGuard( this ); 88 89 sal_Bool bEnabled = sal_False; 90 if ( m_pParent ) 91 bEnabled = m_pParent->IsItemEnabled( m_pParent->GetItemId( m_nItemPos ) ); 92 93 return bEnabled; 94 } 95 96 // ----------------------------------------------------------------------------- 97 98 sal_Bool OAccessibleMenuItemComponent::IsVisible() 99 { 100 sal_Bool bVisible = sal_False; 101 102 if ( m_pParent ) 103 bVisible = m_pParent->IsItemPosVisible( m_nItemPos ); 104 105 return bVisible; 106 } 107 108 // ----------------------------------------------------------------------------- 109 110 void OAccessibleMenuItemComponent::Select() 111 { 112 // open the parent menu 113 Reference< XAccessible > xParent( getAccessibleParent() ); 114 if ( xParent.is() ) 115 { 116 OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xParent.get() ); 117 if ( pComp && pComp->getAccessibleRole() == AccessibleRole::MENU && !pComp->IsPopupMenuOpen() ) 118 pComp->Click(); 119 } 120 121 // highlight the menu item 122 if ( m_pParent ) 123 m_pParent->HighlightItem( m_nItemPos ); 124 } 125 126 // ----------------------------------------------------------------------------- 127 128 void OAccessibleMenuItemComponent::DeSelect() 129 { 130 if ( m_pParent && IsSelected() ) 131 m_pParent->DeHighlight(); 132 } 133 134 // ----------------------------------------------------------------------------- 135 136 void OAccessibleMenuItemComponent::Click() 137 { 138 // open the parent menu 139 Reference< XAccessible > xParent( getAccessibleParent() ); 140 if ( xParent.is() ) 141 { 142 OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xParent.get() ); 143 if ( pComp && pComp->getAccessibleRole() == AccessibleRole::MENU && !pComp->IsPopupMenuOpen() ) 144 pComp->Click(); 145 } 146 147 // click the menu item 148 if ( m_pParent ) 149 { 150 Window* pWindow = m_pParent->GetWindow(); 151 if ( pWindow ) 152 { 153 // #102438# Menu items are not selectable 154 // Popup menus are executed asynchronously, triggered by a timer. 155 // As Menu::SelectItem only works, if the corresponding menu window is 156 // already created, we have to set the menu delay to 0, so 157 // that the popup menus are executed synchronously. 158 AllSettings aSettings = pWindow->GetSettings(); 159 MouseSettings aMouseSettings = aSettings.GetMouseSettings(); 160 sal_uLong nDelay = aMouseSettings.GetMenuDelay(); 161 aMouseSettings.SetMenuDelay( 0 ); 162 aSettings.SetMouseSettings( aMouseSettings ); 163 pWindow->SetSettings( aSettings ); 164 165 m_pParent->SelectItem( m_pParent->GetItemId( m_nItemPos ) ); 166 167 // meanwhile the window pointer may be invalid 168 pWindow = m_pParent->GetWindow(); 169 if ( pWindow ) 170 { 171 // set the menu delay back to the old value 172 aSettings = pWindow->GetSettings(); 173 aMouseSettings = aSettings.GetMouseSettings(); 174 aMouseSettings.SetMenuDelay( nDelay ); 175 aSettings.SetMouseSettings( aMouseSettings ); 176 pWindow->SetSettings( aSettings ); 177 } 178 } 179 } 180 } 181 182 // ----------------------------------------------------------------------------- 183 184 void OAccessibleMenuItemComponent::SetItemPos( sal_uInt16 nItemPos ) 185 { 186 m_nItemPos = nItemPos; 187 } 188 189 // ----------------------------------------------------------------------------- 190 191 void OAccessibleMenuItemComponent::SetAccessibleName( const ::rtl::OUString& sAccessibleName ) 192 { 193 if ( !m_sAccessibleName.equals( sAccessibleName ) ) 194 { 195 Any aOldValue, aNewValue; 196 aOldValue <<= m_sAccessibleName; 197 aNewValue <<= sAccessibleName; 198 m_sAccessibleName = sAccessibleName; 199 NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); 200 } 201 } 202 203 // ----------------------------------------------------------------------------- 204 205 ::rtl::OUString OAccessibleMenuItemComponent::GetAccessibleName() 206 { 207 ::rtl::OUString sName; 208 if ( m_pParent ) 209 { 210 sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos ); 211 sName = m_pParent->GetAccessibleName( nItemId ); 212 if ( sName.getLength() == 0 ) 213 sName = m_pParent->GetItemText( nItemId ); 214 sName = OutputDevice::GetNonMnemonicString( sName ); 215 } 216 217 return sName; 218 } 219 220 // ----------------------------------------------------------------------------- 221 222 void OAccessibleMenuItemComponent::SetItemText( const ::rtl::OUString& sItemText ) 223 { 224 Any aOldValue, aNewValue; 225 if ( OCommonAccessibleText::implInitTextChangedEvent( m_sItemText, sItemText, aOldValue, aNewValue ) ) 226 { 227 m_sItemText = sItemText; 228 NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue ); 229 } 230 } 231 232 // ----------------------------------------------------------------------------- 233 234 ::rtl::OUString OAccessibleMenuItemComponent::GetItemText() 235 { 236 ::rtl::OUString sText; 237 if ( m_pParent ) 238 sText = OutputDevice::GetNonMnemonicString( m_pParent->GetItemText( m_pParent->GetItemId( m_nItemPos ) ) ); 239 240 return sText; 241 } 242 243 // ----------------------------------------------------------------------------- 244 245 void OAccessibleMenuItemComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 246 { 247 if ( IsEnabled() ) 248 { 249 rStateSet.AddState( AccessibleStateType::ENABLED ); 250 rStateSet.AddState( AccessibleStateType::SENSITIVE ); 251 } 252 253 if ( IsVisible() ) 254 { 255 rStateSet.AddState( AccessibleStateType::VISIBLE ); 256 rStateSet.AddState( AccessibleStateType::SHOWING ); 257 } 258 259 rStateSet.AddState( AccessibleStateType::OPAQUE ); 260 } 261 262 // ----------------------------------------------------------------------------- 263 // OCommonAccessibleComponent 264 // ----------------------------------------------------------------------------- 265 266 awt::Rectangle OAccessibleMenuItemComponent::implGetBounds() throw (RuntimeException) 267 { 268 awt::Rectangle aBounds( 0, 0, 0, 0 ); 269 270 if ( m_pParent ) 271 { 272 // get bounding rectangle of the item relative to the containing window 273 aBounds = AWTRectangle( m_pParent->GetBoundingRectangle( m_nItemPos ) ); 274 275 // get position of containing window in screen coordinates 276 Window* pWindow = m_pParent->GetWindow(); 277 if ( pWindow ) 278 { 279 Rectangle aRect = pWindow->GetWindowExtentsRelative( NULL ); 280 awt::Point aWindowScreenLoc = AWTPoint( aRect.TopLeft() ); 281 282 // get position of accessible parent in screen coordinates 283 Reference< XAccessible > xParent = getAccessibleParent(); 284 if ( xParent.is() ) 285 { 286 Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY ); 287 if ( xParentComponent.is() ) 288 { 289 awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen(); 290 291 // calculate bounding rectangle of the item relative to the accessible parent 292 aBounds.X += aWindowScreenLoc.X - aParentScreenLoc.X; 293 aBounds.Y += aWindowScreenLoc.Y - aParentScreenLoc.Y; 294 } 295 } 296 } 297 } 298 299 return aBounds; 300 } 301 302 // ----------------------------------------------------------------------------- 303 // XComponent 304 // ----------------------------------------------------------------------------- 305 306 void SAL_CALL OAccessibleMenuItemComponent::disposing() 307 { 308 OAccessibleMenuBaseComponent::disposing(); 309 310 m_pParent = NULL; 311 m_sAccessibleName = ::rtl::OUString(); 312 m_sItemText = ::rtl::OUString(); 313 } 314 315 // ----------------------------------------------------------------------------- 316 // XAccessibleContext 317 // ----------------------------------------------------------------------------- 318 319 sal_Int32 OAccessibleMenuItemComponent::getAccessibleChildCount() throw (RuntimeException) 320 { 321 OExternalLockGuard aGuard( this ); 322 323 return 0; 324 } 325 326 // ----------------------------------------------------------------------------- 327 328 Reference< XAccessible > OAccessibleMenuItemComponent::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) 329 { 330 OExternalLockGuard aGuard( this ); 331 332 if ( i < 0 || i >= getAccessibleChildCount() ) 333 throw IndexOutOfBoundsException(); 334 335 return Reference< XAccessible >(); 336 } 337 338 // ----------------------------------------------------------------------------- 339 340 Reference< XAccessible > OAccessibleMenuItemComponent::getAccessibleParent( ) throw (RuntimeException) 341 { 342 OExternalLockGuard aGuard( this ); 343 344 return m_pParent->GetAccessible(); 345 } 346 347 // ----------------------------------------------------------------------------- 348 349 sal_Int32 OAccessibleMenuItemComponent::getAccessibleIndexInParent( ) throw (RuntimeException) 350 { 351 OExternalLockGuard aGuard( this ); 352 353 return m_nItemPos; 354 } 355 356 // ----------------------------------------------------------------------------- 357 358 sal_Int16 OAccessibleMenuItemComponent::getAccessibleRole( ) throw (RuntimeException) 359 { 360 OExternalLockGuard aGuard( this ); 361 362 return AccessibleRole::UNKNOWN; 363 } 364 365 // ----------------------------------------------------------------------------- 366 367 ::rtl::OUString OAccessibleMenuItemComponent::getAccessibleDescription( ) throw (RuntimeException) 368 { 369 OExternalLockGuard aGuard( this ); 370 371 ::rtl::OUString sDescription; 372 if ( m_pParent ) 373 sDescription = m_pParent->GetHelpText( m_pParent->GetItemId( m_nItemPos ) ); 374 375 return sDescription; 376 } 377 378 // ----------------------------------------------------------------------------- 379 380 ::rtl::OUString OAccessibleMenuItemComponent::getAccessibleName( ) throw (RuntimeException) 381 { 382 OExternalLockGuard aGuard( this ); 383 384 return m_sAccessibleName; 385 } 386 387 // ----------------------------------------------------------------------------- 388 389 Reference< XAccessibleRelationSet > OAccessibleMenuItemComponent::getAccessibleRelationSet( ) throw (RuntimeException) 390 { 391 OExternalLockGuard aGuard( this ); 392 393 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 394 Reference< XAccessibleRelationSet > xSet = pRelationSetHelper; 395 return xSet; 396 } 397 398 // ----------------------------------------------------------------------------- 399 400 Locale OAccessibleMenuItemComponent::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) 401 { 402 OExternalLockGuard aGuard( this ); 403 404 return Application::GetSettings().GetLocale(); 405 } 406 407 // ----------------------------------------------------------------------------- 408 // XAccessibleComponent 409 // ----------------------------------------------------------------------------- 410 411 Reference< XAccessible > OAccessibleMenuItemComponent::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException) 412 { 413 OExternalLockGuard aGuard( this ); 414 415 return Reference< XAccessible >(); 416 } 417 418 // ----------------------------------------------------------------------------- 419 420 void OAccessibleMenuItemComponent::grabFocus( ) throw (RuntimeException) 421 { 422 // no focus for items 423 } 424 425 // ----------------------------------------------------------------------------- 426 427 sal_Int32 OAccessibleMenuItemComponent::getForeground( ) throw (RuntimeException) 428 { 429 OExternalLockGuard aGuard( this ); 430 431 sal_Int32 nColor = 0; 432 Reference< XAccessible > xParent = getAccessibleParent(); 433 if ( xParent.is() ) 434 { 435 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); 436 if ( xParentComp.is() ) 437 nColor = xParentComp->getForeground(); 438 } 439 440 return nColor; 441 } 442 443 // ----------------------------------------------------------------------------- 444 445 sal_Int32 OAccessibleMenuItemComponent::getBackground( ) throw (RuntimeException) 446 { 447 OExternalLockGuard aGuard( this ); 448 449 sal_Int32 nColor = 0; 450 Reference< XAccessible > xParent = getAccessibleParent(); 451 if ( xParent.is() ) 452 { 453 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); 454 if ( xParentComp.is() ) 455 nColor = xParentComp->getBackground(); 456 } 457 458 return nColor; 459 } 460 461 // ----------------------------------------------------------------------------- 462 // XAccessibleExtendedComponent 463 // ----------------------------------------------------------------------------- 464 465 Reference< awt::XFont > OAccessibleMenuItemComponent::getFont( ) throw (RuntimeException) 466 { 467 OExternalLockGuard aGuard( this ); 468 469 Reference< awt::XFont > xFont; 470 Reference< XAccessible > xParent = getAccessibleParent(); 471 if ( xParent.is() ) 472 { 473 Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); 474 if ( xParentComp.is() ) 475 xFont = xParentComp->getFont(); 476 } 477 478 return xFont; 479 } 480 481 // ----------------------------------------------------------------------------- 482 483 ::rtl::OUString OAccessibleMenuItemComponent::getTitledBorderText( ) throw (RuntimeException) 484 { 485 OExternalLockGuard aGuard( this ); 486 487 return ::rtl::OUString(); 488 } 489 490 // ----------------------------------------------------------------------------- 491 492 ::rtl::OUString OAccessibleMenuItemComponent::getToolTipText( ) throw (RuntimeException) 493 { 494 OExternalLockGuard aGuard( this ); 495 496 ::rtl::OUString sRet; 497 if ( m_pParent ) 498 sRet = m_pParent->GetTipHelpText( m_pParent->GetItemId( m_nItemPos ) ); 499 500 return sRet; 501 } 502 503 // ----------------------------------------------------------------------------- 504