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