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