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