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 "AccessibleEditObject.hxx" 31*cdf0e10cSrcweir #include "scitems.hxx" 32*cdf0e10cSrcweir #include <editeng/eeitem.hxx> 33*cdf0e10cSrcweir #include "unoguard.hxx" 34*cdf0e10cSrcweir #include "AccessibleText.hxx" 35*cdf0e10cSrcweir #include "editsrc.hxx" 36*cdf0e10cSrcweir #include "scmod.hxx" 37*cdf0e10cSrcweir #include "inputhdl.hxx" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX 40*cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx> 41*cdf0e10cSrcweir #endif 42*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_ 43*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp> 44*cdf0e10cSrcweir #endif 45*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_ 46*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp> 47*cdf0e10cSrcweir #endif 48*cdf0e10cSrcweir #include <rtl/uuid.h> 49*cdf0e10cSrcweir #include <tools/debug.hxx> 50*cdf0e10cSrcweir #include <svx/AccessibleTextHelper.hxx> 51*cdf0e10cSrcweir #include <editeng/editview.hxx> 52*cdf0e10cSrcweir #include <editeng/editeng.hxx> 53*cdf0e10cSrcweir #include <svx/svdmodel.hxx> 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir using namespace ::com::sun::star; 56*cdf0e10cSrcweir using namespace ::com::sun::star::accessibility; 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir //===== internal ============================================================ 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir ScAccessibleEditObject::ScAccessibleEditObject( 61*cdf0e10cSrcweir const uno::Reference<XAccessible>& rxParent, 62*cdf0e10cSrcweir EditView* pEditView, Window* pWin, const rtl::OUString& rName, 63*cdf0e10cSrcweir const rtl::OUString& rDescription, EditObjectType eObjectType) 64*cdf0e10cSrcweir : 65*cdf0e10cSrcweir ScAccessibleContextBase(rxParent, AccessibleRole::TEXT_FRAME), 66*cdf0e10cSrcweir mpTextHelper(NULL), 67*cdf0e10cSrcweir mpEditView(pEditView), 68*cdf0e10cSrcweir mpWindow(pWin), 69*cdf0e10cSrcweir meObjectType(eObjectType), 70*cdf0e10cSrcweir mbHasFocus(sal_False) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir CreateTextHelper(); 73*cdf0e10cSrcweir SetName(rName); 74*cdf0e10cSrcweir SetDescription(rDescription); 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir ScAccessibleEditObject::~ScAccessibleEditObject() 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir // increment refcount to prevent double call off dtor 82*cdf0e10cSrcweir osl_incrementInterlockedCount( &m_refCount ); 83*cdf0e10cSrcweir // call dispose to inform object wich have a weak reference to this object 84*cdf0e10cSrcweir dispose(); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir void SAL_CALL ScAccessibleEditObject::disposing() 89*cdf0e10cSrcweir { 90*cdf0e10cSrcweir ScUnoGuard aGuard; 91*cdf0e10cSrcweir if (mpTextHelper) 92*cdf0e10cSrcweir DELETEZ(mpTextHelper); 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir ScAccessibleContextBase::disposing(); 95*cdf0e10cSrcweir } 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir void ScAccessibleEditObject::LostFocus() 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir mbHasFocus = sal_False; 100*cdf0e10cSrcweir if (mpTextHelper) 101*cdf0e10cSrcweir mpTextHelper->SetFocus(sal_False); 102*cdf0e10cSrcweir CommitFocusLost(); 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir void ScAccessibleEditObject::GotFocus() 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir mbHasFocus = sal_True; 108*cdf0e10cSrcweir CommitFocusGained(); 109*cdf0e10cSrcweir if (mpTextHelper) 110*cdf0e10cSrcweir mpTextHelper->SetFocus(sal_True); 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir //===== XAccessibleComponent ============================================ 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAtPoint( 116*cdf0e10cSrcweir const awt::Point& rPoint ) 117*cdf0e10cSrcweir throw (uno::RuntimeException) 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir uno::Reference<XAccessible> xRet; 120*cdf0e10cSrcweir if (containsPoint(rPoint)) 121*cdf0e10cSrcweir { 122*cdf0e10cSrcweir ScUnoGuard aGuard; 123*cdf0e10cSrcweir IsObjectValid(); 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir if(!mpTextHelper) 126*cdf0e10cSrcweir CreateTextHelper(); 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir xRet = mpTextHelper->GetAt(rPoint); 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir return xRet; 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir Rectangle ScAccessibleEditObject::GetBoundingBoxOnScreen(void) const 135*cdf0e10cSrcweir throw (uno::RuntimeException) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir Rectangle aScreenBounds; 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir if ( mpWindow ) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir if ( meObjectType == CellInEditMode ) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir if ( mpEditView && mpEditView->GetEditEngine() ) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir MapMode aMapMode( mpEditView->GetEditEngine()->GetRefMapMode() ); 146*cdf0e10cSrcweir aScreenBounds = mpWindow->LogicToPixel( mpEditView->GetOutputArea(), aMapMode ); 147*cdf0e10cSrcweir Point aCellLoc = aScreenBounds.TopLeft(); 148*cdf0e10cSrcweir Rectangle aWindowRect = mpWindow->GetWindowExtentsRelative( NULL ); 149*cdf0e10cSrcweir Point aWindowLoc = aWindowRect.TopLeft(); 150*cdf0e10cSrcweir Point aPos( aCellLoc.getX() + aWindowLoc.getX(), aCellLoc.getY() + aWindowLoc.getY() ); 151*cdf0e10cSrcweir aScreenBounds.SetPos( aPos ); 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir else 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir aScreenBounds = mpWindow->GetWindowExtentsRelative( NULL ); 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir return aScreenBounds; 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir Rectangle ScAccessibleEditObject::GetBoundingBox(void) const 164*cdf0e10cSrcweir throw (uno::RuntimeException) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir Rectangle aBounds( GetBoundingBoxOnScreen() ); 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir if ( mpWindow ) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir uno::Reference< XAccessible > xThis( mpWindow->GetAccessible() ); 171*cdf0e10cSrcweir if ( xThis.is() ) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir uno::Reference< XAccessibleContext > xContext( xThis->getAccessibleContext() ); 174*cdf0e10cSrcweir if ( xContext.is() ) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir uno::Reference< XAccessible > xParent( xContext->getAccessibleParent() ); 177*cdf0e10cSrcweir if ( xParent.is() ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir uno::Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY ); 180*cdf0e10cSrcweir if ( xParentComponent.is() ) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir Point aScreenLoc = aBounds.TopLeft(); 183*cdf0e10cSrcweir awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen(); 184*cdf0e10cSrcweir Point aPos( aScreenLoc.getX() - aParentScreenLoc.X, aScreenLoc.getY() - aParentScreenLoc.Y ); 185*cdf0e10cSrcweir aBounds.SetPos( aPos ); 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir } 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir return aBounds; 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir //===== XAccessibleContext ============================================== 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir sal_Int32 SAL_CALL 198*cdf0e10cSrcweir ScAccessibleEditObject::getAccessibleChildCount(void) 199*cdf0e10cSrcweir throw (uno::RuntimeException) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir ScUnoGuard aGuard; 202*cdf0e10cSrcweir IsObjectValid(); 203*cdf0e10cSrcweir if (!mpTextHelper) 204*cdf0e10cSrcweir CreateTextHelper(); 205*cdf0e10cSrcweir return mpTextHelper->GetChildCount(); 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir uno::Reference< XAccessible > SAL_CALL 209*cdf0e10cSrcweir ScAccessibleEditObject::getAccessibleChild(sal_Int32 nIndex) 210*cdf0e10cSrcweir throw (uno::RuntimeException, 211*cdf0e10cSrcweir lang::IndexOutOfBoundsException) 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir ScUnoGuard aGuard; 214*cdf0e10cSrcweir IsObjectValid(); 215*cdf0e10cSrcweir if (!mpTextHelper) 216*cdf0e10cSrcweir CreateTextHelper(); 217*cdf0e10cSrcweir return mpTextHelper->GetChild(nIndex); 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir uno::Reference<XAccessibleStateSet> SAL_CALL 221*cdf0e10cSrcweir ScAccessibleEditObject::getAccessibleStateSet(void) 222*cdf0e10cSrcweir throw (uno::RuntimeException) 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir ScUnoGuard aGuard; 225*cdf0e10cSrcweir uno::Reference<XAccessibleStateSet> xParentStates; 226*cdf0e10cSrcweir if (getAccessibleParent().is()) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 229*cdf0e10cSrcweir xParentStates = xParentContext->getAccessibleStateSet(); 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper(); 232*cdf0e10cSrcweir if (IsDefunc(xParentStates)) 233*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::DEFUNC); 234*cdf0e10cSrcweir else 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir // all states are const, because this object exists only in one state 237*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::EDITABLE); 238*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::ENABLED); 239*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::SENSITIVE); 240*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::MULTI_LINE); 241*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE); 242*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::SHOWING); 243*cdf0e10cSrcweir pStateSet->AddState(AccessibleStateType::VISIBLE); 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir return pStateSet; 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 249*cdf0e10cSrcweir ScAccessibleEditObject::createAccessibleDescription(void) 250*cdf0e10cSrcweir throw (uno::RuntimeException) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir // DBG_ERRORFILE("Should never be called, because is set in the constructor.") 253*cdf0e10cSrcweir return rtl::OUString(); 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 257*cdf0e10cSrcweir ScAccessibleEditObject::createAccessibleName(void) 258*cdf0e10cSrcweir throw (uno::RuntimeException) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir DBG_ERRORFILE("Should never be called, because is set in the constructor."); 261*cdf0e10cSrcweir return rtl::OUString(); 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir ///===== XAccessibleEventBroadcaster ===================================== 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir void SAL_CALL 267*cdf0e10cSrcweir ScAccessibleEditObject::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener) 268*cdf0e10cSrcweir throw (uno::RuntimeException) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir if (!mpTextHelper) 271*cdf0e10cSrcweir CreateTextHelper(); 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir mpTextHelper->AddEventListener(xListener); 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir ScAccessibleContextBase::addEventListener(xListener); 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir void SAL_CALL 279*cdf0e10cSrcweir ScAccessibleEditObject::removeEventListener(const uno::Reference<XAccessibleEventListener>& xListener) 280*cdf0e10cSrcweir throw (uno::RuntimeException) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir if (!mpTextHelper) 283*cdf0e10cSrcweir CreateTextHelper(); 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir mpTextHelper->RemoveEventListener(xListener); 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir ScAccessibleContextBase::removeEventListener(xListener); 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir //===== XServiceInfo ==================================================== 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir ::rtl::OUString SAL_CALL ScAccessibleEditObject::getImplementationName(void) 293*cdf0e10cSrcweir throw (uno::RuntimeException) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleEditObject")); 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir //===== XTypeProvider ======================================================= 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir uno::Sequence<sal_Int8> SAL_CALL 301*cdf0e10cSrcweir ScAccessibleEditObject::getImplementationId(void) 302*cdf0e10cSrcweir throw (uno::RuntimeException) 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir ScUnoGuard aGuard; 305*cdf0e10cSrcweir IsObjectValid(); 306*cdf0e10cSrcweir static uno::Sequence<sal_Int8> aId; 307*cdf0e10cSrcweir if (aId.getLength() == 0) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir aId.realloc (16); 310*cdf0e10cSrcweir rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True); 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir return aId; 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir //==== internal ========================================================= 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir sal_Bool ScAccessibleEditObject::IsDefunc( 318*cdf0e10cSrcweir const uno::Reference<XAccessibleStateSet>& rxParentStates) 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() || 321*cdf0e10cSrcweir (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC)); 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir void ScAccessibleEditObject::CreateTextHelper() 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir if (!mpTextHelper) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData; 329*cdf0e10cSrcweir if (meObjectType == CellInEditMode || meObjectType == EditControl) 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir pAccessibleTextData.reset 332*cdf0e10cSrcweir (new ScAccessibleEditObjectTextData(mpEditView, mpWindow)); 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir else 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir pAccessibleTextData.reset 337*cdf0e10cSrcweir (new ScAccessibleEditLineTextData(NULL, mpWindow)); 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData)); 341*cdf0e10cSrcweir mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource ); 342*cdf0e10cSrcweir mpTextHelper->SetEventSource(this); 343*cdf0e10cSrcweir mpTextHelper->SetFocus(mbHasFocus); 344*cdf0e10cSrcweir 345*cdf0e10cSrcweir // #i54814# activate cell in edit mode 346*cdf0e10cSrcweir if( meObjectType == CellInEditMode ) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir // do not activate cell object, if top edit line is active 349*cdf0e10cSrcweir const ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(); 350*cdf0e10cSrcweir if( pInputHdl && !pInputHdl->IsTopMode() ) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir SdrHint aHint( HINT_BEGEDIT ); 353*cdf0e10cSrcweir mpTextHelper->GetEditSource().GetBroadcaster().Broadcast( aHint ); 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir } 358*cdf0e10cSrcweir 359