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