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/extended/AccessibleBrowseBox.hxx" 27 #include "accessibility/extended/AccessibleBrowseBoxTable.hxx" 28 #include "accessibility/extended/AccessibleBrowseBoxHeaderBar.hxx" 29 #include <svtools/accessibletableprovider.hxx> 30 #include <comphelper/types.hxx> 31 #include <toolkit/helper/vclunohelper.hxx> 32 33 // ============================================================================ 34 35 namespace accessibility 36 { 37 38 // ============================================================================ 39 40 using ::rtl::OUString; 41 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star; 44 using namespace ::com::sun::star::lang; 45 using namespace ::com::sun::star::accessibility; 46 using namespace ::svt; 47 48 // ============================================================================ 49 class AccessibleBrowseBoxImpl 50 { 51 public: 52 /// the XAccessible which created the AccessibleBrowseBox 53 WeakReference< XAccessible > m_aCreator; 54 55 /** The data table child. */ 56 Reference< 57 ::com::sun::star::accessibility::XAccessible > mxTable; 58 AccessibleBrowseBoxTable* m_pTable; 59 60 /** The header bar for rows ("handle column"). */ 61 Reference< 62 ::com::sun::star::accessibility::XAccessible > mxRowHeaderBar; 63 AccessibleBrowseBoxHeaderBar* m_pRowHeaderBar; 64 65 /** The header bar for columns (first row of the table). */ 66 Reference< 67 ::com::sun::star::accessibility::XAccessible > mxColumnHeaderBar; 68 AccessibleBrowseBoxHeaderBar* m_pColumnHeaderBar; 69 }; 70 71 // Ctor/Dtor/disposing -------------------------------------------------------- 72 73 DBG_NAME( AccessibleBrowseBox ) 74 75 AccessibleBrowseBox::AccessibleBrowseBox( 76 const Reference< XAccessible >& _rxParent, const Reference< XAccessible >& _rxCreator, 77 IAccessibleTableProvider& _rBrowseBox ) 78 : AccessibleBrowseBoxBase( _rxParent, _rBrowseBox,NULL, BBTYPE_BROWSEBOX ) 79 { 80 DBG_CTOR( AccessibleBrowseBox, NULL ); 81 m_pImpl.reset( new AccessibleBrowseBoxImpl() ); 82 m_pImpl->m_aCreator = _rxCreator; 83 84 m_xFocusWindow = VCLUnoHelper::GetInterface(mpBrowseBox->GetWindowInstance()); 85 } 86 // ----------------------------------------------------------------------------- 87 void AccessibleBrowseBox::setCreator( const Reference< XAccessible >& _rxCreator ) 88 { 89 #if OSL_DEBUG_LEVEL > 0 90 Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator; 91 DBG_ASSERT( !xCreator.is(), "accessibility/extended/AccessibleBrowseBox::setCreator: creator already set!" ); 92 #endif 93 m_pImpl->m_aCreator = _rxCreator; 94 } 95 96 // ----------------------------------------------------------------------------- 97 AccessibleBrowseBox::~AccessibleBrowseBox() 98 { 99 DBG_DTOR( AccessibleBrowseBox, NULL ); 100 } 101 // ----------------------------------------------------------------------------- 102 103 void SAL_CALL AccessibleBrowseBox::disposing() 104 { 105 ::osl::MutexGuard aGuard( getOslMutex() ); 106 107 m_pImpl->m_pTable = NULL; 108 m_pImpl->m_pColumnHeaderBar = NULL; 109 m_pImpl->m_pRowHeaderBar = NULL; 110 m_pImpl->m_aCreator = Reference< XAccessible >(); 111 112 Reference< XAccessible > xTable = m_pImpl->mxTable; 113 114 Reference< XComponent > xComp( m_pImpl->mxTable, UNO_QUERY ); 115 if ( xComp.is() ) 116 { 117 xComp->dispose(); 118 119 } 120 //! ::comphelper::disposeComponent(m_pImpl->mxTable); 121 ::comphelper::disposeComponent(m_pImpl->mxRowHeaderBar); 122 ::comphelper::disposeComponent(m_pImpl->mxColumnHeaderBar); 123 124 AccessibleBrowseBoxBase::disposing(); 125 } 126 // ----------------------------------------------------------------------------- 127 128 // XAccessibleContext --------------------------------------------------------- 129 130 sal_Int32 SAL_CALL AccessibleBrowseBox::getAccessibleChildCount() 131 { 132 BBSolarGuard aSolarGuard; 133 ::osl::MutexGuard aGuard( getOslMutex() ); 134 ensureIsAlive(); 135 return BBINDEX_FIRSTCONTROL + mpBrowseBox->GetAccessibleControlCount(); 136 } 137 // ----------------------------------------------------------------------------- 138 139 Reference< XAccessible > SAL_CALL 140 AccessibleBrowseBox::getAccessibleChild( sal_Int32 nChildIndex ) 141 { 142 BBSolarGuard aSolarGuard; 143 ::osl::MutexGuard aGuard( getOslMutex() ); 144 ensureIsAlive(); 145 146 Reference< XAccessible > xRet; 147 if( nChildIndex >= 0 ) 148 { 149 if( nChildIndex < BBINDEX_FIRSTCONTROL ) 150 xRet = implGetFixedChild( nChildIndex ); 151 else 152 { 153 // additional controls 154 nChildIndex -= BBINDEX_FIRSTCONTROL; 155 if( nChildIndex < mpBrowseBox->GetAccessibleControlCount() ) 156 xRet = mpBrowseBox->CreateAccessibleControl( nChildIndex ); 157 } 158 } 159 160 if( !xRet.is() ) 161 throw lang::IndexOutOfBoundsException(); 162 return xRet; 163 } 164 // ----------------------------------------------------------------------------- 165 166 //sal_Int16 SAL_CALL AccessibleBrowseBox::getAccessibleRole() 167 // throw ( uno::RuntimeException ) 168 //{ 169 // ensureIsAlive(); 170 // return AccessibleRole::PANEL; 171 //} 172 // ----------------------------------------------------------------------------- 173 174 // XAccessibleComponent ------------------------------------------------------- 175 176 Reference< XAccessible > SAL_CALL 177 AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point& rPoint ) 178 { 179 BBSolarGuard aSolarGuard; 180 ::osl::MutexGuard aGuard( getOslMutex() ); 181 ensureIsAlive(); 182 183 Reference< XAccessible > xChild; 184 sal_Int32 nIndex = 0; 185 if( mpBrowseBox->ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) ) 186 xChild = mpBrowseBox->CreateAccessibleControl( nIndex ); 187 else 188 { 189 // try whether point is in one of the fixed children 190 // (table, header bars, corner control) 191 Point aPoint( VCLPoint( rPoint ) ); 192 for( nIndex = 0; (nIndex < BBINDEX_FIRSTCONTROL) && !xChild.is(); ++nIndex ) 193 { 194 Reference< XAccessible > xCurrChild( implGetFixedChild( nIndex ) ); 195 Reference< XAccessibleComponent > 196 xCurrChildComp( xCurrChild, uno::UNO_QUERY ); 197 198 if( xCurrChildComp.is() && 199 VCLRectangle( xCurrChildComp->getBounds() ).IsInside( aPoint ) ) 200 xChild = xCurrChild; 201 } 202 } 203 return xChild; 204 } 205 // ----------------------------------------------------------------------------- 206 207 void SAL_CALL AccessibleBrowseBox::grabFocus() 208 { 209 BBSolarGuard aSolarGuard; 210 ::osl::MutexGuard aGuard( getOslMutex() ); 211 ensureIsAlive(); 212 mpBrowseBox->GrabFocus(); 213 } 214 // ----------------------------------------------------------------------------- 215 216 Any SAL_CALL AccessibleBrowseBox::getAccessibleKeyBinding() 217 { 218 ensureIsAlive(); 219 return Any(); 220 } 221 // ----------------------------------------------------------------------------- 222 223 // XServiceInfo --------------------------------------------------------------- 224 225 OUString SAL_CALL AccessibleBrowseBox::getImplementationName() 226 { 227 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBox" ) ); 228 } 229 // ----------------------------------------------------------------------------- 230 231 // internal virtual methods --------------------------------------------------- 232 233 Rectangle AccessibleBrowseBox::implGetBoundingBox() 234 { 235 Window* pParent = mpBrowseBox->GetAccessibleParentWindow(); 236 DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" ); 237 return mpBrowseBox->GetWindowExtentsRelative( pParent ); 238 } 239 // ----------------------------------------------------------------------------- 240 241 Rectangle AccessibleBrowseBox::implGetBoundingBoxOnScreen() 242 { 243 return mpBrowseBox->GetWindowExtentsRelative( NULL ); 244 } 245 // ----------------------------------------------------------------------------- 246 247 // internal helper methods ---------------------------------------------------- 248 249 Reference< XAccessible > AccessibleBrowseBox::implGetTable() 250 { 251 if( !m_pImpl->mxTable.is() ) 252 { 253 m_pImpl->m_pTable = createAccessibleTable(); 254 m_pImpl->mxTable = m_pImpl->m_pTable; 255 256 } 257 return m_pImpl->mxTable; 258 } 259 // ----------------------------------------------------------------------------- 260 261 Reference< XAccessible > 262 AccessibleBrowseBox::implGetHeaderBar( AccessibleBrowseBoxObjType eObjType ) 263 { 264 Reference< XAccessible > xRet; 265 Reference< XAccessible >* pxMember = NULL; 266 267 if( eObjType == BBTYPE_ROWHEADERBAR ) 268 pxMember = &m_pImpl->mxRowHeaderBar; 269 else if( eObjType == BBTYPE_COLUMNHEADERBAR ) 270 pxMember = &m_pImpl->mxColumnHeaderBar; 271 272 if( pxMember ) 273 { 274 if( !pxMember->is() ) 275 { 276 AccessibleBrowseBoxHeaderBar* pHeaderBar = new AccessibleBrowseBoxHeaderBar( 277 (Reference< XAccessible >)m_pImpl->m_aCreator, *mpBrowseBox, eObjType ); 278 279 if ( BBTYPE_COLUMNHEADERBAR == eObjType) 280 m_pImpl->m_pColumnHeaderBar = pHeaderBar; 281 else 282 m_pImpl->m_pRowHeaderBar = pHeaderBar; 283 284 *pxMember = pHeaderBar; 285 } 286 xRet = *pxMember; 287 } 288 return xRet; 289 } 290 // ----------------------------------------------------------------------------- 291 292 Reference< XAccessible > 293 AccessibleBrowseBox::implGetFixedChild( sal_Int32 nChildIndex ) 294 { 295 Reference< XAccessible > xRet; 296 switch( nChildIndex ) 297 { 298 case BBINDEX_COLUMNHEADERBAR: 299 xRet = implGetHeaderBar( BBTYPE_COLUMNHEADERBAR ); 300 break; 301 case BBINDEX_ROWHEADERBAR: 302 xRet = implGetHeaderBar( BBTYPE_ROWHEADERBAR ); 303 break; 304 case BBINDEX_TABLE: 305 xRet = implGetTable(); 306 break; 307 } 308 return xRet; 309 } 310 // ----------------------------------------------------------------------------- 311 AccessibleBrowseBoxTable* AccessibleBrowseBox::createAccessibleTable() 312 { 313 Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator; 314 DBG_ASSERT( xCreator.is(), "accessibility/extended/AccessibleBrowseBox::createAccessibleTable: my creator died - how this?" ); 315 return new AccessibleBrowseBoxTable( xCreator, *mpBrowseBox ); 316 } 317 // ----------------------------------------------------------------------------- 318 void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue) 319 { 320 if ( m_pImpl->mxTable.is() ) 321 { 322 m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue); 323 } 324 } 325 // ----------------------------------------------------------------------------- 326 void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId, 327 const Any& _rNewValue, 328 const Any& _rOldValue,sal_Bool _bColumnHeaderBar) 329 { 330 Reference< XAccessible > xHeaderBar = _bColumnHeaderBar ? m_pImpl->mxColumnHeaderBar : m_pImpl->mxRowHeaderBar; 331 AccessibleBrowseBoxHeaderBar* pHeaderBar = _bColumnHeaderBar ? m_pImpl->m_pColumnHeaderBar : m_pImpl->m_pRowHeaderBar; 332 if ( xHeaderBar.is() ) 333 pHeaderBar->commitEvent(_nEventId,_rNewValue,_rOldValue); 334 } 335 336 // ============================================================================ 337 // = AccessibleBrowseBoxAccess 338 // ============================================================================ 339 DBG_NAME( AccessibleBrowseBoxAccess ) 340 // ----------------------------------------------------------------------------- 341 AccessibleBrowseBoxAccess::AccessibleBrowseBoxAccess( const Reference< XAccessible >& _rxParent, IAccessibleTableProvider& _rBrowseBox ) 342 :m_xParent( _rxParent ) 343 ,m_rBrowseBox( _rBrowseBox ) 344 ,m_pContext( NULL ) 345 { 346 DBG_CTOR( AccessibleBrowseBoxAccess, NULL ); 347 } 348 349 // ----------------------------------------------------------------------------- 350 AccessibleBrowseBoxAccess::~AccessibleBrowseBoxAccess() 351 { 352 DBG_DTOR( AccessibleBrowseBoxAccess, NULL ); 353 } 354 355 // ----------------------------------------------------------------------------- 356 void AccessibleBrowseBoxAccess::dispose() 357 { 358 ::osl::MutexGuard aGuard( m_aMutex ); 359 360 m_pContext = NULL; 361 ::comphelper::disposeComponent( m_xContext ); 362 } 363 364 // ----------------------------------------------------------------------------- 365 Reference< XAccessibleContext > SAL_CALL AccessibleBrowseBoxAccess::getAccessibleContext() 366 { 367 ::osl::MutexGuard aGuard( m_aMutex ); 368 369 DBG_ASSERT( ( m_pContext && m_xContext.is() ) || ( !m_pContext && !m_xContext.is() ), 370 "accessibility/extended/AccessibleBrowseBoxAccess::getAccessibleContext: inconsistency!" ); 371 372 // if the context died meanwhile (we're no listener, so it won't tell us explicitly when this happens), 373 // then reset an re-create. 374 if ( m_pContext && !m_pContext->isAlive() ) 375 m_xContext = m_pContext = NULL; 376 377 if ( !m_xContext.is() ) 378 m_xContext = m_pContext = new AccessibleBrowseBox( m_xParent, this, m_rBrowseBox ); 379 380 return m_xContext; 381 } 382 383 // ----------------------------------------------------------------------------- 384 bool AccessibleBrowseBoxAccess::isContextAlive() const 385 { 386 return ( NULL != m_pContext ) && m_pContext->isAlive(); 387 } 388 389 // ============================================================================ 390 391 } // namespace accessibility 392