/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */#include <svxrectctaccessiblecontext.hxx>#include <com/sun/star/accessibility/AccessibleRole.hpp>#include <com/sun/star/accessibility/AccessibleEventId.hpp>#include <unotools/accessiblestatesethelper.hxx>#include <com/sun/star/accessibility/AccessibleStateType.hpp>#include <com/sun/star/beans/PropertyChangeEvent.hpp>#include <com/sun/star/awt/XWindow.hpp>#include <cppuhelper/typeprovider.hxx>#include <cppuhelper/supportsservice.hxx>#include <toolkit/helper/convert.hxx>#include <vcl/svapp.hxx>#include <osl/mutex.hxx>#include <tools/debug.hxx>#include <tools/gen.hxx>#include <sal/log.hxx>#include <svx/strings.hrc>#include <svx/dlgctrl.hxx>#include <svx/dialmgr.hxx>#include <comphelper/accessibleeventnotifier.hxx>#include <com/sun/star/accessibility/AccessibleRelationType.hpp>#include <unotools/accessiblerelationsethelper.hxx>usingnamespace::cppu;usingnamespace::osl;usingnamespace::com::sun::star;usingnamespace::com::sun::star::uno;usingnamespace::com::sun::star::accessibility;usingnamespace::com::sun::star::lang;#define MAX_NUM_OF_CHILDREN 9#define NOCHILDSELECTED -1// internalnamespace{structChildIndexToPointData{constchar*pResIdName;constchar*pResIdDescr;RectPointconstePoint;};}staticconstChildIndexToPointData*IndexToPoint(longnIndex){DBG_ASSERT(nIndex<9&&nIndex>=0,"-IndexToPoint(): invalid child index! You have been warned...");// corners are counted from left to right and top to bottomstaticconstChildIndexToPointDatapCornerData[]={// index{RID_SVXSTR_RECTCTL_ACC_CHLD_LT,RID_SVXSTR_RECTCTL_ACC_CHLD_LT,RectPoint::LT},// 0{RID_SVXSTR_RECTCTL_ACC_CHLD_MT,RID_SVXSTR_RECTCTL_ACC_CHLD_MT,RectPoint::MT},// 1{RID_SVXSTR_RECTCTL_ACC_CHLD_RT,RID_SVXSTR_RECTCTL_ACC_CHLD_RT,RectPoint::RT},// 2{RID_SVXSTR_RECTCTL_ACC_CHLD_LM,RID_SVXSTR_RECTCTL_ACC_CHLD_LM,RectPoint::LM},// 3{RID_SVXSTR_RECTCTL_ACC_CHLD_MM,RID_SVXSTR_RECTCTL_ACC_CHLD_MM,RectPoint::MM},// 4{RID_SVXSTR_RECTCTL_ACC_CHLD_RM,RID_SVXSTR_RECTCTL_ACC_CHLD_RM,RectPoint::RM},// 5{RID_SVXSTR_RECTCTL_ACC_CHLD_LB,RID_SVXSTR_RECTCTL_ACC_CHLD_LB,RectPoint::LB},// 6{RID_SVXSTR_RECTCTL_ACC_CHLD_MB,RID_SVXSTR_RECTCTL_ACC_CHLD_MB,RectPoint::MB},// 7{RID_SVXSTR_RECTCTL_ACC_CHLD_RB,RID_SVXSTR_RECTCTL_ACC_CHLD_RB,RectPoint::RB}// 8};returnpCornerData+nIndex;}staticlongPointToIndex(RectPointePoint){longnRet(static_cast<long>(ePoint));// corner control// corners are counted from left to right and top to bottomDBG_ASSERT(int(RectPoint::LT)==0&&int(RectPoint::MT)==1&&int(RectPoint::RT)==2&&int(RectPoint::LM)==3&&int(RectPoint::MM)==4&&int(RectPoint::RM)==5&&int(RectPoint::LB)==6&&int(RectPoint::MB)==7&&int(RectPoint::RB)==8,"*PointToIndex(): unexpected enum value!");nRet=static_cast<long>(ePoint);returnnRet;}SvxRectCtlAccessibleContext::SvxRectCtlAccessibleContext(SvxRectCtl*pRepr):mpRepr(pRepr),mnSelectedChild(NOCHILDSELECTED){{::SolarMutexGuardaSolarGuard;msName=SvxResId(RID_SVXSTR_RECTCTL_ACC_CORN_NAME);msDescription=SvxResId(RID_SVXSTR_RECTCTL_ACC_CORN_DESCR);}mvChildren.resize(MAX_NUM_OF_CHILDREN);}SvxRectCtlAccessibleContext::~SvxRectCtlAccessibleContext(){ensureDisposed();}IMPLEMENT_FORWARD_XINTERFACE2(SvxRectCtlAccessibleContext,OAccessibleSelectionHelper,OAccessibleHelper_Base)IMPLEMENT_FORWARD_XTYPEPROVIDER2(SvxRectCtlAccessibleContext,OAccessibleSelectionHelper,OAccessibleHelper_Base)Reference<XAccessible>SAL_CALLSvxRectCtlAccessibleContext::getAccessibleAtPoint(constawt::Point&rPoint){::osl::MutexGuardaGuard(m_aMutex);Reference<XAccessible>xRet;longnChild=mpRepr?PointToIndex(mpRepr->GetApproxRPFromPixPt(rPoint)):NOCHILDSELECTED;if(nChild!=NOCHILDSELECTED)xRet=getAccessibleChild(nChild);returnxRet;}// XAccessibleContextsal_Int32SAL_CALLSvxRectCtlAccessibleContext::getAccessibleChildCount(){::osl::MutexGuardaGuard(m_aMutex);returnSvxRectCtl::NO_CHILDREN;}Reference<XAccessible>SAL_CALLSvxRectCtlAccessibleContext::getAccessibleChild(sal_Int32nIndex){checkChildIndex(nIndex);Reference<XAccessible>xChild(mvChildren[nIndex].get());if(!xChild.is()){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);xChild=mvChildren[nIndex].get();if(!xChild.is()&&mpRepr){constChildIndexToPointData*p=IndexToPoint(nIndex);OUStringaName(SvxResId(p->pResIdName));OUStringaDescr(SvxResId(p->pResIdDescr));tools::RectangleaFocusRect(mpRepr->CalculateFocusRectangle(p->ePoint));SvxRectCtlChildAccessibleContext*pChild=newSvxRectCtlChildAccessibleContext(this,aName,aDescr,aFocusRect,nIndex);mvChildren[nIndex]=pChild;xChild=pChild;// set actual stateif(mnSelectedChild==nIndex)pChild->setStateChecked(true);}}returnxChild;}Reference<XAccessible>SAL_CALLSvxRectCtlAccessibleContext::getAccessibleParent(){::osl::MutexGuardaGuard(m_aMutex);if(mpRepr)returnmpRepr->getAccessibleParent();returnuno::Reference<css::accessibility::XAccessible>();}sal_Int16SAL_CALLSvxRectCtlAccessibleContext::getAccessibleRole(){returnAccessibleRole::PANEL;}OUStringSAL_CALLSvxRectCtlAccessibleContext::getAccessibleDescription(){::osl::MutexGuardaGuard(m_aMutex);returnmsDescription+" Please use arrow key to selection.";}OUStringSAL_CALLSvxRectCtlAccessibleContext::getAccessibleName(){::osl::MutexGuardaGuard(m_aMutex);returnmsName;}/** Return empty reference to indicate that the relation set is not supported.*/Reference<XAccessibleRelationSet>SAL_CALLSvxRectCtlAccessibleContext::getAccessibleRelationSet(){::osl::MutexGuardaGuard(m_aMutex);if(mpRepr)returnmpRepr->get_accessible_relation_set();returnuno::Reference<css::accessibility::XAccessibleRelationSet>();}Reference<XAccessibleStateSet>SAL_CALLSvxRectCtlAccessibleContext::getAccessibleStateSet(){::osl::MutexGuardaGuard(m_aMutex);utl::AccessibleStateSetHelper*pStateSetHelper=newutl::AccessibleStateSetHelper;if(mpRepr){pStateSetHelper->AddState(AccessibleStateType::ENABLED);pStateSetHelper->AddState(AccessibleStateType::FOCUSABLE);if(mpRepr->HasFocus())pStateSetHelper->AddState(AccessibleStateType::FOCUSED);pStateSetHelper->AddState(AccessibleStateType::OPAQUE);pStateSetHelper->AddState(AccessibleStateType::SHOWING);if(mpRepr->IsVisible())pStateSetHelper->AddState(AccessibleStateType::VISIBLE);}elsepStateSetHelper->AddState(AccessibleStateType::DEFUNC);returnpStateSetHelper;}voidSAL_CALLSvxRectCtlAccessibleContext::grabFocus(){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);if(mpRepr)mpRepr->GrabFocus();}sal_Int32SvxRectCtlAccessibleContext::getForeground(){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);//see SvxRectCtl::PaintconstStyleSettings&rStyles=Application::GetSettings().GetStyleSettings();returnsal_Int32(rStyles.GetLabelTextColor());}sal_Int32SvxRectCtlAccessibleContext::getBackground(){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);//see SvxRectCtl::PaintconstStyleSettings&rStyles=Application::GetSettings().GetStyleSettings();returnsal_Int32(rStyles.GetDialogColor());}// XAccessibleSelectionvoidSvxRectCtlAccessibleContext::implSelect(sal_Int32nIndex,boolbSelect){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);checkChildIndex(nIndex);constChildIndexToPointData*pData=IndexToPoint(nIndex);DBG_ASSERT(pData,"SvxRectCtlAccessibleContext::selectAccessibleChild(): this is an impossible state! Or at least should be...");if(mpRepr){if(bSelect){// this does all what is needed, including the change of the child's state!mpRepr->SetActualRP(pData->ePoint);}else{SAL_WARN("svx","SvxRectCtlAccessibleContext::clearAccessibleSelection() is not possible!");}}}boolSvxRectCtlAccessibleContext::implIsSelected(sal_Int32nIndex){::osl::MutexGuardaGuard(m_aMutex);checkChildIndex(nIndex);returnnIndex==mnSelectedChild;}// internalsvoidSvxRectCtlAccessibleContext::checkChildIndex(longnIndex){if(nIndex<0||nIndex>=getAccessibleChildCount())throwlang::IndexOutOfBoundsException();}voidSvxRectCtlAccessibleContext::FireChildFocus(RectPointeButton){::osl::MutexGuardaGuard(m_aMutex);longnNew=PointToIndex(eButton);longnNumOfChildren=getAccessibleChildCount();if(nNew<nNumOfChildren){// select new childmnSelectedChild=nNew;if(nNew!=NOCHILDSELECTED){if(mvChildren[nNew].is())mvChildren[nNew]->FireFocusEvent();}else{AnyaOld;AnyaNew;aNew<<=AccessibleStateType::FOCUSED;NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED,aOld,aNew);}}elsemnSelectedChild=NOCHILDSELECTED;}voidSvxRectCtlAccessibleContext::selectChild(longnNew){::osl::MutexGuardaGuard(m_aMutex);if(nNew!=mnSelectedChild){longnNumOfChildren=getAccessibleChildCount();if(nNew<nNumOfChildren){// valid indexSvxRectCtlChildAccessibleContext*pChild;

<--- The scope of the variable 'pChild' can be reduced. [+]

The scope of the variable 'pChild' can be reduced. Warning: Be careful when fixing this message, especially when there are inner loops. Here is an example where cppcheck will write that the scope for 'i' can be reduced:
void f(int x)
{
int i = 0;
if (x) {
// it's safe to move 'int i = 0;' here
for (int n = 0; n < 10; ++n) {
// it is possible but not safe to move 'int i = 0;' here
do_something(&i);
}
}
}
When you see this message it is always safe to reduce the variable scope 1 level.

if(mnSelectedChild!=NOCHILDSELECTED){// deselect old selected child if one is selectedpChild=mvChildren[mnSelectedChild].get();if(pChild)pChild->setStateChecked(false);}// select new childmnSelectedChild=nNew;if(nNew!=NOCHILDSELECTED){if(mvChildren[nNew].is())mvChildren[nNew]->setStateChecked(true);}}elsemnSelectedChild=NOCHILDSELECTED;}}voidSvxRectCtlAccessibleContext::selectChild(RectPointeButton){// no guard -> is done in next selectChildselectChild(PointToIndex(eButton));}voidSAL_CALLSvxRectCtlAccessibleContext::disposing(){::osl::MutexGuardaGuard(m_aMutex);OAccessibleSelectionHelper::disposing();for(auto&rxChild:mvChildren){if(rxChild.is())rxChild->dispose();}mvChildren.clear();mpRepr=nullptr;}awt::RectangleSvxRectCtlAccessibleContext::implGetBounds(){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);awt::RectangleaRet;if(mpRepr){constPointaOutPos;SizeaOutSize(mpRepr->GetOutputSizePixel());aRet.X=aOutPos.X();aRet.Y=aOutPos.Y();aRet.Width=aOutSize.Width();aRet.Height=aOutSize.Height();}returnaRet;}SvxRectCtlChildAccessibleContext::SvxRectCtlChildAccessibleContext(constReference<XAccessible>&rxParent,constOUString&rName,constOUString&rDescription,consttools::Rectangle&rBoundingBox,longnIndexInParent):msDescription(rDescription),msName(rName),mxParent(rxParent),maBoundingBox(rBoundingBox),mnIndexInParent(nIndexInParent),mbIsChecked(false){}SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext(){ensureDisposed();}Reference<XAccessible>SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleAtPoint(constawt::Point&/*rPoint*/){returnReference<XAccessible>();}voidSAL_CALLSvxRectCtlChildAccessibleContext::grabFocus(){}sal_Int32SvxRectCtlChildAccessibleContext::getForeground(){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);//see SvxRectCtl::PaintconstStyleSettings&rStyles=Application::GetSettings().GetStyleSettings();returnsal_Int32(rStyles.GetLabelTextColor());}sal_Int32SvxRectCtlChildAccessibleContext::getBackground(){::SolarMutexGuardaSolarGuard;::osl::MutexGuardaGuard(m_aMutex);//see SvxRectCtl::PaintconstStyleSettings&rStyles=Application::GetSettings().GetStyleSettings();returnsal_Int32(rStyles.GetDialogColor());}// XAccessibleContextsal_Int32SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleChildCount(){return0;}Reference<XAccessible>SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleChild(sal_Int32/*nIndex*/){throwlang::IndexOutOfBoundsException();}Reference<XAccessible>SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleParent(){returnmxParent;}sal_Int16SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleRole(){returnAccessibleRole::RADIO_BUTTON;}OUStringSAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleDescription(){::osl::MutexGuardaGuard(m_aMutex);returnmsDescription;}OUStringSAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleName(){::osl::MutexGuardaGuard(m_aMutex);returnmsName;}/** Return empty reference to indicate that the relation set is not supported.*/Reference<XAccessibleRelationSet>SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleRelationSet(){utl::AccessibleRelationSetHelper*pRelationSetHelper=newutl::AccessibleRelationSetHelper;uno::Reference<css::accessibility::XAccessibleRelationSet>xSet=pRelationSetHelper;if(mxParent.is()){uno::Sequence<uno::Reference<uno::XInterface>>aSequence{mxParent};pRelationSetHelper->AddRelation(css::accessibility::AccessibleRelation(css::accessibility::AccessibleRelationType::MEMBER_OF,aSequence));}returnxSet;}Reference<XAccessibleStateSet>SAL_CALLSvxRectCtlChildAccessibleContext::getAccessibleStateSet(){::osl::MutexGuardaGuard(m_aMutex);utl::AccessibleStateSetHelper*pStateSetHelper=newutl::AccessibleStateSetHelper;if(!rBHelper.bDisposed){if(mbIsChecked){pStateSetHelper->AddState(AccessibleStateType::CHECKED);}pStateSetHelper->AddState(AccessibleStateType::ENABLED);pStateSetHelper->AddState(AccessibleStateType::SENSITIVE);pStateSetHelper->AddState(AccessibleStateType::OPAQUE);pStateSetHelper->AddState(AccessibleStateType::SELECTABLE);pStateSetHelper->AddState(AccessibleStateType::SHOWING);pStateSetHelper->AddState(AccessibleStateType::VISIBLE);}elsepStateSetHelper->AddState(AccessibleStateType::DEFUNC);returnpStateSetHelper;}// XAccessibleValueAnySAL_CALLSvxRectCtlChildAccessibleContext::getCurrentValue(){AnyaRet;aRet<<=(mbIsChecked?1.0:0.0);returnaRet;}sal_BoolSAL_CALLSvxRectCtlChildAccessibleContext::setCurrentValue(constAny&/*aNumber*/){returnfalse;}AnySAL_CALLSvxRectCtlChildAccessibleContext::getMaximumValue(){AnyaRet;aRet<<=1.0;returnaRet;}AnySAL_CALLSvxRectCtlChildAccessibleContext::getMinimumValue(){AnyaRet;aRet<<=0.0;returnaRet;}// XAccessibleActionsal_Int32SvxRectCtlChildAccessibleContext::getAccessibleActionCount(){return1;}sal_BoolSvxRectCtlChildAccessibleContext::doAccessibleAction(sal_Int32nIndex){::osl::MutexGuardaGuard(m_aMutex);if(nIndex<0||nIndex>=getAccessibleActionCount())throwIndexOutOfBoundsException();Reference<XAccessibleSelection>xSelection(mxParent,UNO_QUERY);xSelection->selectAccessibleChild(mnIndexInParent);returntrue;}OUStringSvxRectCtlChildAccessibleContext::getAccessibleActionDescription(sal_Int32nIndex){::osl::MutexGuardaGuard(m_aMutex);if(nIndex<0||nIndex>=getAccessibleActionCount())throwIndexOutOfBoundsException();returnOUString("select");}Reference<XAccessibleKeyBinding>SvxRectCtlChildAccessibleContext::getAccessibleActionKeyBinding(sal_Int32nIndex){::osl::MutexGuardaGuard(m_aMutex);if(nIndex<0||nIndex>=getAccessibleActionCount())throwIndexOutOfBoundsException();returnReference<XAccessibleKeyBinding>();}voidSAL_CALLSvxRectCtlChildAccessibleContext::disposing(){OAccessibleComponentHelper::disposing();mxParent.clear();}awt::RectangleSvxRectCtlChildAccessibleContext::implGetBounds(){// no guard necessary, because no one changes maBoundingBox after creating itreturnAWTRectangle(maBoundingBox);}voidSvxRectCtlChildAccessibleContext::setStateChecked(boolbChecked){if(mbIsChecked!=bChecked){mbIsChecked=bChecked;AnyaOld;AnyaNew;Any&rMod=bChecked?aNew:aOld;//Send the STATE_CHANGED(Focused) event to accessiblerMod<<=AccessibleStateType::FOCUSED;NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED,aOld,aNew);rMod<<=AccessibleStateType::CHECKED;NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED,aOld,aNew);}}voidSvxRectCtlChildAccessibleContext::FireFocusEvent(){AnyaOld;AnyaNew;aNew<<=AccessibleStateType::FOCUSED;NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED,aOld,aNew);}IMPLEMENT_FORWARD_XINTERFACE2(SvxRectCtlChildAccessibleContext,OAccessibleComponentHelper,OAccessibleHelper_Base_3)IMPLEMENT_FORWARD_XTYPEPROVIDER2(SvxRectCtlChildAccessibleContext,OAccessibleComponentHelper,OAccessibleHelper_Base_3)/* vim:set shiftwidth=4 softtabstop=4 expandtab: */