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