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