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 #include "scitems.hxx" 27 #include <editeng/eeitem.hxx> 28 #include <tools/gen.hxx> 29 #include "AccessibleText.hxx" 30 #include "editsrc.hxx" 31 #include "AccessiblePreviewCell.hxx" 32 #include "AccessibilityHints.hxx" 33 #include "prevwsh.hxx" 34 #include "unoguard.hxx" 35 #include "prevloc.hxx" 36 #include "document.hxx" 37 #include <svx/AccessibleTextHelper.hxx> 38 #include <unotools/accessiblestatesethelper.hxx> 39 #include <editeng/brshitem.hxx> 40 #include <vcl/window.hxx> 41 #include <toolkit/helper/convert.hxx> 42 43 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 44 45 using namespace ::com::sun::star; 46 using namespace ::com::sun::star::accessibility; 47 48 //===== internal ============================================================ 49 50 ScAccessiblePreviewCell::ScAccessiblePreviewCell( const ::com::sun::star::uno::Reference< 51 ::com::sun::star::accessibility::XAccessible>& rxParent, 52 ScPreviewShell* pViewShell, /* const */ ScAddress& rCellAddress, 53 sal_Int32 nIndex ) : 54 ScAccessibleCellBase( rxParent, ( pViewShell ? pViewShell->GetDocument() : NULL ), rCellAddress, nIndex ), 55 mpViewShell( pViewShell ), 56 mpTextHelper(NULL) 57 { 58 if (mpViewShell) 59 mpViewShell->AddAccessibilityObject(*this); 60 } 61 62 ScAccessiblePreviewCell::~ScAccessiblePreviewCell() 63 { 64 if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose) 65 { 66 // increment refcount to prevent double call off dtor 67 osl_incrementInterlockedCount( &m_refCount ); 68 // call dispose to inform object wich have a weak reference to this object 69 dispose(); 70 } 71 } 72 73 void SAL_CALL ScAccessiblePreviewCell::disposing() 74 { 75 ScUnoGuard aGuard; 76 if (mpViewShell) 77 { 78 mpViewShell->RemoveAccessibilityObject(*this); 79 mpViewShell = NULL; 80 } 81 82 if (mpTextHelper) 83 DELETEZ(mpTextHelper); 84 85 ScAccessibleCellBase::disposing(); 86 } 87 88 void ScAccessiblePreviewCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 89 { 90 if (rHint.ISA( SfxSimpleHint )) 91 { 92 const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint; 93 if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) 94 { 95 if (mpTextHelper) 96 mpTextHelper->UpdateChildren(); 97 } 98 } 99 100 ScAccessibleContextBase::Notify(rBC, rHint); 101 } 102 103 //===== XAccessibleComponent ============================================ 104 105 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewCell::getAccessibleAtPoint( const awt::Point& rPoint ) 106 throw (uno::RuntimeException) 107 { 108 uno::Reference<XAccessible> xRet; 109 if (containsPoint(rPoint)) 110 { 111 ScUnoGuard aGuard; 112 IsObjectValid(); 113 114 if(!mpTextHelper) 115 CreateTextHelper(); 116 117 xRet = mpTextHelper->GetAt(rPoint); 118 } 119 120 return xRet; 121 } 122 123 void SAL_CALL ScAccessiblePreviewCell::grabFocus() throw (uno::RuntimeException) 124 { 125 ScUnoGuard aGuard; 126 IsObjectValid(); 127 if (getAccessibleParent().is()) 128 { 129 uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); 130 if (xAccessibleComponent.is()) 131 xAccessibleComponent->grabFocus(); 132 } 133 } 134 135 //===== XAccessibleContext ============================================== 136 137 sal_Int32 SAL_CALL ScAccessiblePreviewCell::getAccessibleChildCount() throw(uno::RuntimeException) 138 { 139 ScUnoGuard aGuard; 140 IsObjectValid(); 141 if (!mpTextHelper) 142 CreateTextHelper(); 143 return mpTextHelper->GetChildCount(); 144 } 145 146 uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewCell::getAccessibleChild(sal_Int32 nIndex) 147 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 148 { 149 ScUnoGuard aGuard; 150 IsObjectValid(); 151 if (!mpTextHelper) 152 CreateTextHelper(); 153 return mpTextHelper->GetChild(nIndex); 154 } 155 156 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewCell::getAccessibleStateSet() 157 throw(uno::RuntimeException) 158 { 159 ScUnoGuard aGuard; 160 161 uno::Reference<XAccessibleStateSet> xParentStates; 162 if (getAccessibleParent().is()) 163 { 164 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 165 xParentStates = xParentContext->getAccessibleStateSet(); 166 } 167 utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 168 if (IsDefunc(xParentStates)) 169 pStateSet->AddState(AccessibleStateType::DEFUNC); 170 else 171 { 172 pStateSet->AddState(AccessibleStateType::ENABLED); 173 pStateSet->AddState(AccessibleStateType::MULTI_LINE); 174 if (IsOpaque(xParentStates)) 175 pStateSet->AddState(AccessibleStateType::OPAQUE); 176 if (isShowing()) 177 pStateSet->AddState(AccessibleStateType::SHOWING); 178 pStateSet->AddState(AccessibleStateType::TRANSIENT); 179 if (isVisible()) 180 pStateSet->AddState(AccessibleStateType::VISIBLE); 181 // #111635# MANAGES_DESCENDANTS (for paragraphs) 182 pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS); 183 } 184 return pStateSet; 185 } 186 187 //===== XServiceInfo ==================================================== 188 189 rtl::OUString SAL_CALL ScAccessiblePreviewCell::getImplementationName() throw(uno::RuntimeException) 190 { 191 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewCell")); 192 } 193 194 uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewCell::getSupportedServiceNames() 195 throw(uno::RuntimeException) 196 { 197 uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames(); 198 sal_Int32 nOldSize(aSequence.getLength()); 199 aSequence.realloc(nOldSize + 1); 200 ::rtl::OUString* pNames = aSequence.getArray(); 201 202 pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView")); 203 204 return aSequence; 205 } 206 207 //===== XTypeProvider ======================================================= 208 209 uno::Sequence<sal_Int8> SAL_CALL 210 ScAccessiblePreviewCell::getImplementationId(void) 211 throw (uno::RuntimeException) 212 { 213 ScUnoGuard aGuard; 214 IsObjectValid(); 215 static uno::Sequence<sal_Int8> aId; 216 if (aId.getLength() == 0) 217 { 218 aId.realloc (16); 219 rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 220 } 221 return aId; 222 } 223 224 //==== internal ========================================================= 225 226 Rectangle ScAccessiblePreviewCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException) 227 { 228 Rectangle aCellRect; 229 if (mpViewShell) 230 { 231 mpViewShell->GetLocationData().GetCellPosition( maCellAddress, aCellRect ); 232 Window* pWindow = mpViewShell->GetWindow(); 233 if (pWindow) 234 { 235 Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL); 236 aCellRect.setX(aCellRect.getX() + aRect.getX()); 237 aCellRect.setY(aCellRect.getY() + aRect.getY()); 238 } 239 } 240 return aCellRect; 241 } 242 243 Rectangle ScAccessiblePreviewCell::GetBoundingBox() const throw (uno::RuntimeException) 244 { 245 Rectangle aCellRect; 246 if (mpViewShell) 247 { 248 mpViewShell->GetLocationData().GetCellPosition( maCellAddress, aCellRect ); 249 uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewCell*>(this)->getAccessibleParent(); 250 if (xAccParent.is()) 251 { 252 uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext(); 253 uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY); 254 if (xAccParentComp.is()) 255 { 256 Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds())); 257 aCellRect.setX(aCellRect.getX() - aParentRect.getX()); 258 aCellRect.setY(aCellRect.getY() - aParentRect.getY()); 259 } 260 } 261 } 262 return aCellRect; 263 } 264 265 sal_Bool ScAccessiblePreviewCell::IsDefunc( 266 const uno::Reference<XAccessibleStateSet>& rxParentStates) 267 { 268 return ScAccessibleContextBase::IsDefunc() || (mpDoc == NULL) || (mpViewShell == NULL) || !getAccessibleParent().is() || 269 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 270 } 271 272 sal_Bool ScAccessiblePreviewCell::IsEditable( 273 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) 274 { 275 return sal_False; 276 } 277 278 sal_Bool ScAccessiblePreviewCell::IsOpaque( 279 const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) 280 { 281 // test whether there is a background color 282 //! could be moved to ScAccessibleCellBase 283 284 sal_Bool bOpaque(sal_True); 285 if (mpDoc) 286 { 287 const SvxBrushItem* pItem = (const SvxBrushItem*)mpDoc->GetAttr( 288 maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_BACKGROUND); 289 if (pItem) 290 bOpaque = pItem->GetColor() != COL_TRANSPARENT; 291 } 292 return bOpaque; 293 } 294 295 void ScAccessiblePreviewCell::CreateTextHelper() 296 { 297 if (!mpTextHelper) 298 { 299 ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewCellTextData 300 (new ScAccessiblePreviewCellTextData(mpViewShell, maCellAddress)); 301 ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewCellTextData)); 302 303 mpTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource ); 304 mpTextHelper->SetEventSource( this ); 305 306 // #111635# paragraphs in preview are transient 307 ::accessibility::AccessibleTextHelper::VectorOfStates aChildStates; 308 aChildStates.push_back( AccessibleStateType::TRANSIENT ); 309 mpTextHelper->SetAdditionalChildStates( aChildStates ); 310 } 311 } 312 313