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 /** Acquire 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 { 294 if ( ( _nIndex < 0 ) || ( _nIndex >= implGetCellCount() ) ) 295 throw IndexOutOfBoundsException(); 296 } 297 implIsRowSelected(sal_Int32 _nRow) const298 sal_Bool AccessibleTabListBoxTable::implIsRowSelected( sal_Int32 _nRow ) const 299 { 300 return m_pTabListBox ? m_pTabListBox->IsSelected( m_pTabListBox->GetEntry( _nRow ) ) : sal_False; 301 } 302 implSelectRow(sal_Int32 _nRow,sal_Bool _bSelect)303 void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow, sal_Bool _bSelect ) 304 { 305 if ( m_pTabListBox ) 306 m_pTabListBox->Select( m_pTabListBox->GetEntry( _nRow ), _bSelect ); 307 } 308 implGetRowCount() const309 sal_Int32 AccessibleTabListBoxTable::implGetRowCount() const 310 { 311 return m_pTabListBox ? m_pTabListBox->GetEntryCount() : 0; 312 } 313 implGetColumnCount() const314 sal_Int32 AccessibleTabListBoxTable::implGetColumnCount() const 315 { 316 return m_pTabListBox ? m_pTabListBox->GetColumnCount() : 0; 317 } 318 implGetSelRowCount() const319 sal_Int32 AccessibleTabListBoxTable::implGetSelRowCount() const 320 { 321 return m_pTabListBox ? m_pTabListBox->GetSelectionCount() : 0; 322 } 323 implGetSelRow(sal_Int32 nSelRow) const324 sal_Int32 AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow ) const 325 { 326 if ( m_pTabListBox ) 327 { 328 sal_Int32 nRow = 0; 329 SvLBoxEntry* pEntry = m_pTabListBox->FirstSelected(); 330 while ( pEntry ) 331 { 332 ++nRow; 333 if ( nRow == nSelRow ) 334 return m_pTabListBox->GetEntryPos( pEntry ); 335 pEntry = m_pTabListBox->NextSelected( pEntry ); 336 } 337 } 338 339 return 0; 340 } 341 // ----------------------------------------------------------------------------- 342 // XInterface & XTypeProvider 343 // ----------------------------------------------------------------------------- IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable,AccessibleBrowseBoxTable,AccessibleTabListBoxTableImplHelper)344 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) 345 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) 346 // ----------------------------------------------------------------------------- 347 // XServiceInfo 348 // ----------------------------------------------------------------------------- 349 ::rtl::OUString AccessibleTabListBoxTable::getImplementationName (void) 350 { 351 return ::rtl::OUString::createFromAscii("com.sun.star.comp.svtools.AccessibleTabListBoxTable"); 352 } 353 // ----------------------------------------------------------------------------- 354 // XAccessibleSelection 355 // ----------------------------------------------------------------------------- selectAccessibleChild(sal_Int32 nChildIndex)356 void SAL_CALL AccessibleTabListBoxTable::selectAccessibleChild( sal_Int32 nChildIndex ) 357 { 358 TLBSolarGuard aSolarGuard; 359 ::osl::MutexGuard aGuard( getOslMutex() ); 360 361 ensureIsAlive(); 362 ensureValidIndex( nChildIndex ); 363 364 implSelectRow( implGetRow( nChildIndex ), sal_True ); 365 } 366 // ----------------------------------------------------------------------------- isAccessibleChildSelected(sal_Int32 nChildIndex)367 sal_Bool SAL_CALL AccessibleTabListBoxTable::isAccessibleChildSelected( sal_Int32 nChildIndex ) 368 { 369 TLBSolarGuard aSolarGuard; 370 ::osl::MutexGuard aGuard( getOslMutex() ); 371 372 ensureIsAlive(); 373 ensureValidIndex( nChildIndex ); 374 375 return implIsRowSelected( implGetRow( nChildIndex ) ); 376 } 377 // ----------------------------------------------------------------------------- clearAccessibleSelection()378 void SAL_CALL AccessibleTabListBoxTable::clearAccessibleSelection( ) 379 { 380 TLBSolarGuard aSolarGuard; 381 ::osl::MutexGuard aGuard( getOslMutex() ); 382 383 ensureIsAlive(); 384 385 m_pTabListBox->SetNoSelection(); 386 } 387 // ----------------------------------------------------------------------------- selectAllAccessibleChildren()388 void SAL_CALL AccessibleTabListBoxTable::selectAllAccessibleChildren( ) 389 { 390 TLBSolarGuard aSolarGuard; 391 ::osl::MutexGuard aGuard( getOslMutex() ); 392 393 ensureIsAlive(); 394 395 m_pTabListBox->SelectAll(); 396 } 397 // ----------------------------------------------------------------------------- getSelectedAccessibleChildCount()398 sal_Int32 SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChildCount( ) 399 { 400 TLBSolarGuard aSolarGuard; 401 ::osl::MutexGuard aGuard( getOslMutex() ); 402 403 ensureIsAlive(); 404 405 return implGetColumnCount() * implGetSelRowCount(); 406 } 407 // ----------------------------------------------------------------------------- getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)408 Reference< XAccessible > SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 409 { 410 TLBSolarGuard aSolarGuard; 411 ::osl::MutexGuard aGuard( getOslMutex() ); 412 413 ensureIsAlive(); 414 415 sal_Int32 nRows = implGetSelRowCount(); 416 if ( nRows == 0 ) 417 throw IndexOutOfBoundsException(); 418 419 sal_Int32 nRow = implGetSelRow( nSelectedChildIndex % nRows ); 420 sal_Int32 nColumn = nSelectedChildIndex / nRows; 421 return getAccessibleCellAt( nRow, nColumn ); 422 } 423 // ----------------------------------------------------------------------------- deselectAccessibleChild(sal_Int32 nSelectedChildIndex)424 void SAL_CALL AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) 425 { 426 TLBSolarGuard aSolarGuard; 427 ::osl::MutexGuard aGuard( getOslMutex() ); 428 429 ensureIsAlive(); 430 ensureValidIndex( nSelectedChildIndex ); 431 432 implSelectRow( implGetRow( nSelectedChildIndex ), sal_False ); 433 } 434 435 //........................................................................ 436 }// namespace accessibility 437 //........................................................................ 438