1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_accessibility.hxx" 28 29 #include "accessibility/extended/AccessibleToolPanelDeckTabBarItem.hxx" 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/accessibility/AccessibleRole.hpp> 33 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 34 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 35 #include <com/sun/star/lang/DisposedException.hpp> 36 /** === end UNO includes === **/ 37 38 #include <svtools/toolpanel/toolpaneldeck.hxx> 39 #include <svtools/toolpanel/paneltabbar.hxx> 40 #include <unotools/accessiblestatesethelper.hxx> 41 #include <unotools/accessiblerelationsethelper.hxx> 42 #include <tools/diagnose_ex.h> 43 #include <vcl/svapp.hxx> 44 #include <vos/mutex.hxx> 45 46 //...................................................................................................................... 47 namespace accessibility 48 { 49 //...................................................................................................................... 50 51 typedef ::com::sun::star::awt::Rectangle UnoRectangle; 52 typedef ::com::sun::star::awt::Point UnoPoint; 53 54 /** === begin UNO using === **/ 55 using ::com::sun::star::uno::Reference; 56 using ::com::sun::star::uno::XInterface; 57 using ::com::sun::star::uno::UNO_QUERY; 58 using ::com::sun::star::uno::UNO_QUERY_THROW; 59 using ::com::sun::star::uno::UNO_SET_THROW; 60 using ::com::sun::star::uno::Exception; 61 using ::com::sun::star::uno::RuntimeException; 62 using ::com::sun::star::uno::Any; 63 using ::com::sun::star::uno::makeAny; 64 using ::com::sun::star::uno::Sequence; 65 using ::com::sun::star::uno::Type; 66 using ::com::sun::star::accessibility::XAccessible; 67 using ::com::sun::star::lang::DisposedException; 68 using ::com::sun::star::lang::IndexOutOfBoundsException; 69 using ::com::sun::star::accessibility::XAccessibleRelationSet; 70 using ::com::sun::star::accessibility::XAccessibleStateSet; 71 using ::com::sun::star::accessibility::XAccessibleComponent; 72 using ::com::sun::star::accessibility::XAccessibleExtendedComponent; 73 using ::com::sun::star::awt::XFont; 74 /** === end UNO using === **/ 75 76 namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole; 77 namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType; 78 namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; 79 80 //================================================================================================================== 81 //= AccessibleToolPanelDeckTabBarItem_Impl 82 //================================================================================================================== 83 class AccessibleToolPanelDeckTabBarItem_Impl : public ::svt::IToolPanelDeckListener 84 { 85 public: 86 AccessibleToolPanelDeckTabBarItem_Impl( 87 AccessibleToolPanelDeckTabBarItem& i_rAntiImpl, 88 const Reference< XAccessible >& i_rAccessibleParent, 89 ::svt::IToolPanelDeck& i_rPanelDeck, 90 ::svt::PanelTabBar& i_rTabBar, 91 const size_t i_nItemPos 92 ); 93 ~AccessibleToolPanelDeckTabBarItem_Impl(); 94 95 ::svt::PanelTabBar* getTabBar() const { return m_pTabBar; } 96 97 // IToolPanelDeckListener 98 virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ); 99 virtual void PanelRemoved( const size_t i_nPosition ); 100 virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); 101 virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ); 102 virtual void Dying(); 103 104 public: 105 bool isDisposed() const { return m_pPanelDeck == NULL; } 106 void checkDisposed() const; 107 void dispose(); 108 109 const Reference< XAccessible >& 110 getAccessibleParent() const { return m_xAccessibleParent; } 111 size_t getItemPos() const { return m_nItemPos; } 112 113 Reference< XAccessibleComponent > getParentAccessibleComponent() const; 114 ::svt::IToolPanelDeck* getPanelDeck() const { return m_pPanelDeck; } 115 ::rtl::OUString getPanelDisplayName(); 116 117 private: 118 void impl_notifyBoundRectChanges(); 119 void impl_notifyStateChange( const sal_Int16 i_nLostState, const sal_Int16 i_nGainedState ); 120 121 private: 122 AccessibleToolPanelDeckTabBarItem& m_rAntiImpl; 123 Reference< XAccessible > m_xAccessibleParent; 124 ::svt::IToolPanelDeck* m_pPanelDeck; 125 ::svt::PanelTabBar* m_pTabBar; 126 size_t m_nItemPos; 127 }; 128 129 //================================================================================================================== 130 //= AccessibleToolPanelDeckTabBarItem_Impl 131 //================================================================================================================== 132 //------------------------------------------------------------------------------------------------------------------ 133 AccessibleToolPanelDeckTabBarItem_Impl::AccessibleToolPanelDeckTabBarItem_Impl( AccessibleToolPanelDeckTabBarItem& i_rAntiImpl, 134 const Reference< XAccessible >& i_rAccessibleParent, ::svt::IToolPanelDeck& i_rPanelDeck, ::svt::PanelTabBar& i_rTabBar, 135 const size_t i_nItemPos ) 136 :m_rAntiImpl( i_rAntiImpl ) 137 ,m_xAccessibleParent( i_rAccessibleParent ) 138 ,m_pPanelDeck( &i_rPanelDeck ) 139 ,m_pTabBar( &i_rTabBar ) 140 ,m_nItemPos( i_nItemPos ) 141 { 142 m_pPanelDeck->AddListener( *this ); 143 } 144 145 //------------------------------------------------------------------------------------------------------------------ 146 AccessibleToolPanelDeckTabBarItem_Impl::~AccessibleToolPanelDeckTabBarItem_Impl() 147 { 148 } 149 150 //------------------------------------------------------------------------------------------------------------------ 151 void AccessibleToolPanelDeckTabBarItem_Impl::checkDisposed() const 152 { 153 if ( isDisposed() ) 154 throw DisposedException( ::rtl::OUString(), *&m_rAntiImpl ); 155 } 156 157 //------------------------------------------------------------------------------------------------------------------ 158 void AccessibleToolPanelDeckTabBarItem_Impl::dispose() 159 { 160 ENSURE_OR_RETURN_VOID( !isDisposed(), "AccessibleToolPanelDeckTabBarItem_Impl::dispose: disposed twice!" ); 161 162 m_xAccessibleParent.clear(); 163 m_pPanelDeck->RemoveListener( *this ); 164 m_pPanelDeck = NULL; 165 m_pTabBar = NULL; 166 } 167 168 //------------------------------------------------------------------------------------------------------------------ 169 Reference< XAccessibleComponent > AccessibleToolPanelDeckTabBarItem_Impl::getParentAccessibleComponent() const 170 { 171 Reference< XAccessible > xAccessibleParent( m_rAntiImpl.getAccessibleParent(), UNO_QUERY_THROW ); 172 return Reference< XAccessibleComponent >( xAccessibleParent->getAccessibleContext(), UNO_QUERY ); 173 } 174 175 //------------------------------------------------------------------------------------------------------------------ 176 ::rtl::OUString AccessibleToolPanelDeckTabBarItem_Impl::getPanelDisplayName() 177 { 178 const ::svt::PToolPanel pPanel( m_pPanelDeck->GetPanel( getItemPos() ) ); 179 if ( pPanel.get() == NULL ) 180 throw DisposedException(); 181 return pPanel->GetDisplayName(); 182 } 183 184 //------------------------------------------------------------------------------------------------------------------ 185 void AccessibleToolPanelDeckTabBarItem_Impl::impl_notifyBoundRectChanges() 186 { 187 m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any() ); 188 } 189 190 //------------------------------------------------------------------------------------------------------------------ 191 void AccessibleToolPanelDeckTabBarItem_Impl::impl_notifyStateChange( const sal_Int16 i_nLostState, const sal_Int16 i_nGainedState ) 192 { 193 m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, 194 i_nLostState > -1 ? makeAny( i_nLostState ) : Any(), 195 i_nGainedState > -1 ? makeAny( i_nGainedState ) : Any() 196 ); 197 } 198 199 //------------------------------------------------------------------------------------------------------------------ 200 void AccessibleToolPanelDeckTabBarItem_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) 201 { 202 (void)i_pPanel; 203 if ( i_nPosition <= m_nItemPos ) 204 ++m_nItemPos; 205 impl_notifyBoundRectChanges(); 206 } 207 208 //------------------------------------------------------------------------------------------------------------------ 209 void AccessibleToolPanelDeckTabBarItem_Impl::PanelRemoved( const size_t i_nPosition ) 210 { 211 if ( i_nPosition == m_nItemPos ) 212 { 213 m_rAntiImpl.dispose(); 214 } 215 else if ( i_nPosition < m_nItemPos ) 216 { 217 --m_nItemPos; 218 impl_notifyBoundRectChanges(); 219 } 220 } 221 222 //------------------------------------------------------------------------------------------------------------------ 223 void AccessibleToolPanelDeckTabBarItem_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) 224 { 225 if ( m_nItemPos == i_rOldActive ) 226 { 227 impl_notifyStateChange( AccessibleStateType::ACTIVE, -1 ); 228 impl_notifyStateChange( AccessibleStateType::SELECTED, -1 ); 229 } 230 else if ( m_nItemPos == i_rNewActive ) 231 { 232 impl_notifyStateChange( -1, AccessibleStateType::ACTIVE ); 233 impl_notifyStateChange( -1, AccessibleStateType::SELECTED ); 234 } 235 } 236 237 //------------------------------------------------------------------------------------------------------------------ 238 void AccessibleToolPanelDeckTabBarItem_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) 239 { 240 (void)i_rNewLayouter; 241 // if the tool panel deck has a new layouter, then the old layouter, and thus all items it was 242 // responsible for, died. So do we. 243 dispose(); 244 } 245 246 //------------------------------------------------------------------------------------------------------------------ 247 void AccessibleToolPanelDeckTabBarItem_Impl::Dying() 248 { 249 // if the tool panel deck is dying, then its layouter dies, so should we. 250 dispose(); 251 } 252 253 //================================================================================================================== 254 //= ItemMethodGuard 255 //================================================================================================================== 256 class ItemMethodGuard 257 { 258 public: 259 ItemMethodGuard( AccessibleToolPanelDeckTabBarItem_Impl& i_rImpl ) 260 :m_aGuard( Application::GetSolarMutex() ) 261 { 262 i_rImpl.checkDisposed(); 263 } 264 ~ItemMethodGuard() 265 { 266 } 267 268 void clear() 269 { 270 m_aGuard.clear(); 271 } 272 273 private: 274 ::vos::OClearableGuard m_aGuard; 275 }; 276 277 //================================================================================================================== 278 //= AccessibleToolPanelDeckTabBarItem 279 //================================================================================================================== 280 //------------------------------------------------------------------------------------------------------------------ 281 AccessibleToolPanelDeckTabBarItem::AccessibleToolPanelDeckTabBarItem( const Reference< XAccessible >& i_rAccessibleParent, 282 ::svt::IToolPanelDeck& i_rPanelDeck, ::svt::PanelTabBar& i_rTabBar, const size_t i_nItemPos ) 283 :m_pImpl( new AccessibleToolPanelDeckTabBarItem_Impl( *this, i_rAccessibleParent, i_rPanelDeck, i_rTabBar, i_nItemPos ) ) 284 { 285 } 286 287 //------------------------------------------------------------------------------------------------------------------ 288 AccessibleToolPanelDeckTabBarItem::~AccessibleToolPanelDeckTabBarItem() 289 { 290 } 291 292 //-------------------------------------------------------------------- 293 sal_Int32 SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleChildCount( ) throw (RuntimeException) 294 { 295 return 0; 296 } 297 298 //-------------------------------------------------------------------- 299 Reference< XAccessible > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) 300 { 301 (void)i; 302 throw IndexOutOfBoundsException( ::rtl::OUString(), *this ); 303 } 304 305 //-------------------------------------------------------------------- 306 Reference< XAccessible > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleParent( ) throw (RuntimeException) 307 { 308 ItemMethodGuard aGuard( *m_pImpl ); 309 return m_pImpl->getAccessibleParent(); 310 } 311 312 //-------------------------------------------------------------------- 313 sal_Int16 SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleRole( ) throw (RuntimeException) 314 { 315 return AccessibleRole::PAGE_TAB; 316 } 317 318 //-------------------------------------------------------------------- 319 ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleDescription( ) throw (RuntimeException) 320 { 321 ItemMethodGuard aGuard( *m_pImpl ); 322 return m_pImpl->getPanelDisplayName(); 323 } 324 325 //-------------------------------------------------------------------- 326 ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleName( ) throw (RuntimeException) 327 { 328 ItemMethodGuard aGuard( *m_pImpl ); 329 return m_pImpl->getPanelDisplayName(); 330 } 331 332 //-------------------------------------------------------------------- 333 Reference< XAccessibleRelationSet > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleRelationSet( ) throw (RuntimeException) 334 { 335 ItemMethodGuard aGuard( *m_pImpl ); 336 ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper; 337 return pRelationSet; 338 } 339 340 //-------------------------------------------------------------------- 341 Reference< XAccessibleStateSet > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleStateSet( ) throw (RuntimeException) 342 { 343 ItemMethodGuard aGuard( *m_pImpl ); 344 345 ::utl::AccessibleStateSetHelper* pStateSet( new ::utl::AccessibleStateSetHelper ); 346 pStateSet->AddState( AccessibleStateType::FOCUSABLE ); 347 pStateSet->AddState( AccessibleStateType::SELECTABLE ); 348 pStateSet->AddState( AccessibleStateType::ICONIFIED ); 349 350 if ( m_pImpl->getItemPos() == m_pImpl->getPanelDeck()->GetActivePanel() ) 351 { 352 pStateSet->AddState( AccessibleStateType::ACTIVE ); 353 pStateSet->AddState( AccessibleStateType::SELECTED ); 354 } 355 356 if ( m_pImpl->getItemPos() == m_pImpl->getTabBar()->GetFocusedPanelItem() ) 357 pStateSet->AddState( AccessibleStateType::FOCUSED ); 358 359 if ( m_pImpl->getTabBar()->IsEnabled() ) 360 pStateSet->AddState( AccessibleStateType::ENABLED ); 361 362 if ( m_pImpl->getTabBar()->IsVisible() ) 363 { 364 pStateSet->AddState( AccessibleStateType::SHOWING ); 365 pStateSet->AddState( AccessibleStateType::VISIBLE ); 366 } 367 368 return pStateSet; 369 } 370 371 372 //-------------------------------------------------------------------- 373 Reference< XAccessible > SAL_CALL AccessibleToolPanelDeckTabBarItem::getAccessibleAtPoint( const UnoPoint& i_rLocation ) throw (RuntimeException) 374 { 375 ItemMethodGuard aGuard( *m_pImpl ); 376 // we do not have children ... 377 (void)i_rLocation; 378 return NULL; 379 } 380 381 //-------------------------------------------------------------------- 382 void SAL_CALL AccessibleToolPanelDeckTabBarItem::grabFocus( ) throw (RuntimeException) 383 { 384 ItemMethodGuard aGuard( *m_pImpl ); 385 m_pImpl->getTabBar()->FocusPanelItem( m_pImpl->getItemPos() ); 386 } 387 388 //-------------------------------------------------------------------- 389 ::sal_Int32 SAL_CALL AccessibleToolPanelDeckTabBarItem::getForeground( ) throw (RuntimeException) 390 { 391 ItemMethodGuard aGuard( *m_pImpl ); 392 Reference< XAccessibleComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_SET_THROW ); 393 return xParentComponent->getForeground(); 394 } 395 396 //-------------------------------------------------------------------- 397 ::sal_Int32 SAL_CALL AccessibleToolPanelDeckTabBarItem::getBackground( ) throw (RuntimeException) 398 { 399 ItemMethodGuard aGuard( *m_pImpl ); 400 Reference< XAccessibleComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_SET_THROW ); 401 return xParentComponent->getBackground(); 402 } 403 404 //-------------------------------------------------------------------- 405 Reference< XFont > SAL_CALL AccessibleToolPanelDeckTabBarItem::getFont( ) throw (RuntimeException) 406 { 407 ItemMethodGuard aGuard( *m_pImpl ); 408 Reference< XAccessibleExtendedComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_QUERY_THROW ); 409 // TODO: strictly, this is not correct: The TabBar implementation of the TabLayouter might use 410 // a different font ... 411 return xParentComponent->getFont(); 412 } 413 414 //-------------------------------------------------------------------- 415 ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getTitledBorderText( ) throw (RuntimeException) 416 { 417 ItemMethodGuard aGuard( *m_pImpl ); 418 // no support 419 return ::rtl::OUString(); 420 } 421 422 //-------------------------------------------------------------------- 423 ::rtl::OUString SAL_CALL AccessibleToolPanelDeckTabBarItem::getToolTipText( ) throw (RuntimeException) 424 { 425 ItemMethodGuard aGuard( *m_pImpl ); 426 return m_pImpl->getPanelDisplayName(); 427 } 428 429 //-------------------------------------------------------------------- 430 UnoRectangle SAL_CALL AccessibleToolPanelDeckTabBarItem::implGetBounds() throw (RuntimeException) 431 { 432 ItemMethodGuard aGuard( *m_pImpl ); 433 434 const ::Rectangle aItemScreenRect( m_pImpl->getTabBar()->GetItemScreenRect( m_pImpl->getItemPos() ) ); 435 436 Reference< XAccessibleComponent > xParentComponent( m_pImpl->getParentAccessibleComponent(), UNO_SET_THROW ); 437 const UnoPoint aParentLocation( xParentComponent->getLocationOnScreen() ); 438 return UnoRectangle( 439 aItemScreenRect.Left() - aParentLocation.X, 440 aItemScreenRect.Top() - aParentLocation.Y, 441 aItemScreenRect.GetWidth(), 442 aItemScreenRect.GetHeight() 443 ); 444 } 445 446 //-------------------------------------------------------------------- 447 void SAL_CALL AccessibleToolPanelDeckTabBarItem::disposing() 448 { 449 ItemMethodGuard aGuard( *m_pImpl ); 450 m_pImpl->dispose(); 451 } 452 453 //...................................................................................................................... 454 } // namespace accessibility 455 //...................................................................................................................... 456