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 27 #ifndef ACCESSIBILITY_EXT_ACCESSIBLETABLISTBOXTABLE_HXX_ 28 #include "accessibility/extended/accessibletablistboxtable.hxx" 29 #endif 30 #include "accessibility/extended/AccessibleBrowseBoxTableCell.hxx" 31 #include "accessibility/extended/AccessibleBrowseBoxCheckBoxCell.hxx" 32 #include <svtools/svtabbx.hxx> 33 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 34 35 #ifndef _SVTOOLS_ACCESSIBILEBROWSEBOXTABLECELL_HXX 36 #include "accessibility/extended/AccessibleBrowseBoxTableCell.hxx" 37 #endif 38 //........................................................................ 39 namespace accessibility 40 { 41 //........................................................................ 42 43 // class TLBSolarGuard --------------------------------------------------------- 44 45 /** Aquire the solar mutex. */ 46 class TLBSolarGuard : public ::vos::OGuard 47 { 48 public: TLBSolarGuard()49 inline TLBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {} 50 }; 51 52 // class AccessibleTabListBoxTable --------------------------------------------- 53 54 using namespace ::com::sun::star::accessibility; 55 using namespace ::com::sun::star::uno; 56 using namespace ::com::sun::star::lang; 57 using namespace ::com::sun::star; 58 DBG_NAME(AccessibleTabListBoxTable)59 DBG_NAME(AccessibleTabListBoxTable) 60 61 // ----------------------------------------------------------------------------- 62 // Ctor() and Dtor() 63 // ----------------------------------------------------------------------------- 64 AccessibleTabListBoxTable::AccessibleTabListBoxTable( const Reference< XAccessible >& rxParent, SvHeaderTabListBox& rBox ) : 65 66 AccessibleBrowseBoxTable( rxParent, rBox ), 67 68 m_pTabListBox ( &rBox ) 69 70 { 71 DBG_CTOR( AccessibleTabListBoxTable, NULL ); 72 73 m_pTabListBox->AddEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) ); 74 } 75 // ----------------------------------------------------------------------------- ~AccessibleTabListBoxTable()76 AccessibleTabListBoxTable::~AccessibleTabListBoxTable() 77 { 78 DBG_DTOR( AccessibleTabListBoxTable, NULL ); 79 80 if ( isAlive() ) 81 { 82 m_pTabListBox = NULL; 83 84 // increment ref count to prevent double call of Dtor 85 osl_incrementInterlockedCount( &m_refCount ); 86 dispose(); 87 } 88 } 89 // ----------------------------------------------------------------------------- ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)90 void AccessibleTabListBoxTable::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) 91 { 92 if ( isAlive() ) 93 { 94 sal_uLong nEventId = rVclWindowEvent.GetId(); 95 switch ( nEventId ) 96 { 97 case VCLEVENT_OBJECT_DYING : 98 { 99 m_pTabListBox->RemoveEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) ); 100 m_pTabListBox = NULL; 101 break; 102 } 103 104 case VCLEVENT_CONTROL_GETFOCUS : 105 case VCLEVENT_CONTROL_LOSEFOCUS : 106 { 107 uno::Any aOldValue, aNewValue; 108 if ( VCLEVENT_CONTROL_GETFOCUS == nEventId ) 109 aNewValue <<= AccessibleStateType::FOCUSED; 110 else 111 aOldValue <<= AccessibleStateType::FOCUSED; 112 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); 113 break; 114 } 115 116 case VCLEVENT_LISTBOX_SELECT : 117 { 118 // First send an event that tells the listeners of a 119 // modified selection. The active descendant event is 120 // send after that so that the receiving AT has time to 121 // read the text or name of the active child. 122 commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 123 if ( m_pTabListBox && m_pTabListBox->HasFocus() ) 124 { 125 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 126 if ( pEntry ) 127 { 128 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); 129 sal_uInt16 nCol = m_pTabListBox->GetCurrColumn(); 130 Reference< XAccessible > xChild = 131 m_pTabListBox->CreateAccessibleCell( nRow, nCol ); 132 uno::Any aOldValue, aNewValue; 133 134 if ( m_pTabListBox->IsTransientChildrenDisabled() ) 135 { 136 aNewValue <<= AccessibleStateType::FOCUSED; 137 TriState eState = STATE_DONTKNOW; 138 if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) 139 { 140 AccessibleCheckBoxCell* pCell = 141 static_cast< AccessibleCheckBoxCell* >( xChild.get() ); 142 pCell->commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); 143 } 144 else 145 { 146 AccessibleBrowseBoxTableCell* pCell = 147 static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); 148 pCell->commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); 149 } 150 } 151 else 152 { 153 aNewValue <<= xChild; 154 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue, aOldValue ); 155 } 156 } 157 } 158 break; 159 } 160 case VCLEVENT_WINDOW_GETFOCUS : 161 { 162 uno::Any aOldValue, aNewValue; 163 aNewValue <<= AccessibleStateType::FOCUSED; 164 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); 165 break; 166 167 } 168 case VCLEVENT_WINDOW_LOSEFOCUS : 169 { 170 uno::Any aOldValue, aNewValue; 171 aOldValue <<= AccessibleStateType::FOCUSED; 172 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); 173 break; 174 } 175 case VCLEVENT_LISTBOX_TREESELECT: 176 { 177 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 178 if (pEntry) 179 { 180 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); 181 Reference< XAccessible > xChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() ); 182 TriState eState = STATE_DONTKNOW; 183 if ( m_pTabListBox->IsCellCheckBox( nRow, m_pTabListBox->GetCurrColumn(), eState ) ) 184 { 185 AccessibleCheckBoxCell* pCell = static_cast< AccessibleCheckBoxCell* >( xChild.get() ); 186 pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 187 } 188 else 189 { 190 AccessibleBrowseBoxTableCell* pCell = static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); 191 pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 192 } 193 } 194 } 195 break; 196 case VCLEVENT_LISTBOX_TREEFOCUS: 197 { 198 if ( m_pTabListBox && m_pTabListBox->HasFocus() ) 199 { 200 uno::Any aOldValue, aNewValue; 201 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 202 if ( pEntry ) 203 { 204 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); 205 m_xCurChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() ); 206 aNewValue <<= m_xCurChild; 207 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue ,aOldValue); 208 } 209 else 210 { 211 aNewValue <<= AccessibleStateType::FOCUSED; 212 commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue ,aOldValue); 213 } 214 } 215 } 216 break; 217 218 case VCLEVENT_CHECKBOX_TOGGLE : 219 { 220 if ( m_pTabListBox && m_pTabListBox->HasFocus() ) 221 { 222 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 223 if ( pEntry ) 224 { 225 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); 226 sal_uInt16 nCol = m_pTabListBox->GetCurrColumn(); 227 TriState eState = STATE_DONTKNOW; 228 if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) 229 { 230 Reference< XAccessible > xChild = 231 m_pTabListBox->CreateAccessibleCell( nRow, nCol ); 232 AccessibleCheckBoxCell* pCell = 233 static_cast< AccessibleCheckBoxCell* >( xChild.get() ); 234 pCell->SetChecked( m_pTabListBox->IsItemChecked( pEntry, nCol ) ); 235 } 236 } 237 } 238 break; 239 } 240 241 case VCLEVENT_TABLECELL_NAMECHANGED : 242 { 243 if ( m_pTabListBox->IsTransientChildrenDisabled() ) 244 { 245 commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 246 TabListBoxEventData* pData = static_cast< TabListBoxEventData* >( rVclWindowEvent.GetData() ); 247 SvLBoxEntry* pEntry = pData != NULL ? pData->m_pEntry : NULL; 248 if ( pEntry ) 249 { 250 sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); 251 sal_uInt16 nCol = pData->m_nColumn; 252 Reference< XAccessible > xChild = 253 m_pTabListBox->CreateAccessibleCell( nRow, nCol ); 254 uno::Any aOldValue, aNewValue; 255 aOldValue <<= ::rtl::OUString( pData->m_sOldText ); 256 ::rtl::OUString sNewText( m_pTabListBox->GetCellText( nRow, nCol ) ); 257 aNewValue <<= sNewText; 258 TriState eState = STATE_DONTKNOW; 259 260 if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) 261 { 262 AccessibleCheckBoxCell* pCell = 263 static_cast< AccessibleCheckBoxCell* >( xChild.get() ); 264 pCell->commitEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); 265 } 266 else 267 { 268 AccessibleBrowseBoxTableCell* pCell = 269 static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); 270 pCell->nameChanged( sNewText, pData->m_sOldText ); 271 } 272 } 273 } 274 break; 275 } 276 } 277 } 278 } 279 // ----------------------------------------------------------------------------- IMPL_LINK(AccessibleTabListBoxTable,WindowEventListener,VclSimpleEvent *,pEvent)280 IMPL_LINK( AccessibleTabListBoxTable, WindowEventListener, VclSimpleEvent*, pEvent ) 281 { 282 DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); 283 if ( pEvent && pEvent->ISA( VclWindowEvent ) ) 284 { 285 DBG_ASSERT( ( (VclWindowEvent*)pEvent )->GetWindow() && m_pTabListBox, "no event window" ); 286 ProcessWindowEvent( *(VclWindowEvent*)pEvent ); 287 } 288 return 0; 289 } 290 // helpers -------------------------------------------------------------------- 291 ensureValidIndex(sal_Int32 _nIndex) const292 void AccessibleTabListBoxTable::ensureValidIndex( sal_Int32 _nIndex ) const 293 SAL_THROW( ( IndexOutOfBoundsException ) ) 294 { 295 if ( ( _nIndex < 0 ) || ( _nIndex >= implGetCellCount() ) ) 296 throw IndexOutOfBoundsException(); 297 } 298 implIsRowSelected(sal_Int32 _nRow) const299 sal_Bool AccessibleTabListBoxTable::implIsRowSelected( sal_Int32 _nRow ) const 300 { 301 return m_pTabListBox ? m_pTabListBox->IsSelected( m_pTabListBox->GetEntry( _nRow ) ) : sal_False; 302 } 303 implSelectRow(sal_Int32 _nRow,sal_Bool _bSelect)304 void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow, sal_Bool _bSelect ) 305 { 306 if ( m_pTabListBox ) 307 m_pTabListBox->Select( m_pTabListBox->GetEntry( _nRow ), _bSelect ); 308 } 309 implGetRowCount() const310 sal_Int32 AccessibleTabListBoxTable::implGetRowCount() const 311 { 312 return m_pTabListBox ? m_pTabListBox->GetEntryCount() : 0; 313 } 314 implGetColumnCount() const315 sal_Int32 AccessibleTabListBoxTable::implGetColumnCount() const 316 { 317 return m_pTabListBox ? m_pTabListBox->GetColumnCount() : 0; 318 } 319 implGetSelRowCount() const320 sal_Int32 AccessibleTabListBoxTable::implGetSelRowCount() const 321 { 322 return m_pTabListBox ? m_pTabListBox->GetSelectionCount() : 0; 323 } 324 implGetSelRow(sal_Int32 nSelRow) const325 sal_Int32 AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow ) const 326 { 327 if ( m_pTabListBox ) 328 { 329 sal_Int32 nRow = 0; 330 SvLBoxEntry* pEntry = m_pTabListBox->FirstSelected(); 331 while ( pEntry ) 332 { 333 ++nRow; 334 if ( nRow == nSelRow ) 335 return m_pTabListBox->GetEntryPos( pEntry ); 336 pEntry = m_pTabListBox->NextSelected( pEntry ); 337 } 338 } 339 340 return 0; 341 } 342 // ----------------------------------------------------------------------------- 343 // XInterface & XTypeProvider 344 // ----------------------------------------------------------------------------- IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable,AccessibleBrowseBoxTable,AccessibleTabListBoxTableImplHelper)345 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) 346 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) 347 // ----------------------------------------------------------------------------- 348 // XServiceInfo 349 // ----------------------------------------------------------------------------- 350 ::rtl::OUString AccessibleTabListBoxTable::getImplementationName (void) throw (RuntimeException) 351 { 352 return ::rtl::OUString::createFromAscii("com.sun.star.comp.svtools.AccessibleTabListBoxTable"); 353 } 354 // ----------------------------------------------------------------------------- 355 // XAccessibleSelection 356 // ----------------------------------------------------------------------------- selectAccessibleChild(sal_Int32 nChildIndex)357 void SAL_CALL AccessibleTabListBoxTable::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 358 { 359 TLBSolarGuard aSolarGuard; 360 ::osl::MutexGuard aGuard( getOslMutex() ); 361 362 ensureIsAlive(); 363 ensureValidIndex( nChildIndex ); 364 365 implSelectRow( implGetRow( nChildIndex ), sal_True ); 366 } 367 // ----------------------------------------------------------------------------- isAccessibleChildSelected(sal_Int32 nChildIndex)368 sal_Bool SAL_CALL AccessibleTabListBoxTable::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 369 { 370 TLBSolarGuard aSolarGuard; 371 ::osl::MutexGuard aGuard( getOslMutex() ); 372 373 ensureIsAlive(); 374 ensureValidIndex( nChildIndex ); 375 376 return implIsRowSelected( implGetRow( nChildIndex ) ); 377 } 378 // ----------------------------------------------------------------------------- clearAccessibleSelection()379 void SAL_CALL AccessibleTabListBoxTable::clearAccessibleSelection( ) throw (RuntimeException) 380 { 381 TLBSolarGuard aSolarGuard; 382 ::osl::MutexGuard aGuard( getOslMutex() ); 383 384 ensureIsAlive(); 385 386 m_pTabListBox->SetNoSelection(); 387 } 388 // ----------------------------------------------------------------------------- selectAllAccessibleChildren()389 void SAL_CALL AccessibleTabListBoxTable::selectAllAccessibleChildren( ) throw (RuntimeException) 390 { 391 TLBSolarGuard aSolarGuard; 392 ::osl::MutexGuard aGuard( getOslMutex() ); 393 394 ensureIsAlive(); 395 396 m_pTabListBox->SelectAll(); 397 } 398 // ----------------------------------------------------------------------------- getSelectedAccessibleChildCount()399 sal_Int32 SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChildCount( ) throw (RuntimeException) 400 { 401 TLBSolarGuard aSolarGuard; 402 ::osl::MutexGuard aGuard( getOslMutex() ); 403 404 ensureIsAlive(); 405 406 return implGetColumnCount() * implGetSelRowCount(); 407 } 408 // ----------------------------------------------------------------------------- getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)409 Reference< XAccessible > SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 410 { 411 TLBSolarGuard aSolarGuard; 412 ::osl::MutexGuard aGuard( getOslMutex() ); 413 414 ensureIsAlive(); 415 416 sal_Int32 nRows = implGetSelRowCount(); 417 if ( nRows == 0 ) 418 throw IndexOutOfBoundsException(); 419 420 sal_Int32 nRow = implGetSelRow( nSelectedChildIndex % nRows ); 421 sal_Int32 nColumn = nSelectedChildIndex / nRows; 422 return getAccessibleCellAt( nRow, nColumn ); 423 } 424 // ----------------------------------------------------------------------------- deselectAccessibleChild(sal_Int32 nSelectedChildIndex)425 void SAL_CALL AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 426 { 427 TLBSolarGuard aSolarGuard; 428 ::osl::MutexGuard aGuard( getOslMutex() ); 429 430 ensureIsAlive(); 431 ensureValidIndex( nSelectedChildIndex ); 432 433 implSelectRow( implGetRow( nSelectedChildIndex ), sal_False ); 434 } 435 436 //........................................................................ 437 }// namespace accessibility 438 //........................................................................ 439 440