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