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