507 lines
13 KiB
C++
507 lines
13 KiB
C++
/* -*- 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 <accessibledialogcontrolshape.hxx>
|
|
#include <baside3.hxx>
|
|
#include <dlgeddef.hxx>
|
|
#include <dlgedview.hxx>
|
|
#include <dlgedobj.hxx>
|
|
#include <com/sun/star/awt/XVclWindowPeer.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleRole.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
|
|
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
|
|
#include <cppuhelper/supportsservice.hxx>
|
|
#include <unotools/accessiblerelationsethelper.hxx>
|
|
#include <toolkit/awt/vclxfont.hxx>
|
|
#include <toolkit/helper/vclunohelper.hxx>
|
|
#include <comphelper/accessiblecontexthelper.hxx>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <vcl/unohelp.hxx>
|
|
#include <i18nlangtag/languagetag.hxx>
|
|
|
|
namespace basctl
|
|
{
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::lang;
|
|
using namespace ::com::sun::star::beans;
|
|
using namespace ::com::sun::star::accessibility;
|
|
using namespace ::comphelper;
|
|
|
|
|
|
|
|
|
|
AccessibleDialogControlShape::AccessibleDialogControlShape (DialogWindow* pDialogWindow, DlgEdObj* pDlgEdObj)
|
|
:m_pDialogWindow( pDialogWindow )
|
|
,m_pDlgEdObj( pDlgEdObj )
|
|
{
|
|
if ( m_pDlgEdObj )
|
|
m_xControlModel.set( m_pDlgEdObj->GetUnoControlModel(), UNO_QUERY );
|
|
|
|
if ( m_xControlModel.is() )
|
|
m_xControlModel->addPropertyChangeListener( OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
|
|
|
|
m_bFocused = IsFocused();
|
|
m_bSelected = IsSelected();
|
|
m_aBounds = GetBounds();
|
|
}
|
|
|
|
|
|
AccessibleDialogControlShape::~AccessibleDialogControlShape()
|
|
{
|
|
if ( m_xControlModel.is() )
|
|
m_xControlModel->removePropertyChangeListener( OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
|
|
}
|
|
|
|
|
|
bool AccessibleDialogControlShape::IsFocused() const
|
|
{
|
|
bool bFocused = false;
|
|
if ( m_pDialogWindow )
|
|
{
|
|
SdrView& rView = m_pDialogWindow->GetView();
|
|
if (rView.IsObjMarked(m_pDlgEdObj) && rView.GetMarkedObjectList().GetMarkCount() == 1)
|
|
bFocused = true;
|
|
}
|
|
|
|
return bFocused;
|
|
}
|
|
|
|
|
|
bool AccessibleDialogControlShape::IsSelected() const
|
|
{
|
|
if ( m_pDialogWindow )
|
|
return m_pDialogWindow->GetView().IsObjMarked(m_pDlgEdObj);
|
|
return false;
|
|
}
|
|
|
|
|
|
void AccessibleDialogControlShape::SetFocused( bool bFocused )
|
|
{
|
|
if ( m_bFocused != bFocused )
|
|
{
|
|
Any aOldValue, aNewValue;
|
|
if ( m_bFocused )
|
|
aOldValue <<= AccessibleStateType::FOCUSED;
|
|
else
|
|
aNewValue <<= AccessibleStateType::FOCUSED;
|
|
m_bFocused = bFocused;
|
|
NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
|
|
}
|
|
}
|
|
|
|
|
|
void AccessibleDialogControlShape::SetSelected( bool bSelected )
|
|
{
|
|
if ( m_bSelected != bSelected )
|
|
{
|
|
Any aOldValue, aNewValue;
|
|
if ( m_bSelected )
|
|
aOldValue <<= AccessibleStateType::SELECTED;
|
|
else
|
|
aNewValue <<= AccessibleStateType::SELECTED;
|
|
m_bSelected = bSelected;
|
|
NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
|
|
}
|
|
}
|
|
|
|
|
|
awt::Rectangle AccessibleDialogControlShape::GetBounds() const
|
|
{
|
|
awt::Rectangle aBounds( 0, 0, 0, 0 );
|
|
if ( m_pDlgEdObj )
|
|
{
|
|
// get the bounding box of the shape in logic units
|
|
tools::Rectangle aRect = m_pDlgEdObj->GetSnapRect();
|
|
|
|
if ( m_pDialogWindow )
|
|
{
|
|
// transform coordinates relative to the parent
|
|
MapMode aMap = m_pDialogWindow->GetMapMode();
|
|
Point aOrg = aMap.GetOrigin();
|
|
aRect.Move( aOrg.X(), aOrg.Y() );
|
|
|
|
// convert logic units to pixel
|
|
aRect = m_pDialogWindow->LogicToPixel( aRect, MapMode(MapUnit::Map100thMM) );
|
|
|
|
// clip the shape's bounding box with the bounding box of its parent
|
|
tools::Rectangle aParentRect( Point( 0, 0 ), m_pDialogWindow->GetSizePixel() );
|
|
aRect = aRect.GetIntersection( aParentRect );
|
|
aBounds = vcl::unohelper::ConvertToAWTRect(aRect);
|
|
}
|
|
}
|
|
|
|
return aBounds;
|
|
}
|
|
|
|
|
|
void AccessibleDialogControlShape::SetBounds( const awt::Rectangle& aBounds )
|
|
{
|
|
if ( m_aBounds.X != aBounds.X || m_aBounds.Y != aBounds.Y || m_aBounds.Width != aBounds.Width || m_aBounds.Height != aBounds.Height )
|
|
{
|
|
m_aBounds = aBounds;
|
|
NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any() );
|
|
}
|
|
}
|
|
|
|
|
|
vcl::Window* AccessibleDialogControlShape::GetWindow() const
|
|
{
|
|
vcl::Window* pWindow = nullptr;
|
|
if ( m_pDlgEdObj )
|
|
{
|
|
Reference< awt::XControl > xControl = m_pDlgEdObj->GetControl();
|
|
if ( xControl.is() )
|
|
pWindow = VCLUnoHelper::GetWindow( xControl->getPeer() );
|
|
}
|
|
|
|
return pWindow;
|
|
}
|
|
|
|
|
|
OUString AccessibleDialogControlShape::GetModelStringProperty( OUString const & pPropertyName )
|
|
{
|
|
OUString sReturn;
|
|
|
|
try
|
|
{
|
|
if ( m_xControlModel.is() )
|
|
{
|
|
Reference< XPropertySetInfo > xInfo = m_xControlModel->getPropertySetInfo();
|
|
if ( xInfo.is() && xInfo->hasPropertyByName( pPropertyName ) )
|
|
m_xControlModel->getPropertyValue( pPropertyName ) >>= sReturn;
|
|
}
|
|
}
|
|
catch ( const Exception& )
|
|
{
|
|
TOOLS_WARN_EXCEPTION( "basctl", "AccessibleDialogControlShape::GetModelStringProperty" );
|
|
}
|
|
|
|
return sReturn;
|
|
}
|
|
|
|
|
|
void AccessibleDialogControlShape::FillAccessibleStateSet( sal_Int64& rStateSet )
|
|
{
|
|
rStateSet |= AccessibleStateType::ENABLED;
|
|
|
|
rStateSet |= AccessibleStateType::VISIBLE;
|
|
|
|
rStateSet |= AccessibleStateType::SHOWING;
|
|
|
|
rStateSet |= AccessibleStateType::FOCUSABLE;
|
|
|
|
if ( IsFocused() )
|
|
rStateSet |= AccessibleStateType::FOCUSED;
|
|
|
|
rStateSet |= AccessibleStateType::SELECTABLE;
|
|
|
|
if ( IsSelected() )
|
|
rStateSet |= AccessibleStateType::SELECTED;
|
|
|
|
rStateSet |= AccessibleStateType::RESIZABLE;
|
|
}
|
|
|
|
// OCommonAccessibleComponent
|
|
awt::Rectangle AccessibleDialogControlShape::implGetBounds()
|
|
{
|
|
return GetBounds();
|
|
}
|
|
|
|
// XComponent
|
|
void AccessibleDialogControlShape::disposing()
|
|
{
|
|
OAccessibleExtendedComponentHelper::disposing();
|
|
|
|
m_pDialogWindow = nullptr;
|
|
m_pDlgEdObj = nullptr;
|
|
|
|
if ( m_xControlModel.is() )
|
|
m_xControlModel->removePropertyChangeListener( OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
|
|
m_xControlModel.clear();
|
|
}
|
|
|
|
|
|
// XEventListener
|
|
|
|
|
|
void AccessibleDialogControlShape::disposing( const lang::EventObject& )
|
|
{
|
|
if ( m_xControlModel.is() )
|
|
m_xControlModel->removePropertyChangeListener( OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
|
|
m_xControlModel.clear();
|
|
}
|
|
|
|
|
|
// XPropertyChangeListener
|
|
|
|
|
|
void AccessibleDialogControlShape::propertyChange( const beans::PropertyChangeEvent& rEvent )
|
|
{
|
|
if ( rEvent.PropertyName == DLGED_PROP_NAME )
|
|
{
|
|
NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, rEvent.OldValue, rEvent.NewValue );
|
|
}
|
|
else if ( rEvent.PropertyName == DLGED_PROP_POSITIONX ||
|
|
rEvent.PropertyName == DLGED_PROP_POSITIONY ||
|
|
rEvent.PropertyName == DLGED_PROP_WIDTH ||
|
|
rEvent.PropertyName == DLGED_PROP_HEIGHT )
|
|
{
|
|
SetBounds( GetBounds() );
|
|
}
|
|
else if ( rEvent.PropertyName == DLGED_PROP_BACKGROUNDCOLOR ||
|
|
rEvent.PropertyName == DLGED_PROP_TEXTCOLOR ||
|
|
rEvent.PropertyName == DLGED_PROP_TEXTLINECOLOR )
|
|
{
|
|
NotifyAccessibleEvent( AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any() );
|
|
}
|
|
}
|
|
|
|
// XServiceInfo
|
|
OUString AccessibleDialogControlShape::getImplementationName()
|
|
{
|
|
return u"com.sun.star.comp.basctl.AccessibleShape"_ustr;
|
|
}
|
|
|
|
sal_Bool AccessibleDialogControlShape::supportsService( const OUString& rServiceName )
|
|
{
|
|
return cppu::supportsService(this, rServiceName);
|
|
}
|
|
|
|
Sequence< OUString > AccessibleDialogControlShape::getSupportedServiceNames()
|
|
{
|
|
return { u"com.sun.star.drawing.AccessibleShape"_ustr };
|
|
}
|
|
|
|
// XAccessible
|
|
Reference< XAccessibleContext > AccessibleDialogControlShape::getAccessibleContext( )
|
|
{
|
|
return this;
|
|
}
|
|
|
|
// XAccessibleContext
|
|
sal_Int64 AccessibleDialogControlShape::getAccessibleChildCount()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
Reference< XAccessible > AccessibleDialogControlShape::getAccessibleChild( sal_Int64 i )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
if ( i < 0 || i >= getAccessibleChildCount() )
|
|
throw IndexOutOfBoundsException();
|
|
|
|
return Reference< XAccessible >();
|
|
}
|
|
|
|
|
|
Reference< XAccessible > AccessibleDialogControlShape::getAccessibleParent( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
Reference< XAccessible > xParent;
|
|
if ( m_pDialogWindow )
|
|
xParent = m_pDialogWindow->GetAccessible();
|
|
|
|
return xParent;
|
|
}
|
|
|
|
|
|
sal_Int64 AccessibleDialogControlShape::getAccessibleIndexInParent( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
sal_Int64 nIndexInParent = -1;
|
|
Reference< XAccessible > xParent( getAccessibleParent() );
|
|
if ( xParent.is() )
|
|
{
|
|
Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
|
|
if ( xParentContext.is() )
|
|
{
|
|
for ( sal_Int64 i = 0, nCount = xParentContext->getAccessibleChildCount(); i < nCount; ++i )
|
|
{
|
|
Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
|
|
if ( xChild.is() )
|
|
{
|
|
Reference< XAccessibleContext > xChildContext = xChild->getAccessibleContext();
|
|
if ( xChildContext == static_cast<XAccessibleContext*>(this) )
|
|
{
|
|
nIndexInParent = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nIndexInParent;
|
|
}
|
|
|
|
|
|
sal_Int16 AccessibleDialogControlShape::getAccessibleRole( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return AccessibleRole::SHAPE;
|
|
}
|
|
|
|
|
|
OUString AccessibleDialogControlShape::getAccessibleDescription( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return GetModelStringProperty( u"HelpText"_ustr );
|
|
}
|
|
|
|
|
|
OUString AccessibleDialogControlShape::getAccessibleName( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return GetModelStringProperty( u"Name"_ustr );
|
|
}
|
|
|
|
|
|
Reference< XAccessibleRelationSet > AccessibleDialogControlShape::getAccessibleRelationSet( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return new utl::AccessibleRelationSetHelper;
|
|
}
|
|
|
|
|
|
sal_Int64 AccessibleDialogControlShape::getAccessibleStateSet( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
sal_Int64 nStateSet = 0;
|
|
|
|
if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
|
|
{
|
|
FillAccessibleStateSet( nStateSet );
|
|
}
|
|
else
|
|
{
|
|
nStateSet |= AccessibleStateType::DEFUNC;
|
|
}
|
|
|
|
return nStateSet;
|
|
}
|
|
|
|
|
|
Locale AccessibleDialogControlShape::getLocale( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return Application::GetSettings().GetLanguageTag().getLocale();
|
|
}
|
|
|
|
|
|
// XAccessibleComponent
|
|
|
|
|
|
Reference< XAccessible > AccessibleDialogControlShape::getAccessibleAtPoint( const awt::Point& )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return Reference< XAccessible >();
|
|
}
|
|
|
|
|
|
void AccessibleDialogControlShape::grabFocus( )
|
|
{
|
|
// no focus for shapes
|
|
}
|
|
|
|
|
|
sal_Int32 AccessibleDialogControlShape::getForeground( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
Color nColor;
|
|
vcl::Window* pWindow = GetWindow();
|
|
if ( pWindow )
|
|
{
|
|
if ( pWindow->IsControlForeground() )
|
|
nColor = pWindow->GetControlForeground();
|
|
else
|
|
{
|
|
vcl::Font aFont;
|
|
if ( pWindow->IsControlFont() )
|
|
aFont = pWindow->GetControlFont();
|
|
else
|
|
aFont = pWindow->GetFont();
|
|
nColor = aFont.GetColor();
|
|
}
|
|
}
|
|
|
|
return sal_Int32(nColor);
|
|
}
|
|
|
|
|
|
sal_Int32 AccessibleDialogControlShape::getBackground( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
Color nColor;
|
|
vcl::Window* pWindow = GetWindow();
|
|
if ( pWindow )
|
|
{
|
|
if ( pWindow->IsControlBackground() )
|
|
nColor = pWindow->GetControlBackground();
|
|
else
|
|
nColor = pWindow->GetBackground().GetColor();
|
|
}
|
|
|
|
return sal_Int32(nColor);
|
|
}
|
|
|
|
|
|
// XAccessibleExtendedComponent
|
|
|
|
OUString AccessibleDialogControlShape::getTitledBorderText( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
return OUString();
|
|
}
|
|
|
|
|
|
OUString AccessibleDialogControlShape::getToolTipText( )
|
|
{
|
|
OExternalLockGuard aGuard( this );
|
|
|
|
OUString sText;
|
|
vcl::Window* pWindow = GetWindow();
|
|
if ( pWindow )
|
|
sText = pWindow->GetQuickHelpText();
|
|
|
|
return sText;
|
|
}
|
|
|
|
|
|
} // namespace basctl
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|