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