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_sc.hxx" 26 27 28 #include "AccessibleTableBase.hxx" 29 #include "miscuno.hxx" 30 #include "document.hxx" 31 #include "unoguard.hxx" 32 #include "scresid.hxx" 33 #ifndef SC_SC_HRC 34 #include "sc.hrc" 35 #endif 36 37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_ 38 #include <com/sun/star/accessibility/AccessibleRole.hpp> 39 #endif 40 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> 41 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 42 #include <rtl/uuid.h> 43 #include <tools/debug.hxx> 44 #include <comphelper/sequence.hxx> 45 46 47 using namespace ::com::sun::star; 48 using namespace ::com::sun::star::accessibility; 49 50 //===== internal ============================================================ 51 52 ScAccessibleTableBase::ScAccessibleTableBase( 53 const uno::Reference<XAccessible>& rxParent, 54 ScDocument* pDoc, 55 const ScRange& rRange) 56 : 57 ScAccessibleContextBase (rxParent, AccessibleRole::TABLE), 58 maRange(rRange), 59 mpDoc(pDoc) 60 { 61 } 62 63 ScAccessibleTableBase::~ScAccessibleTableBase() 64 { 65 } 66 67 void SAL_CALL ScAccessibleTableBase::disposing() 68 { 69 ScUnoGuard aGuard; 70 mpDoc = NULL; 71 72 ScAccessibleContextBase::disposing(); 73 } 74 75 //===== XInterface ===================================================== 76 77 uno::Any SAL_CALL ScAccessibleTableBase::queryInterface( uno::Type const & rType ) 78 throw (uno::RuntimeException) 79 { 80 //uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType)); 81 //return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); 82 uno::Any aRet; 83 if ( rType == ::getCppuType((uno::Reference<XAccessibleTableSelection> *)0) ) 84 { 85 uno::Reference<XAccessibleTableSelection> xThis( this ); 86 aRet <<= xThis; 87 return aRet; 88 } 89 else 90 { 91 uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType)); 92 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); 93 } 94 return aRet; 95 } 96 97 void SAL_CALL ScAccessibleTableBase::acquire() 98 throw () 99 { 100 ScAccessibleContextBase::acquire(); 101 } 102 103 void SAL_CALL ScAccessibleTableBase::release() 104 throw () 105 { 106 ScAccessibleContextBase::release(); 107 } 108 109 //===== XAccessibleTable ================================================ 110 111 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount( ) 112 throw (uno::RuntimeException) 113 { 114 ScUnoGuard aGuard; 115 IsObjectValid(); 116 return maRange.aEnd.Row() - maRange.aStart.Row() + 1; 117 } 118 119 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount( ) 120 throw (uno::RuntimeException) 121 { 122 ScUnoGuard aGuard; 123 IsObjectValid(); 124 return maRange.aEnd.Col() - maRange.aStart.Col() + 1; 125 } 126 127 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow ) 128 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 129 { 130 DBG_ERROR("Here should be a implementation to fill the description"); 131 132 if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) 133 throw lang::IndexOutOfBoundsException(); 134 135 //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description 136 return rtl::OUString(); 137 } 138 139 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn ) 140 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 141 { 142 DBG_ERROR("Here should be a implementation to fill the description"); 143 144 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0)) 145 throw lang::IndexOutOfBoundsException(); 146 147 //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description 148 return rtl::OUString(); 149 } 150 151 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) 152 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 153 { 154 ScUnoGuard aGuard; 155 IsObjectValid(); 156 157 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || 158 (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) 159 throw lang::IndexOutOfBoundsException(); 160 161 sal_Int32 nCount(1); // the same cell 162 nRow += maRange.aStart.Row(); 163 nColumn += maRange.aStart.Col(); 164 165 if (mpDoc) 166 { 167 SCROW nEndRow(0); 168 SCCOL nEndCol(0); 169 mpDoc->GetTableByIndex(maRange.aStart.Tab())->GetColumnByIndex(nColumn)-> 170 ExtendMerge( static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), nRow, nEndCol, nEndRow, sal_False, sal_False ); 171 if (nEndRow > nRow) 172 nCount = nEndRow - nRow + 1; 173 // if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), 174 // nEndCol, nEndRow, maRange.aStart.Tab())) 175 //{ 176 // if (nEndRow > nRow) 177 // nCount = nEndRow - nRow + 1; 178 //} 179 } 180 181 return nCount; 182 } 183 184 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) 185 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 186 { 187 ScUnoGuard aGuard; 188 IsObjectValid(); 189 190 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || 191 (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) 192 throw lang::IndexOutOfBoundsException(); 193 194 sal_Int32 nCount(1); // the same cell 195 nRow += maRange.aStart.Row(); 196 nColumn += maRange.aStart.Col(); 197 198 if (mpDoc) 199 { 200 SCROW nEndRow(0); 201 SCCOL nEndCol(0); 202 mpDoc->GetTableByIndex(maRange.aStart.Tab())->GetColumnByIndex(nColumn)-> 203 ExtendMerge( static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), nRow, nEndCol, nEndRow, sal_False, sal_False ); 204 if (nEndCol > nColumn) 205 nCount = nEndCol - nColumn + 1; 206 // if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), 207 // nEndCol, nEndRow, maRange.aStart.Tab())) 208 //{ 209 // if (nEndCol > nColumn) 210 // nCount = nEndCol - nColumn + 1; 211 //} 212 } 213 214 return nCount; 215 } 216 217 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders( ) 218 throw (uno::RuntimeException) 219 { 220 uno::Reference< XAccessibleTable > xAccessibleTable; 221 DBG_ERROR("Here should be a implementation to fill the row headers"); 222 223 //CommitChange 224 return xAccessibleTable; 225 } 226 227 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders( ) 228 throw (uno::RuntimeException) 229 { 230 uno::Reference< XAccessibleTable > xAccessibleTable; 231 DBG_ERROR("Here should be a implementation to fill the column headers"); 232 233 //CommitChange 234 return xAccessibleTable; 235 } 236 237 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows( ) 238 throw (uno::RuntimeException) 239 { 240 DBG_ERROR("not implemented yet"); 241 uno::Sequence< sal_Int32 > aSequence; 242 return aSequence; 243 } 244 245 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns( ) 246 throw (uno::RuntimeException) 247 { 248 DBG_ERROR("not implemented yet"); 249 uno::Sequence< sal_Int32 > aSequence; 250 return aSequence; 251 } 252 253 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ ) 254 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 255 { 256 DBG_ERROR("not implemented yet"); 257 return sal_False; 258 } 259 260 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ ) 261 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 262 { 263 DBG_ERROR("not implemented yet"); 264 return sal_False; 265 } 266 267 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ ) 268 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 269 { 270 DBG_ERROR("not implemented yet"); 271 uno::Reference< XAccessible > xAccessible; 272 return xAccessible; 273 } 274 275 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption( ) 276 throw (uno::RuntimeException) 277 { 278 DBG_ERROR("not implemented yet"); 279 uno::Reference< XAccessible > xAccessible; 280 return xAccessible; 281 } 282 283 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary( ) 284 throw (uno::RuntimeException) 285 { 286 DBG_ERROR("not implemented yet"); 287 uno::Reference< XAccessible > xAccessible; 288 return xAccessible; 289 } 290 291 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ ) 292 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 293 { 294 DBG_ERROR("not implemented yet"); 295 return sal_False; 296 } 297 298 //===== XAccessibleExtendedTable ======================================== 299 300 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) 301 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 302 { 303 ScUnoGuard aGuard; 304 IsObjectValid(); 305 306 if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) || 307 nRow < 0 || 308 nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) || 309 nColumn < 0) 310 throw lang::IndexOutOfBoundsException(); 311 312 nRow -= maRange.aStart.Row(); 313 nColumn -= maRange.aStart.Col(); 314 return (nRow * (maRange.aEnd.Col() + 1)) + nColumn; 315 } 316 317 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex ) 318 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 319 { 320 ScUnoGuard aGuard; 321 IsObjectValid(); 322 323 if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0) 324 throw lang::IndexOutOfBoundsException(); 325 326 return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1); 327 } 328 329 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex ) 330 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 331 { 332 ScUnoGuard aGuard; 333 IsObjectValid(); 334 335 if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0) 336 throw lang::IndexOutOfBoundsException(); 337 338 return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1); 339 } 340 341 //===== XAccessibleContext ============================================== 342 343 sal_Int32 SAL_CALL 344 ScAccessibleTableBase::getAccessibleChildCount(void) 345 throw (uno::RuntimeException) 346 { 347 ScUnoGuard aGuard; 348 IsObjectValid(); 349 return static_cast<sal_Int32>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) * 350 (maRange.aEnd.Col() - maRange.aStart.Col() + 1); 351 // return 1; 352 } 353 354 uno::Reference< XAccessible > SAL_CALL 355 ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex) 356 throw (uno::RuntimeException, 357 lang::IndexOutOfBoundsException) 358 { 359 ScUnoGuard aGuard; 360 IsObjectValid(); 361 362 if (nIndex >= getAccessibleChildCount() || nIndex < 0) 363 throw lang::IndexOutOfBoundsException(); 364 365 sal_Int32 nRow(0); 366 sal_Int32 nColumn(0); 367 sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1); 368 nRow = nIndex / nTemp; 369 nColumn = nIndex % nTemp; 370 return getAccessibleCellAt(nRow, nColumn); 371 } 372 373 ::rtl::OUString SAL_CALL 374 ScAccessibleTableBase::createAccessibleDescription(void) 375 throw (uno::RuntimeException) 376 { 377 String sDesc(ScResId(STR_ACC_TABLE_DESCR)); 378 /* String sCoreName; 379 if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName )) 380 sDesc.SearchAndReplaceAscii("%1", sCoreName); 381 sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/ 382 return rtl::OUString(sDesc); 383 } 384 385 ::rtl::OUString SAL_CALL 386 ScAccessibleTableBase::createAccessibleName(void) 387 throw (uno::RuntimeException) 388 { 389 String sName(ScResId(STR_ACC_TABLE_NAME)); 390 String sCoreName; 391 if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName )) 392 sName.SearchAndReplaceAscii("%1", sCoreName); 393 return rtl::OUString(sName); 394 } 395 396 uno::Reference<XAccessibleRelationSet> SAL_CALL 397 ScAccessibleTableBase::getAccessibleRelationSet(void) 398 throw (uno::RuntimeException) 399 { 400 DBG_ERROR("should be implemented in the abrevated class"); 401 return uno::Reference<XAccessibleRelationSet>(); 402 } 403 404 uno::Reference<XAccessibleStateSet> SAL_CALL 405 ScAccessibleTableBase::getAccessibleStateSet(void) 406 throw (uno::RuntimeException) 407 { 408 DBG_ERROR("should be implemented in the abrevated class"); 409 uno::Reference< XAccessibleStateSet > xAccessibleStateSet; 410 return xAccessibleStateSet; 411 } 412 413 ///===== XAccessibleSelection =========================================== 414 415 void SAL_CALL 416 ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ ) 417 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 418 { 419 } 420 421 sal_Bool SAL_CALL 422 ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex ) 423 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 424 { 425 // I don't need to guard, because the called funtions have a guard 426 // ScUnoGuard aGuard; 427 if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) 428 throw lang::IndexOutOfBoundsException(); 429 return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex)); 430 } 431 432 void SAL_CALL 433 ScAccessibleTableBase::clearAccessibleSelection( ) 434 throw (uno::RuntimeException) 435 { 436 } 437 438 void SAL_CALL 439 ScAccessibleTableBase::selectAllAccessibleChildren( ) 440 throw (uno::RuntimeException) 441 { 442 } 443 444 sal_Int32 SAL_CALL 445 ScAccessibleTableBase::getSelectedAccessibleChildCount( ) 446 throw (uno::RuntimeException) 447 { 448 sal_Int32 nResult(0); 449 return nResult; 450 } 451 452 uno::Reference<XAccessible > SAL_CALL 453 ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32 /* nSelectedChildIndex */ ) 454 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 455 { 456 uno::Reference < XAccessible > xAccessible; 457 return xAccessible; 458 } 459 460 void SAL_CALL 461 ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ ) 462 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 463 { 464 } 465 466 //===== XServiceInfo ==================================================== 467 468 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getImplementationName(void) 469 throw (uno::RuntimeException) 470 { 471 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleTableBase")); 472 } 473 474 //===== XTypeProvider =================================================== 475 476 uno::Sequence< uno::Type > SAL_CALL ScAccessibleTableBase::getTypes() 477 throw (uno::RuntimeException) 478 { 479 return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes()); 480 } 481 482 uno::Sequence<sal_Int8> SAL_CALL 483 ScAccessibleTableBase::getImplementationId(void) 484 throw (uno::RuntimeException) 485 { 486 ScUnoGuard aGuard; 487 IsObjectValid(); 488 static uno::Sequence<sal_Int8> aId; 489 if (aId.getLength() == 0) 490 { 491 aId.realloc (16); 492 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 493 } 494 return aId; 495 } 496 497 void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId) 498 { 499 AccessibleTableModelChange aModelChange; 500 aModelChange.FirstRow = nStartRow; 501 aModelChange.FirstColumn = nStartCol; 502 aModelChange.LastRow = nEndRow; 503 aModelChange.LastColumn = nEndCol; 504 aModelChange.Type = nId; 505 506 AccessibleEventObject aEvent; 507 aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED; 508 aEvent.Source = uno::Reference< XAccessibleContext >(this); 509 aEvent.NewValue <<= aModelChange; 510 511 CommitChange(aEvent); 512 } 513 sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 ) 514 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 515 { 516 return sal_True; 517 } 518 sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 ) 519 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 520 { 521 return sal_True; 522 } 523 sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 ) 524 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 525 { 526 return sal_True; 527 } 528 sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 ) 529 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 530 { 531 return sal_True; 532 } 533 534 535