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 "AccessibleCellBase.hxx" 33 #include "attrib.hxx" 34 #include "scitems.hxx" 35 #include "miscuno.hxx" 36 #include "document.hxx" 37 #include "docfunc.hxx" 38 #include "cell.hxx" 39 #include "unoguard.hxx" 40 #include "scresid.hxx" 41 #ifndef SC_SC_HRC 42 #include "sc.hrc" 43 #endif 44 #include "unonames.hxx" 45 46 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_ 47 #include <com/sun/star/accessibility/AccessibleRole.hpp> 48 #endif 49 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_ 50 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 51 #endif 52 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 53 #include <com/sun/star/sheet/XSpreadsheet.hpp> 54 #include <tools/debug.hxx> 55 #include <editeng/brshitem.hxx> 56 #include <rtl/uuid.h> 57 #include <comphelper/sequence.hxx> 58 #include <sfx2/objsh.hxx> 59 60 #include <float.h> 61 62 using namespace ::com::sun::star; 63 using namespace ::com::sun::star::accessibility; 64 65 //===== internal ============================================================ 66 67 ScAccessibleCellBase::ScAccessibleCellBase( 68 const uno::Reference<XAccessible>& rxParent, 69 ScDocument* pDoc, 70 const ScAddress& rCellAddress, 71 sal_Int32 nIndex) 72 : 73 ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL), 74 maCellAddress(rCellAddress), 75 mpDoc(pDoc), 76 mnIndex(nIndex) 77 { 78 } 79 80 ScAccessibleCellBase::~ScAccessibleCellBase() 81 { 82 } 83 84 //===== XAccessibleComponent ============================================ 85 86 sal_Bool SAL_CALL ScAccessibleCellBase::isVisible( ) 87 throw (uno::RuntimeException) 88 { 89 ScUnoGuard aGuard; 90 IsObjectValid(); 91 // test whether the cell is hidden (column/row - hidden/filtered) 92 sal_Bool bVisible(sal_True); 93 if (mpDoc) 94 { 95 bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab()); 96 bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab()); 97 bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab()); 98 bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab()); 99 100 if (bColHidden || bColFiltered || bRowHidden || bRowFiltered) 101 bVisible = sal_False; 102 } 103 return bVisible; 104 } 105 106 sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground() 107 throw (uno::RuntimeException) 108 { 109 ScUnoGuard aGuard; 110 IsObjectValid(); 111 sal_Int32 nColor(0); 112 if (mpDoc) 113 { 114 SfxObjectShell* pObjSh = mpDoc->GetDocumentShell(); 115 if ( pObjSh ) 116 { 117 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY ); 118 if ( xSpreadDoc.is() ) 119 { 120 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets(); 121 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); 122 if ( xIndex.is() ) 123 { 124 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab()); 125 uno::Reference<sheet::XSpreadsheet> xTable; 126 if (aTable>>=xTable) 127 { 128 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row()); 129 if (xCell.is()) 130 { 131 uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY); 132 if (xCellProps.is()) 133 { 134 uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CCOLOR))); 135 aAny >>= nColor; 136 } 137 } 138 } 139 } 140 } 141 } 142 } 143 return nColor; 144 } 145 146 sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground() 147 throw (uno::RuntimeException) 148 { 149 ScUnoGuard aGuard; 150 IsObjectValid(); 151 sal_Int32 nColor(0); 152 153 if (mpDoc) 154 { 155 SfxObjectShell* pObjSh = mpDoc->GetDocumentShell(); 156 if ( pObjSh ) 157 { 158 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY ); 159 if ( xSpreadDoc.is() ) 160 { 161 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets(); 162 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); 163 if ( xIndex.is() ) 164 { 165 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab()); 166 uno::Reference<sheet::XSpreadsheet> xTable; 167 if (aTable>>=xTable) 168 { 169 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row()); 170 if (xCell.is()) 171 { 172 uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY); 173 if (xCellProps.is()) 174 { 175 uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLBACK))); 176 aAny >>= nColor; 177 } 178 } 179 } 180 } 181 } 182 } 183 } 184 185 return nColor; 186 } 187 188 //===== XInterface ===================================================== 189 190 uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType ) 191 throw (uno::RuntimeException) 192 { 193 uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType)); 194 return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); 195 } 196 197 void SAL_CALL ScAccessibleCellBase::acquire() 198 throw () 199 { 200 ScAccessibleContextBase::acquire(); 201 } 202 203 void SAL_CALL ScAccessibleCellBase::release() 204 throw () 205 { 206 ScAccessibleContextBase::release(); 207 } 208 209 //===== XAccessibleContext ============================================== 210 211 sal_Int32 212 ScAccessibleCellBase::getAccessibleIndexInParent(void) 213 throw (uno::RuntimeException) 214 { 215 ScUnoGuard aGuard; 216 IsObjectValid(); 217 return mnIndex; 218 } 219 220 ::rtl::OUString SAL_CALL 221 ScAccessibleCellBase::createAccessibleDescription(void) 222 throw (uno::RuntimeException) 223 { 224 rtl::OUString sDescription = String(ScResId(STR_ACC_CELL_DESCR)); 225 226 return sDescription; 227 } 228 229 ::rtl::OUString SAL_CALL 230 ScAccessibleCellBase::createAccessibleName(void) 231 throw (uno::RuntimeException) 232 { 233 String sName( ScResId(STR_ACC_CELL_NAME) ); 234 String sAddress; 235 // Document not needed, because only the cell address, but not the tablename is needed 236 // always us OOO notation 237 maCellAddress.Format( sAddress, SCA_VALID, NULL ); 238 sName.SearchAndReplaceAscii("%1", sAddress); 239 /* #i65103# ZoomText merges cell address and contents, e.g. if value 2 is 240 contained in cell A1, ZT reads "cell A twelve" instead of "cell A1 - 2". 241 Simple solution: Append a space character to the cell address. */ 242 sName.Append( ' ' ); 243 return rtl::OUString(sName); 244 } 245 246 //===== XAccessibleValue ================================================ 247 248 uno::Any SAL_CALL 249 ScAccessibleCellBase::getCurrentValue( ) 250 throw (uno::RuntimeException) 251 { 252 ScUnoGuard aGuard; 253 IsObjectValid(); 254 uno::Any aAny; 255 if (mpDoc) 256 aAny <<= mpDoc->GetValue(maCellAddress); 257 258 return aAny; 259 } 260 261 sal_Bool SAL_CALL 262 ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber ) 263 throw (uno::RuntimeException) 264 { 265 ScUnoGuard aGuard; 266 IsObjectValid(); 267 double fValue = 0; 268 sal_Bool bResult(sal_False); 269 if((aNumber >>= fValue) && mpDoc && mpDoc->GetDocumentShell()) 270 { 271 uno::Reference<XAccessibleStateSet> xParentStates; 272 if (getAccessibleParent().is()) 273 { 274 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 275 xParentStates = xParentContext->getAccessibleStateSet(); 276 } 277 if (IsEditable(xParentStates)) 278 { 279 ScDocShell* pDocShell = (ScDocShell*) mpDoc->GetDocumentShell(); 280 ScDocFunc aFunc(*pDocShell); 281 bResult = aFunc.PutCell( maCellAddress, new ScValueCell(fValue), sal_True ); 282 } 283 } 284 return bResult; 285 } 286 287 uno::Any SAL_CALL 288 ScAccessibleCellBase::getMaximumValue( ) 289 throw (uno::RuntimeException) 290 { 291 uno::Any aAny; 292 aAny <<= DBL_MAX; 293 294 return aAny; 295 } 296 297 uno::Any SAL_CALL 298 ScAccessibleCellBase::getMinimumValue( ) 299 throw (uno::RuntimeException) 300 { 301 uno::Any aAny; 302 aAny <<= -DBL_MAX; 303 304 return aAny; 305 } 306 307 //===== XServiceInfo ==================================================== 308 309 ::rtl::OUString SAL_CALL ScAccessibleCellBase::getImplementationName(void) 310 throw (uno::RuntimeException) 311 { 312 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCellBase")); 313 } 314 315 //===== XTypeProvider =================================================== 316 317 uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes() 318 throw (uno::RuntimeException) 319 { 320 return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes()); 321 } 322 323 uno::Sequence<sal_Int8> SAL_CALL 324 ScAccessibleCellBase::getImplementationId(void) 325 throw (uno::RuntimeException) 326 { 327 ScUnoGuard aGuard; 328 IsObjectValid(); 329 static uno::Sequence<sal_Int8> aId; 330 if (aId.getLength() == 0) 331 { 332 aId.realloc (16); 333 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 334 } 335 return aId; 336 } 337 338 sal_Bool ScAccessibleCellBase::IsEditable( 339 const uno::Reference<XAccessibleStateSet>& rxParentStates) 340 { 341 sal_Bool bEditable(sal_False); 342 if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE)) 343 bEditable = sal_True; 344 return bEditable; 345 } 346