diff options
Diffstat (limited to 'accessibility')
146 files changed, 32837 insertions, 0 deletions
diff --git a/accessibility/AllLangMoTarget_acc.mk b/accessibility/AllLangMoTarget_acc.mk new file mode 100644 index 0000000000..a45cee50eb --- /dev/null +++ b/accessibility/AllLangMoTarget_acc.mk @@ -0,0 +1,13 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. + +$(eval $(call gb_AllLangMoTarget_AllLangMoTarget,acc)) + +$(eval $(call gb_AllLangMoTarget_set_polocation,acc,accessibility)) + +# vim: set noet sw=4 ts=4: diff --git a/accessibility/IwyuFilter_accessibility.yaml b/accessibility/IwyuFilter_accessibility.yaml new file mode 100644 index 0000000000..543ac74d92 --- /dev/null +++ b/accessibility/IwyuFilter_accessibility.yaml @@ -0,0 +1,12 @@ +--- +assumeFilename: accessibility/source/standard/accessiblemenucomponent.cxx +excludelist: + accessibility/source/standard/vclxaccessiblecombobox.cxx: + # Needed for implicit dtor + - vcl/window.hxx + accessibility/source/extended/accessibletabbar.cxx: + # Needed for implicit dtor + - com/sun/star/awt/XWindowPeer.hpp + accessibility/source/standard/accessiblemenucomponent.cxx: + # Needed for implicit dtor + - com/sun/star/awt/XWindowPeer.hpp diff --git a/accessibility/Library_acc.mk b/accessibility/Library_acc.mk new file mode 100644 index 0000000000..34c4dc7eb0 --- /dev/null +++ b/accessibility/Library_acc.mk @@ -0,0 +1,121 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Library_Library,acc)) + +$(eval $(call gb_Library_set_plugin_for,acc,tk)) + +$(eval $(call gb_Library_set_include,acc,\ + $$(INCLUDE) \ + -I$(SRCDIR)/accessibility/inc \ + -I$(SRCDIR)/accessibility/source/inc \ +)) + +$(eval $(call gb_Library_set_precompiled_header,acc,accessibility/inc/pch/precompiled_acc)) + +$(eval $(call gb_Library_use_external,acc,boost_headers)) + +$(eval $(call gb_Library_use_sdk_api,acc)) + +$(eval $(call gb_Library_use_libraries,acc,\ + comphelper \ + cppu \ + cppuhelper \ + sal \ + salhelper \ + i18nlangtag \ + sot \ + svl \ + svt \ + tl \ + utl \ + vcl \ +)) + +$(eval $(call gb_Library_add_defs,acc,\ + -DVCL_INTERNALS \ +)) + +$(eval $(call gb_Library_add_exception_objects,acc,\ + accessibility/source/extended/AccessibleBrowseBox \ + accessibility/source/extended/AccessibleBrowseBoxBase \ + accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell \ + accessibility/source/extended/AccessibleBrowseBoxHeaderBar \ + accessibility/source/extended/AccessibleBrowseBoxHeaderCell \ + accessibility/source/extended/AccessibleBrowseBoxTable \ + accessibility/source/extended/AccessibleBrowseBoxTableBase \ + accessibility/source/extended/AccessibleBrowseBoxTableCell \ + accessibility/source/extended/AccessibleGridControl \ + accessibility/source/extended/AccessibleGridControlBase \ + accessibility/source/extended/AccessibleGridControlHeader \ + accessibility/source/extended/AccessibleGridControlHeaderCell \ + accessibility/source/extended/AccessibleGridControlTable \ + accessibility/source/extended/AccessibleGridControlTableBase \ + accessibility/source/extended/AccessibleGridControlTableCell \ + accessibility/source/extended/accessiblebrowseboxcell \ + accessibility/source/extended/accessibleeditbrowseboxcell \ + accessibility/source/extended/accessibleiconchoicectrl \ + accessibility/source/extended/accessibleiconchoicectrlentry \ + accessibility/source/extended/AccessibleIconView \ + accessibility/source/extended/accessiblelistbox \ + accessibility/source/extended/accessiblelistboxentry \ + accessibility/source/extended/accessibletablistbox \ + accessibility/source/extended/accessibletablistboxtable \ + accessibility/source/extended/textwindowaccessibility \ + accessibility/source/helper/acc_factory \ + accessibility/source/helper/accresmgr \ + accessibility/source/helper/characterattributeshelper \ + accessibility/source/helper/IComboListBoxHelper \ + accessibility/source/standard/accessiblemenubasecomponent \ + accessibility/source/standard/accessiblemenucomponent \ + accessibility/source/standard/accessiblemenuitemcomponent \ + accessibility/source/standard/floatingwindowaccessible \ + accessibility/source/standard/svtaccessiblenumericfield \ + accessibility/source/standard/vclxaccessiblebox \ + accessibility/source/standard/vclxaccessiblebutton \ + accessibility/source/standard/vclxaccessiblecheckbox \ + accessibility/source/standard/vclxaccessiblecombobox \ + accessibility/source/standard/vclxaccessibledropdowncombobox \ + accessibility/source/standard/vclxaccessibledropdownlistbox \ + accessibility/source/standard/vclxaccessibleedit \ + accessibility/source/standard/vclxaccessiblefixedhyperlink \ + accessibility/source/standard/vclxaccessiblefixedtext \ + accessibility/source/standard/vclxaccessibleheaderbar \ + accessibility/source/standard/vclxaccessibleheaderbaritem \ + accessibility/source/standard/vclxaccessiblelist \ + accessibility/source/standard/vclxaccessiblelistbox \ + accessibility/source/standard/vclxaccessiblelistitem \ + accessibility/source/standard/vclxaccessiblemenu \ + accessibility/source/standard/vclxaccessiblemenubar \ + accessibility/source/standard/vclxaccessiblemenuitem \ + accessibility/source/standard/vclxaccessiblemenuseparator \ + accessibility/source/standard/vclxaccessiblepopupmenu \ + accessibility/source/standard/vclxaccessibleradiobutton \ + accessibility/source/standard/vclxaccessiblescrollbar \ + accessibility/source/standard/vclxaccessiblestatusbar \ + accessibility/source/standard/vclxaccessiblestatusbaritem \ + accessibility/source/standard/vclxaccessibletabcontrol \ + accessibility/source/standard/vclxaccessibletabpage \ + accessibility/source/standard/vclxaccessibletabpagewindow \ + accessibility/source/standard/vclxaccessibletextcomponent \ + accessibility/source/standard/vclxaccessibletextfield \ + accessibility/source/standard/vclxaccessibletoolbox \ + accessibility/source/standard/vclxaccessibletoolboxitem \ +)) + +ifneq ($(filter SCRIPTING,$(BUILD_TYPE)),) +$(eval $(call gb_Library_add_exception_objects,acc,\ + accessibility/source/extended/accessibletabbar \ + accessibility/source/extended/accessibletabbarbase \ + accessibility/source/extended/accessibletabbarpage \ + accessibility/source/extended/accessibletabbarpagelist \ +)) +endif + +# vim:set noet sw=4 ts=4: diff --git a/accessibility/Makefile b/accessibility/Makefile new file mode 100644 index 0000000000..0997e62848 --- /dev/null +++ b/accessibility/Makefile @@ -0,0 +1,14 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +include $(module_directory)/../solenv/gbuild/partial_build.mk + +# vim: set noet sw=4 ts=4: diff --git a/accessibility/Module_accessibility.mk b/accessibility/Module_accessibility.mk new file mode 100644 index 0000000000..de252a36d5 --- /dev/null +++ b/accessibility/Module_accessibility.mk @@ -0,0 +1,20 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Module_Module,accessibility)) + +$(eval $(call gb_Module_add_targets,accessibility,\ + Library_acc \ +)) + +$(eval $(call gb_Module_add_l10n_targets,accessibility,\ + AllLangMoTarget_acc \ +)) + +# vim:set noet sw=4 ts=4: diff --git a/accessibility/README.md b/accessibility/README.md new file mode 100644 index 0000000000..6e11da1ace --- /dev/null +++ b/accessibility/README.md @@ -0,0 +1,3 @@ +# Accessibility Support for LibreOffice + +Provides accessible components for LibreOffice diff --git a/accessibility/inc/extended/AccessibleBrowseBox.hxx b/accessibility/inc/extended/AccessibleBrowseBox.hxx new file mode 100644 index 0000000000..b7e912df6e --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBox.hxx @@ -0,0 +1,276 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleBrowseBoxBase.hxx> +#include <cppuhelper/weakref.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <mutex> + +namespace accessibility { + + class AccessibleBrowseBoxHeaderBar; + class AccessibleBrowseBoxTable; + + +/** This class represents the complete accessible BrowseBox object. */ +class AccessibleBrowseBox : public AccessibleBrowseBoxBase +{ + friend class AccessibleBrowseBoxAccess; + +protected: + AccessibleBrowseBox( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator, + ::vcl::IAccessibleTableProvider& _rBrowseBox + ); + + virtual ~AccessibleBrowseBox() override; + + /** sets the XAccessible which created the context + + To be called only once, and only if in the ctor NULL was passed. + */ + void setCreator( + const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator + ); + + /** Cleans up members. */ + using AccessibleBrowseBoxBase::disposing; + virtual void SAL_CALL disposing() override; + +protected: + // XAccessibleContext + + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< + css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + // XAccessibleComponent + + /** @return + The accessible child rendered under the given point. + */ + virtual css::uno::Reference< + css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + /** Grabs the focus to the BrowseBox. */ + virtual void SAL_CALL grabFocus() override; + + // XServiceInfo + + /** @return + The name of this class. + */ + virtual OUString SAL_CALL getImplementationName() override; + +public: + // helper functions + /** commitHeaderBarEvent commit the event at all listeners of the column/row header bar + @param nEventId + the event id + @param rNewValue + the new value + @param rOldValue + the old value + @param _bColumnHeaderBar + true if a column based header bar, false if a row based header bar + */ + void commitHeaderBarEvent(sal_Int16 nEventId, + const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue, bool _bColumnHeaderBar); + + // helper functions + /** commitTableEvent commit the event at all listeners of the table + @param nEventId + the event id + @param rNewValue + the new value + @param rOldValue + the old value + */ + void commitTableEvent(sal_Int16 nEventId, + const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue); + + /** returns the accessible object for the row or the column header bar + */ + css::uno::Reference< + css::accessibility::XAccessible > + getHeaderBar( AccessibleBrowseBoxObjType _eObjType ) + { + return implGetHeaderBar(_eObjType); + } + + /** returns the accessible object for the table representation + */ + css::uno::Reference< + css::accessibility::XAccessible > + getTable( ) + { + return implGetTable(); + } + +protected: + // internal virtual methods + + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() override; + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + // internal helper methods + + /** This method creates (once) and returns the accessible data table child. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the data table. */ + css::uno::Reference< + css::accessibility::XAccessible > implGetTable(); + + /** This method creates (once) and returns the specified header bar. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the header bar. */ + css::uno::Reference< + css::accessibility::XAccessible > + implGetHeaderBar( AccessibleBrowseBoxObjType eObjType ); + + /** This method returns one of the children that are always present: + Data table, row and column header bar or corner control. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the specified child. */ + css::uno::Reference< + css::accessibility::XAccessible > + implGetFixedChild( sal_Int64 nChildIndex ); + + /** This method creates and returns an accessible table. + @return An AccessibleBrowseBoxTable. */ + virtual rtl::Reference<AccessibleBrowseBoxTable> createAccessibleTable(); + +private: + /// the css::accessibility::XAccessible which created the AccessibleBrowseBox + css::uno::WeakReference< css::accessibility::XAccessible > m_aCreator; + + /** The data table child. */ + rtl::Reference<AccessibleBrowseBoxTable> mxTable; + + /** The header bar for rows ("handle column"). */ + rtl::Reference<AccessibleBrowseBoxHeaderBar> mxRowHeaderBar; + + /** The header bar for columns (first row of the table). */ + rtl::Reference<AccessibleBrowseBoxHeaderBar> mxColumnHeaderBar; +}; + + +/** the XAccessible which creates/returns an AccessibleBrowseBox + + The instance holds its XAccessibleContext with a hard reference, while + the context holds this instance weak. +*/ +class AccessibleBrowseBoxAccess final : public ::vcl::IAccessibleBrowseBox +{ +private: + std::mutex m_aMutex; + css::uno::Reference< css::accessibility::XAccessible > + m_xParent; + ::vcl::IAccessibleTableProvider& m_rBrowseBox; + + rtl::Reference<AccessibleBrowseBox> m_xContext; + +public: + AccessibleBrowseBoxAccess( + css::uno::Reference< css::accessibility::XAccessible > _xParent, + ::vcl::IAccessibleTableProvider& _rBrowseBox + ); + + /// returns the AccessibleContext belonging to this Accessible + AccessibleBrowseBox* getContext() { return m_xContext.get(); } + +private: + virtual ~AccessibleBrowseBoxAccess() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + SAL_CALL getAccessibleContext() override; + + // IAccessibleBrowseBox + void dispose() override; + virtual bool isAlive() const override + { + return m_xContext.is() && m_xContext->isAlive(); + } + virtual css::uno::Reference< css::accessibility::XAccessible > + getHeaderBar( AccessibleBrowseBoxObjType _eObjType ) override + { + css::uno::Reference< css::accessibility::XAccessible > xAccessible; + AccessibleBrowseBox* pContext( getContext() ); + if ( pContext ) + xAccessible = pContext->getHeaderBar( _eObjType ); + return xAccessible; + } + virtual css::uno::Reference< css::accessibility::XAccessible > + getTable() override + { + css::uno::Reference< css::accessibility::XAccessible > xAccessible; + AccessibleBrowseBox* pContext( getContext() ); + if ( pContext ) + xAccessible = pContext->getTable(); + return xAccessible; + } + virtual void commitHeaderBarEvent( sal_Int16 nEventId, const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue, bool _bColumnHeaderBar ) override + { + AccessibleBrowseBox* pContext( getContext() ); + if ( pContext ) + pContext->commitHeaderBarEvent( nEventId, rNewValue, rOldValue, _bColumnHeaderBar ); + } + virtual void commitTableEvent( sal_Int16 nEventId, + const css::uno::Any& rNewValue, const css::uno::Any& rOldValue ) override + { + AccessibleBrowseBox* pContext( getContext() ); + if ( pContext ) + pContext->commitTableEvent( nEventId, rNewValue, rOldValue ); + } + virtual void commitEvent( sal_Int16 nEventId, + const css::uno::Any& rNewValue, const css::uno::Any& rOldValue ) override + { + AccessibleBrowseBox* pContext( getContext() ); + if ( pContext ) + pContext->commitEvent( nEventId, rNewValue, rOldValue ); + } + +private: + AccessibleBrowseBoxAccess( const AccessibleBrowseBoxAccess& ) = delete; + AccessibleBrowseBoxAccess& operator=( const AccessibleBrowseBoxAccess& ) = delete; +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxBase.hxx b/accessibility/inc/extended/AccessibleBrowseBoxBase.hxx new file mode 100644 index 0000000000..d4ea1aabc0 --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxBase.hxx @@ -0,0 +1,403 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <sal/config.h> + +#include <vcl/AccessibleBrowseBoxObjType.hxx> +#include <rtl/ustring.hxx> +#include <tools/gen.hxx> +#include <vcl/svapp.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/awt/XFocusListener.hpp> +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/uno3.hxx> + + +namespace vcl { class Window; } + +namespace vcl { + class IAccessibleTableProvider; +} + +namespace accessibility { + +typedef ::cppu::WeakComponentImplHelper< + css::accessibility::XAccessibleContext, + css::accessibility::XAccessibleComponent, + css::accessibility::XAccessibleEventBroadcaster, + css::awt::XFocusListener, + css::lang::XServiceInfo > + AccessibleBrowseBoxImplHelper; + +/** The BrowseBox accessible objects inherit from this base class. It + implements basic functionality for various Accessibility interfaces and + the event broadcaster and contains the osl::Mutex. */ +class AccessibleBrowseBoxBase : + public ::cppu::BaseMutex, + public AccessibleBrowseBoxImplHelper +{ +public: + /** Constructor sets specified name and description. If the constant of a + text is BBTEXT_NONE, the derived class has to set the text via + implSetName() (in Ctor) or later via + setAccessibleName() and setAccessibleDescription() (these methods + notify the listeners about the change). + + @param rxParent XAccessible interface of the parent object. + @param rBrowseBox The BrowseBox control. + @param _xFocusWindow The window that gets all the focus events. + @param eObjType Object type */ + AccessibleBrowseBoxBase( + css::uno::Reference< css::accessibility::XAccessible > xParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + css::uno::Reference< css::awt::XWindow > _xFocusWindow, + AccessibleBrowseBoxObjType eObjType ); + + /** Constructor sets specified name and description. + @param rxParent XAccessible interface of the parent object. + @param rBrowseBox The BrowseBox control. + @param _xFocusWindow The window that gets all the focus events. + @param eObjType Object type + @param rName The name of this object. + @param rDescription The description text of this object. */ + AccessibleBrowseBoxBase( + css::uno::Reference< css::accessibility::XAccessible > xParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + css::uno::Reference< css::awt::XWindow > _xFocusWindow, + AccessibleBrowseBoxObjType eObjType, + OUString rName, + OUString rDescription ); + +protected: + virtual ~AccessibleBrowseBoxBase() override; + + /** Commits DeFunc event to listeners and cleans up members. */ + virtual void SAL_CALL disposing() override; + +public: + // XAccessibleContext + + /** @return A reference to the parent accessible object. */ + virtual css::uno::Reference<css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + /** @return + The description of this object. + */ + virtual OUString SAL_CALL getAccessibleDescription() override; + + /** @return + The name of this object. + */ + virtual OUString SAL_CALL getAccessibleName() override; + + /** @return + The relation set (the BrowseBox does not have one). + */ + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override; + + /** @return The set of current states. */ + virtual sal_Int64 SAL_CALL getAccessibleStateSet() override; + + /** @return The parent's locale. */ + virtual css::lang::Locale SAL_CALL getLocale() override; + + /** @return + The role of this object. Panel, ROWHEADER, COLUMNHEADER, TABLE, TABLE_CELL are supported. + */ + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + /* Derived classes have to implement: + - getAccessibleChildCount, + - getAccessibleChild, + - getAccessibleRole. + Derived classes may overwrite getAccessibleIndexInParent to increase + performance. */ + + // XAccessibleComponent + + /** @return + TRUE, if the point lies within the bounding box of this object. */ + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& rPoint ) override; + + /** @return The bounding box of this object. */ + virtual css::awt::Rectangle SAL_CALL getBounds() override; + + /** @return + The upper left corner of the bounding box relative to the parent. */ + virtual css::awt::Point SAL_CALL getLocation() override; + + /** @return + The upper left corner of the bounding box in screen coordinates. */ + virtual css::awt::Point SAL_CALL getLocationOnScreen() override; + + /** @return The size of the bounding box. */ + virtual css::awt::Size SAL_CALL getSize() override; + + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XFocusListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + virtual void SAL_CALL focusGained( const css::awt::FocusEvent& e ) override; + virtual void SAL_CALL focusLost( const css::awt::FocusEvent& e ) override; + + /* Derived classes have to implement: + - getAccessibleAt, + - grabFocus. */ + + /** @return + The accessible child rendered under the given point. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + // XAccessibleEventBroadcaster + + /** Adds a new event listener */ + virtual void SAL_CALL addAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& rxListener ) override; + + /** Removes an event listener. */ + virtual void SAL_CALL removeAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& rxListener ) override; + + // XTypeProvider + + /** @return a unique implementation ID. */ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + + // XServiceInfo + + /** @return Whether the specified service is supported by this class. */ + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + + /** @return A list of all supported services. */ + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + /* Derived classes have to implement: + - getImplementationName. */ + + // helper methods + + /** @return The BrowseBox object type. */ + inline AccessibleBrowseBoxObjType getType() const; + + /** Changes the name of the object and notifies listeners. */ + void setAccessibleName( const OUString& rName ); + /** Changes the description of the object and notifies listeners. */ + void setAccessibleDescription( const OUString& rDescription ); + + /** Commits an event to all listeners. */ + void commitEvent( + sal_Int16 nEventId, + const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue ); + /** @return TRUE, if the object is not disposed or disposing. */ + bool isAlive() const; + +protected: + // internal virtual methods + + /** Determines whether the BrowseBox control is really showing inside of + its parent accessible window. Derived classes may implement different + behaviour. + @attention This method requires locked mutex's and a living object. + @return TRUE, if the object is really showing. */ + bool implIsShowing(); + + /** Derived classes return the bounding box relative to the parent window. + @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() = 0; + /** Derived classes return the bounding box in screen coordinates. + @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() = 0; + + /** Creates a bitset of states of the + current object. This method calls FillStateSet at the BrowseBox which + fills it with more states depending on the object type. Derived classes + may overwrite this method and add more states. + @attention This method requires locked mutex's. + */ + virtual sal_Int64 implCreateStateSet(); + + // internal helper methods + + /** Changes the name of the object (flat assignment, no notify). + @attention This method requires a locked mutex. */ + inline void implSetName( const OUString& rName ); + + /** Locks all mutex's and calculates the bounding box relative to the + parent window. + @return The bounding box (VCL rect.) relative to the parent object. + @throws css::lang::DisposedException + */ + tools::Rectangle getBoundingBox(); + /** Locks all mutex's and calculates the bounding box in screen + coordinates. + @return The bounding box (VCL rect.) in screen coordinates. + @throws css::lang::DisposedException + */ + AbsoluteScreenPixelRectangle getBoundingBoxOnScreen(); + +public: + /** @return The osl::Mutex member provided by the class BaseMutex. */ + ::osl::Mutex& getMutex( ) { return m_aMutex; } + + /** @throws <type>DisposedException</type> If the object is not alive. */ + void ensureIsAlive() const; + + +protected: + // members + + /** The parent accessible object. */ + css::uno::Reference< css::accessibility::XAccessible > mxParent; + /** The VCL BrowseBox control. */ + ::vcl::IAccessibleTableProvider* mpBrowseBox; + + /** This is the window which get all the nice focus events + */ + css::uno::Reference< css::awt::XWindow > m_xFocusWindow; + +private: + ::comphelper::AccessibleEventNotifier::TClientId getClientId() const { return m_aClientId; } + void setClientId(::comphelper::AccessibleEventNotifier::TClientId _aNewClientId) { m_aClientId = _aNewClientId; } + + /** Localized name. */ + OUString maName; + /** Localized description text. */ + OUString maDescription; + + /** The type of this object (for names, descriptions, state sets, ...). */ + AccessibleBrowseBoxObjType meObjType; + + ::comphelper::AccessibleEventNotifier::TClientId m_aClientId; +}; + + +// a version of AccessibleBrowseBoxBase which implements not only the XAccessibleContext, +// but also the XAccessible + +typedef ::cppu::ImplHelper1 < css::accessibility::XAccessible + > BrowseBoxAccessibleElement_Base; + +class BrowseBoxAccessibleElement + :public AccessibleBrowseBoxBase + ,public BrowseBoxAccessibleElement_Base +{ +protected: + /** Constructor sets specified name and description. If the constant of a + text is BBTEXT_NONE, the derived class has to set the text via + implSetName() (in Ctor) or later via + setAccessibleName() and setAccessibleDescription() (these methods + notify the listeners about the change). + + @param rxParent XAccessible interface of the parent object. + @param rBrowseBox The BrowseBox control. + @param _xFocusWindow The window that gets all the focus events. + @param eObjType Object type + */ + BrowseBoxAccessibleElement( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType eObjType ); + + /** Constructor sets specified name and description. + + @param rxParent XAccessible interface of the parent object. + @param rBrowseBox The BrowseBox control. + @param _xFocusWindow The window that gets all the focus events. + @param eObjType Object type + @param rName The name of this object. + @param rDescription The description text of this object. + */ + BrowseBoxAccessibleElement( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType eObjType, + const OUString& rName, + const OUString& rDescription ); + +public: + // noncopyable + BrowseBoxAccessibleElement(const BrowseBoxAccessibleElement&) = delete; + const BrowseBoxAccessibleElement& operator=(const BrowseBoxAccessibleElement&) = delete; + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + +protected: + virtual ~BrowseBoxAccessibleElement() override; + +protected: + // XAccessible + + /** @return The XAccessibleContext interface of this object. */ + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override; +}; + + +// a helper class for protecting methods which need to lock the solar mutex in addition to the own mutex + +class SolarMethodGuard : public SolarMutexGuard, public osl::MutexGuard +{ +public: + SolarMethodGuard( osl::Mutex& rMutex ) + :SolarMutexGuard( ) + ,osl::MutexGuard( rMutex ) + { + } +}; + +// inlines + +inline AccessibleBrowseBoxObjType AccessibleBrowseBoxBase::getType() const +{ + return meObjType; +} + +inline void AccessibleBrowseBoxBase::implSetName( + const OUString& rName ) +{ + maName = rName; +} + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxCheckBoxCell.hxx b/accessibility/inc/extended/AccessibleBrowseBoxCheckBoxCell.hxx new file mode 100644 index 0000000000..dbc2fbd52a --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxCheckBoxCell.hxx @@ -0,0 +1,80 @@ +/* -*- 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 . + */ +#pragma once + +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <extended/accessiblebrowseboxcell.hxx> +#include <cppuhelper/implbase2.hxx> + +namespace accessibility +{ + + typedef ::cppu::ImplHelper2 < css::accessibility::XAccessible, + css::accessibility::XAccessibleValue + > AccessibleCheckBoxCell_BASE; + + class AccessibleCheckBoxCell final : public AccessibleBrowseBoxCell + ,public AccessibleCheckBoxCell_BASE + { + private: + TriState m_eState; + bool m_bIsTriState; + + virtual ~AccessibleCheckBoxCell() override {} + + virtual sal_Int64 implCreateStateSet() override; + + public: + AccessibleCheckBoxCell(const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + const TriState& _eState, + bool _bIsTriState); + + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; + + // internal + void SetChecked( bool _bChecked ); + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxHeaderBar.hxx b/accessibility/inc/extended/AccessibleBrowseBoxHeaderBar.hxx new file mode 100644 index 0000000000..d353b8c601 --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxHeaderBar.hxx @@ -0,0 +1,218 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleBrowseBoxTableBase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> + + +namespace accessibility { + + +typedef ::cppu::ImplHelper1< css::accessibility::XAccessibleSelection > + AccessibleBrowseBoxHeaderBarImplHelper; + +/** This class represents the accessible object of a header bar of a BrowseBox + control (row or column header bar). This object supports the + XAccessibleSelection interface. Selecting a child of this object selects + complete rows or columns of the data table. */ +class AccessibleBrowseBoxHeaderBar final : + public AccessibleBrowseBoxTableBase, + public AccessibleBrowseBoxHeaderBarImplHelper +{ +public: + /** @param rxParent Parent that holds the browsebox headerbar control + @param rBrowseBox The BrowseBox control. + @param eObjType One of the two allowed types AccessibleBrowseBoxObjType::RowHeaderBar or + AccessibleBrowseBoxObjType::ColumnHeaderBar. */ + AccessibleBrowseBoxHeaderBar( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + AccessibleBrowseBoxObjType eObjType ); + +private: + virtual ~AccessibleBrowseBoxHeaderBar() override; + +public: + // XAccessibleContext + + /** @return + The XAccessible interface of the specified child. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + // XAccessibleComponent + + /** @return The accessible child rendered under the given point. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + /** Grabs the focus to (the current cell of) the data table. */ + virtual void SAL_CALL grabFocus() override; + + // XAccessibleTable + + /** @return The description text of the specified row. */ + virtual OUString SAL_CALL + getAccessibleRowDescription( sal_Int32 nRow ) override; + + /** @return The description text of the specified column. */ + virtual OUString SAL_CALL getAccessibleColumnDescription( sal_Int32 nColumn ) override; + + /** @return The XAccessibleTable interface of the row header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleRowHeaders() override; + + /** @return The XAccessibleTable interface of the column header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleColumnHeaders() override; + + /** @return An index list of completely selected rows. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleRows() override; + + /** @return An index list of completely selected columns. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleColumns() override; + + /** @return TRUE, if the specified row is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleRowSelected( sal_Int32 nRow ) override; + + /** @return TRUE, if the specified column is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleColumnSelected( sal_Int32 nColumn ) override; + + /** @return The XAccessible interface of the cell object at the specified + cell position. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return TRUE, if the specified cell is selected. */ + virtual sal_Bool SAL_CALL isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) override; + + // XAccessibleSelection + + /** Selects the specified child (row or column of the table). */ + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return TRUE, if the specified child (row/column) is selected. */ + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + + /** Clears the complete selection. */ + virtual void SAL_CALL clearAccessibleSelection() override; + + /** Selects all children or first, if multiselection is not supported. */ + virtual void SAL_CALL selectAllAccessibleChildren() override; + + /** @return The number of selected rows/columns. */ + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount() override; + + /** @return The specified selected row/column. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + + /** Removes the specified row/column from the selection. */ + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + + // XInterface + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + + // XServiceInfo + + /** @return The name of this class. */ + virtual OUString SAL_CALL getImplementationName() override; + + /** @return a unique implementation ID. */ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + +private: + // internal virtual methods + + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() override; + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + /** @attention This method requires locked mutex's and a living object. + @return The count of used rows. */ + virtual sal_Int32 implGetRowCount() const override; + /** @attention This method requires locked mutex's and a living object. + @return The count of used columns. */ + virtual sal_Int32 implGetColumnCount() const override; + + // internal helper methods + + /** @return TRUE, if the objects is a header bar for rows. */ + inline bool isRowBar() const; + /** @return TRUE, if the objects is a header bar for columns. */ + inline bool isColumnBar() const; + + /** Returns the specified row or column. Uses one of the parameters, + depending on object type. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the specified column/row. */ + css::uno::Reference< css::accessibility::XAccessible > + implGetChild( sal_Int32 nRow, sal_uInt16 nColumnPos ); + + /** @attention This method requires locked mutex's and a living object. + @return The absolute child index from the index of selected children. + @throws <type>IndexOutOfBoundsException</type> + If the specified index is invalid. */ + sal_Int64 implGetChildIndexFromSelectedIndex( sal_Int64 nSelectedChildIndex ); + + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified row/column index (depending on type) is invalid. */ + void ensureIsValidHeaderIndex( sal_Int32 nIndex ); +}; + +// inlines + +inline bool AccessibleBrowseBoxHeaderBar::isRowBar() const +{ + return getType() == AccessibleBrowseBoxObjType::RowHeaderBar; +} + +inline bool AccessibleBrowseBoxHeaderBar::isColumnBar() const +{ + return getType() == AccessibleBrowseBoxObjType::ColumnHeaderBar; +} + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxHeaderCell.hxx b/accessibility/inc/extended/AccessibleBrowseBoxHeaderCell.hxx new file mode 100644 index 0000000000..530e9f37f1 --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxHeaderCell.hxx @@ -0,0 +1,69 @@ +/* -*- 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 . + */ +#pragma once + +#include <extended/AccessibleBrowseBoxBase.hxx> + +namespace accessibility +{ + class AccessibleBrowseBoxHeaderCell final : public BrowseBoxAccessibleElement + { + sal_Int32 m_nColumnRowId; + public: + AccessibleBrowseBoxHeaderCell(sal_Int32 _nColumnRowId, + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType _eObjType); + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + /** Grabs the focus to the BrowseBox. */ + virtual void SAL_CALL grabFocus() override; + + bool isRowBarCell() const + { + return getType() == AccessibleBrowseBoxObjType::RowHeaderCell; + } + + /** @return + The name of this class. + */ + virtual OUString SAL_CALL getImplementationName() override; + + /** Return a bitset of states of the current object. + */ + sal_Int64 implCreateStateSet() override; + + private: + virtual tools::Rectangle implGetBoundingBox() override; + + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + }; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxTable.hxx b/accessibility/inc/extended/AccessibleBrowseBoxTable.hxx new file mode 100644 index 0000000000..8892ff384e --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxTable.hxx @@ -0,0 +1,129 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleBrowseBoxTableBase.hxx> + + +namespace accessibility { + +/** This class represents the accessible object of the data table of a + BrowseBox control. */ +class AccessibleBrowseBoxTable : public AccessibleBrowseBoxTableBase +{ + friend class AccessibleBrowseBox; // to create header bars + +public: + AccessibleBrowseBoxTable( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::IAccessibleTableProvider& rBrowseBox ); + +protected: + virtual ~AccessibleBrowseBoxTable() override; + +public: + // XAccessibleContext + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + // XAccessibleComponent + + /** @return The accessible child rendered under the given point. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + /** Grabs the focus to (the current cell of) the data table. */ + virtual void SAL_CALL grabFocus() override; + + // XAccessibleTable + + /** @return The description text of the specified row. */ + virtual OUString SAL_CALL getAccessibleRowDescription( sal_Int32 nRow ) override; + + /** @return The description text of the specified column. */ + virtual OUString SAL_CALL getAccessibleColumnDescription( sal_Int32 nColumn ) override; + + /** @return The XAccessibleTable interface of the row header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleRowHeaders() override; + + /** @return The XAccessibleTable interface of the column header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleColumnHeaders() override; + + /** @return An index list of completely selected rows. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleRows() override; + + /** @return An index list of completely selected columns. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleColumns() override; + + /** @return TRUE, if the specified row is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleRowSelected( sal_Int32 nRow ) override; + + /** @return TRUE, if the specified column is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleColumnSelected( sal_Int32 nColumn ) override; + + /** @return The XAccessible interface of the cell object at the specified + cell position. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return TRUE, if the specified cell is selected. */ + virtual sal_Bool SAL_CALL isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) override; + + // XServiceInfo + + /** @return The name of this class. */ + virtual OUString SAL_CALL getImplementationName() override; + +protected: + // internal virtual methods + + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() override; + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + // internal helper methods + + /** @attention This method requires a locked mutex. + @return The XAccessibleTable interface of the specified header bar. + @throws css::uno::RuntimeException + */ + css::uno::Reference< css::accessibility::XAccessibleTable > + implGetHeaderBar( sal_Int32 nChildIndex ); +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxTableBase.hxx b/accessibility/inc/extended/AccessibleBrowseBoxTableBase.hxx new file mode 100644 index 0000000000..422aa177ad --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxTableBase.hxx @@ -0,0 +1,239 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleBrowseBoxBase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> + + +namespace accessibility { + +typedef ::cppu::ImplHelper1< css::accessibility::XAccessibleTable > + AccessibleBrowseBoxTableImplHelper; + +/** The BrowseBox accessible table objects inherit from this base class. It + implements basic functionality for the XAccessibleTable interface. + BrowseBox table objects are: the data table, the column header bar and the + row header bar. */ +class AccessibleBrowseBoxTableBase : + public BrowseBoxAccessibleElement, + public AccessibleBrowseBoxTableImplHelper +{ +public: + /** Constructor sets specified name and description. If the constant of a + text is BBTEXT_NONE, the derived class has to set the text via + implSetName() and implSetDescription() (in Ctor) or later via + setAccessibleName() and setAccessibleDescription() (these methods + notify the listeners about the change). + @param rxParent XAccessible interface of the parent object. + @param rBrowseBox The BrowseBox control. + @param eObjType Type of BrowseBox object. */ + AccessibleBrowseBoxTableBase( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + AccessibleBrowseBoxObjType eObjType ); + +protected: + virtual ~AccessibleBrowseBoxTableBase() override = default; + +public: + // XAccessibleContext + + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The role of this object (a table). */ + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + /* Derived classes have to implement: + - getAccessibleChild, + - getAccessibleIndexInParent. */ + + // XAccessibleComponent + + /* Derived classes have to implement: + - getAccessibleAt, + - grabFocus. */ + + // XAccessibleTable + + /** @return The number of used rows in the table (0 = empty table). */ + virtual sal_Int32 SAL_CALL getAccessibleRowCount() override; + + /** @return The number of used columns in the table (0 = empty table). */ + virtual sal_Int32 SAL_CALL getAccessibleColumnCount() override; + + /** @return The row extent of the specified cell (always 1). */ + virtual sal_Int32 SAL_CALL + getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return The column extent of the specified cell (always 1). */ + virtual sal_Int32 SAL_CALL + getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return The caption cell of the table (not supported). */ + virtual css::uno::Reference< + css::accessibility::XAccessible > SAL_CALL + getAccessibleCaption() override; + + /** @return The summary object of the table (not supported). */ + virtual css::uno::Reference< + css::accessibility::XAccessible > SAL_CALL + getAccessibleSummary() override; + + /** @return The child index of the specified cell. */ + virtual sal_Int64 SAL_CALL getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return The row index of the specified child cell. */ + virtual sal_Int32 SAL_CALL getAccessibleRow( sal_Int64 nChildIndex ) override; + + /** @return The column index of the specified child cell. */ + virtual sal_Int32 SAL_CALL getAccessibleColumn( sal_Int64 nChildIndex ) override; + + /* Derived classes have to implement: + - getAccessibleRowDescription, + - getAccessibleColumnDescription, + - getAccessibleRowHeaders, + - getAccessibleColumnHeaders, + - getSelectedAccessibleRows, + - getSelectedAccessibleColumns, + - isAccessibleRowSelected, + - isAccessibleColumnSelected, + - getAccessibleCellAt, + - isAccessibleSelected. */ + + // XInterface + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + + // XTypeProvider + + /** @return a sequence of possible types (received from base classes). */ + virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override; + + /** @return a unique implementation ID. */ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + + // XServiceInfo + + /* Derived classes have to implement: + - getImplementationName */ + +protected: + // internal virtual methods + + /** @attention This method requires locked mutex's and a living object. + @return The count of data rows without header bar. */ + virtual sal_Int32 implGetRowCount() const; + /** @attention This method requires locked mutex's and a living object. + @return The count of data columns without "handle column". */ + virtual sal_Int32 implGetColumnCount() const; + + // internal helper methods + + /** @return TRUE, if first BrowseBox column is the "handle column". */ + bool implHasHandleColumn() const; + + /** @attention This method requires locked mutex's and a living object. + @param nColumn + the position of the column in the Accessible world + @return + the position of the column in VCL the Accessible world + */ + sal_uInt16 implToVCLColumnPos( sal_Int32 nColumn ) const; + + /** @attention This method requires locked mutex's and a living object. + @return The number of cells of the table. */ + sal_Int64 implGetChildCount() const; + + /** @attention This method requires locked mutex's and a living object. + @return The row index of the specified cell index. */ + sal_Int32 implGetRow( sal_Int64 nChildIndex ) const; + /** @attention This method requires locked mutex's and a living object. + @return The column index of the specified cell index. */ + sal_Int32 implGetColumn( sal_Int64 nChildIndex ) const; + + /** @attention This method requires locked mutex's and a living object. + @return TRUE, if the specified row is selected. */ + bool implIsRowSelected( sal_Int32 nRow ) const; + /** @attention This method requires locked mutex's and a living object. + @return TRUE, if the specified column is selected. */ + bool implIsColumnSelected( sal_Int32 nColumn ) const; + + /** Selects/deselects a row (tries to expand selection). + @attention This method requires locked mutex's and a living object. + @param nRow Row to select + @param bSelect TRUE = select, FALSE = deselect */ + void implSelectRow( sal_Int32 nRow, bool bSelect ); + /** Selects/deselects a column (tries to expand selection). + @attention This method requires locked mutex's and a living object. + @param nColumnPos column number to select + @param bSelect TRUE = select, FALSE = deselect */ + void implSelectColumn( sal_Int32 nColumnPos, bool bSelect ); + + /** @attention This method requires locked mutex's and a living object. + @return The count of selected rows. */ + sal_Int32 implGetSelectedRowCount() const; + /** @attention This method requires locked mutex's and a living object. + @return The count of selected columns. */ + sal_Int32 implGetSelectedColumnCount() const; + + /** Fills a sequence with sorted indexes of completely selected rows. + @attention This method requires locked mutex's and a living object. + @param rSeq Out-parameter that takes the sorted row index list. */ + void implGetSelectedRows( css::uno::Sequence< sal_Int32 >& rSeq ); + /** Fills a sequence with sorted indexes of completely selected columns. + @attention This method requires locked mutex's and a living object. + @param rSeq Out-parameter that takes the sorted column index list. */ + void implGetSelectedColumns( css::uno::Sequence< sal_Int32 >& rSeq ); + + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified row index is invalid. */ + void ensureIsValidRow( sal_Int32 nRow ); + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified column index is invalid. */ + void ensureIsValidColumn( sal_Int32 nColumn ); + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified cell address is invalid. */ + void ensureIsValidAddress( sal_Int32 nRow, sal_Int32 nColumn ); + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified child index is invalid. */ + void ensureIsValidIndex( sal_Int64 nChildIndex ); +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleBrowseBoxTableCell.hxx b/accessibility/inc/extended/AccessibleBrowseBoxTableCell.hxx new file mode 100644 index 0000000000..166b7f3803 --- /dev/null +++ b/accessibility/inc/extended/AccessibleBrowseBoxTableCell.hxx @@ -0,0 +1,119 @@ +/* -*- 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 . + */ +#pragma once + +#include <extended/accessiblebrowseboxcell.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> + +namespace accessibility +{ + typedef ::cppu::ImplHelper2 < css::accessibility::XAccessibleText + , css::accessibility::XAccessible + > AccessibleTextHelper_BASE; + + // implementation of a table cell of BrowseBox + class AccessibleBrowseBoxTableCell final : public AccessibleBrowseBoxCell + ,public AccessibleTextHelper_BASE + ,public ::comphelper::OCommonAccessibleText + { + private: + sal_Int32 m_nOffset; + + // OCommonAccessibleText + virtual OUString implGetText() final override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + + public: + AccessibleBrowseBoxTableCell( const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowId, + sal_uInt16 _nColId, + sal_Int32 _nOffset ); + + // XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + + // XEventListener + using AccessibleBrowseBoxBase::disposing; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + /** @return + The name of this class. + */ + virtual OUString SAL_CALL getImplementationName() override; + + /** @return + The count of visible children. + */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return + The XAccessible interface of the specified child. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** Return a bitset of states of the current object. + */ + sal_Int64 implCreateStateSet() override; + + // XAccessible ------------------------------------------------------------ + + /** @return The XAccessibleContext interface of this object. */ + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext() override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() final override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControl.hxx b/accessibility/inc/extended/AccessibleGridControl.hxx new file mode 100644 index 0000000000..a1f7815ce1 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControl.hxx @@ -0,0 +1,223 @@ +/* -*- 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 . + */ + +#pragma once + +#include <extended/AccessibleGridControlBase.hxx> +#include <extended/AccessibleGridControlTable.hxx> +#include <cppuhelper/weakref.hxx> +#include <rtl/ref.hxx> +#include <vcl/accessibletable.hxx> + +namespace accessibility { + + class AccessibleGridControlHeader; + + +/** This class represents the complete accessible Grid Control object. */ +class AccessibleGridControl final : public AccessibleGridControlBase +{ + friend class AccessibleGridControlAccess; + + AccessibleGridControl( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator, + ::vcl::table::IAccessibleTable& _rTable + ); + + virtual ~AccessibleGridControl() override = default; + + /** Cleans up members. */ + using AccessibleGridControlBase::disposing; + virtual void SAL_CALL disposing() override; + + // XAccessibleContext ----------------------------------------------------- + + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The role of this object (a table). */ + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + // XAccessibleComponent --------------------------------------------------- + + /** @return + The accessible child rendered under the given point. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + /** Grabs the focus to the Grid Control. */ + virtual void SAL_CALL grabFocus() override; + + // XServiceInfo ----------------------------------------------------------- + + /** @return + The name of this class. + */ + virtual OUString SAL_CALL getImplementationName() override; + +public: + // helper functions + + /** commitCellEvent commit the event at all listeners of the table + @param nEventId + the event id + @param rNewValue + the new value + @param rOldValue + the old value + */ + void commitCellEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue); + + /** commitTableEvent commit the event at all listeners of the table + @param nEventId + the event id + @param rNewValue + the new value + @param rOldValue + the old value + */ + void commitTableEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue); + +private: + // internal virtual methods ----------------------------------------------- + + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() override; + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + // internal helper methods ------------------------------------------------ + + /** This method creates (once) and returns the accessible data table child. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the data table. */ + css::uno::Reference< css::accessibility::XAccessible > implGetTable(); + + /** This method creates (once) and returns the specified header bar. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the header bar. */ + css::uno::Reference< css::accessibility::XAccessible > + implGetHeaderBar( ::vcl::table::AccessibleTableControlObjType eObjType ); + + /** This method returns one of the children that are always present: + Data table, row and column header bar or corner control. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the specified child. */ + css::uno::Reference< css::accessibility::XAccessible > + implGetFixedChild( sal_Int64 nChildIndex ); + + /** This method creates and returns an accessible table. + @return An AccessibleGridControlTable. */ + rtl::Reference<AccessibleGridControlTable> createAccessibleTable(); + + /// the css::accessibility::XAccessible which created the AccessibleGridControl + css::uno::WeakReference< css::accessibility::XAccessible > m_aCreator; + + /** The data table child. */ + rtl::Reference<AccessibleGridControlTable> m_xTable; + + /** The header bar for rows. */ + rtl::Reference<AccessibleGridControlHeader> m_xRowHeaderBar; + + /** The header bar for columns (first row of the table). */ + rtl::Reference<AccessibleGridControlHeader> m_xColumnHeaderBar; + + /** @return The count of visible children. */ + inline sal_Int64 implGetAccessibleChildCount(); +}; + + +/** the XAccessible which creates/returns an AccessibleGridControl + + <p>The instance holds its XAccessibleContext with a hard reference, while + the context holds this instance weak.</p> +*/ + +class AccessibleGridControlAccess final : public ::vcl::table::IAccessibleTableControl +{ +private: + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + ::vcl::table::IAccessibleTable * m_pTable; + rtl::Reference<AccessibleGridControl> m_xContext; + +public: + AccessibleGridControlAccess( + css::uno::Reference< css::accessibility::XAccessible > _xParent, + ::vcl::table::IAccessibleTable& _rTable + ); + + /// returns the AccessibleContext belonging to this Accessible + AccessibleGridControl* getContext() { return m_xContext.get(); } + +private: + virtual ~AccessibleGridControlAccess() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + SAL_CALL getAccessibleContext() override; + + // IAccessibleTable + void DisposeAccessImpl() override; + virtual bool isAlive() const override + { + return m_xContext.is() && m_xContext->isAlive(); + } + virtual void commitCellEvent( sal_Int16 nEventId, + const css::uno::Any& rNewValue, const css::uno::Any& rOldValue ) override + { + AccessibleGridControl* pContext( getContext() ); + if ( pContext ) + pContext->commitCellEvent( nEventId, rNewValue, rOldValue ); + } + virtual void commitTableEvent( sal_Int16 nEventId, + const css::uno::Any& rNewValue, const css::uno::Any& rOldValue ) override + { + AccessibleGridControl* pContext( getContext() ); + if ( pContext ) + pContext->commitTableEvent( nEventId, rNewValue, rOldValue ); + } + virtual void commitEvent( sal_Int16 nEventId, + const css::uno::Any& rNewValue ) override + { + AccessibleGridControl* pContext( getContext() ); + if ( pContext ) + pContext->commitEvent( nEventId, rNewValue, css::uno::Any() ); + } + +private: + AccessibleGridControlAccess( const AccessibleGridControlAccess& ) = delete; + AccessibleGridControlAccess& operator=( const AccessibleGridControlAccess& ) = delete; +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControlBase.hxx b/accessibility/inc/extended/AccessibleGridControlBase.hxx new file mode 100644 index 0000000000..186edc8379 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControlBase.hxx @@ -0,0 +1,307 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <vcl/accessibletable.hxx> +#include <rtl/ustring.hxx> +#include <rtl/ref.hxx> +#include <tools/gen.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/uno3.hxx> + + +namespace vcl { class Window; } + + +namespace accessibility { + +typedef ::cppu::WeakComponentImplHelper< + css::accessibility::XAccessibleContext, + css::accessibility::XAccessibleComponent, + css::accessibility::XAccessibleEventBroadcaster, + css::lang::XServiceInfo > + AccessibleGridControlImplHelper; + +/** The GridControl accessible objects inherit from this base class. It + implements basic functionality for various Accessibility interfaces and + the event broadcaster and contains the osl::Mutex. */ +class AccessibleGridControlBase : + public ::cppu::BaseMutex, + public AccessibleGridControlImplHelper +{ +public: + /** Constructor. + @param rxParent XAccessible interface of the parent object. + @param rTable The Table control. + @param eObjType Type of accessible table control. */ + AccessibleGridControlBase( + css::uno::Reference< css::accessibility::XAccessible > xParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType ); + +protected: + virtual ~AccessibleGridControlBase() override; + + /** Commits DeFunc event to listeners and cleans up members. */ + virtual void SAL_CALL disposing() override; + +public: + // XAccessibleContext + + /** @return A reference to the parent accessible object. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleParent() override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + /** @return + The description of this object. + */ + virtual OUString SAL_CALL getAccessibleDescription() override; + + /** @return + The name of this object. + */ + virtual OUString SAL_CALL getAccessibleName() override; + + /** @return + The relation set (the GridControl does not have one). + */ + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL + getAccessibleRelationSet() override; + + /** @return The set of current states. */ + virtual sal_Int64 SAL_CALL getAccessibleStateSet() override; + + /** @return The parent's locale. */ + virtual css::lang::Locale SAL_CALL getLocale() override; + + /** @return + The role of this object. Panel, ROWHEADER, COLUMNHEADER, TABLE, TABLE_CELL are supported. + */ + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + /* Derived classes have to implement: + - getAccessibleChildCount, + - getAccessibleChild, + - getAccessibleRole. + Derived classes may overwrite getAccessibleIndexInParent to increase + performance. */ + + // XAccessibleComponent + + /** @return + TRUE, if the point lies within the bounding box of this object. */ + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& rPoint ) override; + + /** @return The bounding box of this object. */ + virtual css::awt::Rectangle SAL_CALL getBounds() override; + + /** @return + The upper left corner of the bounding box relative to the parent. */ + virtual css::awt::Point SAL_CALL getLocation() override; + + /** @return + The upper left corner of the bounding box in screen coordinates. */ + virtual css::awt::Point SAL_CALL getLocationOnScreen() override; + + /** @return The size of the bounding box. */ + virtual css::awt::Size SAL_CALL getSize() override; + + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + + /* Derived classes have to implement: + - getAccessibleAt, + - grabFocus. */ + + /** @return + The accessible child rendered under the given point. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + // XAccessibleEventBroadcaster + + /** Adds a new event listener */ + virtual void SAL_CALL addAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& rxListener ) override; + + /** Removes an event listener. */ + virtual void SAL_CALL removeAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& rxListener ) override; + + // XTypeProvider + + /** @return a unique implementation ID. */ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + + // XServiceInfo + + /** @return Whether the specified service is supported by this class. */ + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + + /** @return a list of all supported services. */ + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + + /* Derived classes have to implement: + - getImplementationName. */ + + // helper methods + + /** @return The GridControl object type. */ + inline ::vcl::table::AccessibleTableControlObjType getType() const; + + /** Commits an event to all listeners. */ + virtual void commitEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue); + /** @return TRUE, if the object is not disposed or disposing. */ + bool isAlive() const; + +protected: + // internal virtual methods + + /** Determines whether the Grid control is really showing inside of + its parent accessible window. Derived classes may implement different + behaviour. + @attention This method requires locked mutex's and a living object. + @return TRUE, if the object is really showing. */ + bool implIsShowing(); + + /** Derived classes return the bounding box relative to the parent window. + @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() = 0; + ///** Derived classes return the bounding box in screen coordinates. + // @attention This method requires locked mutex's and a living object. + // @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() = 0; + + /** Creates a bitset of states of the + current object. This method calls FillStateSet at the GridControl which + fills it with more states depending on the object type. Derived classes + may overwrite this method and add more states. + @attention This method requires locked mutex's. + */ + virtual sal_Int64 implCreateStateSet(); + + // internal helper methods + + /** @throws <type>DisposedException</type> If the object is not alive. */ + void ensureIsAlive() const; + + /** Locks all mutex's and calculates the bounding box relative to the + parent window. + @return The bounding box (VCL rect.) relative to the parent object. + @throws css::lang::DisposedException + */ + tools::Rectangle getBoundingBox(); + ///** Locks all mutex's and calculates the bounding box in screen + // coordinates. + // @return The bounding box (VCL rect.) in screen coordinates. */ + /// @throws css::lang::DisposedException + AbsoluteScreenPixelRectangle getBoundingBoxOnScreen(); + + ::comphelper::AccessibleEventNotifier::TClientId getClientId() const { return m_aClientId; } + void setClientId(::comphelper::AccessibleEventNotifier::TClientId _aNewClientId) { m_aClientId = _aNewClientId; } + +protected: + // members + + /** The parent accessible object. */ + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + /** The SVT Table control. */ + ::vcl::table::IAccessibleTable& m_aTable; + /** The type of this object (for names, descriptions, state sets, ...). */ + ::vcl::table::AccessibleTableControlObjType m_eObjType; + +private: + ::comphelper::AccessibleEventNotifier::TClientId m_aClientId; +}; + + +// a version of AccessibleGridControlBase which implements not only the XAccessibleContext, +// but also the XAccessible + +typedef ::cppu::ImplHelper1 < css::accessibility::XAccessible + > GridControlAccessibleElement_Base; + +class GridControlAccessibleElement + :public AccessibleGridControlBase + ,public GridControlAccessibleElement_Base +{ +protected: + /** Constructor sets specified name and description. + + @param rxParent XAccessible interface of the parent object. + @param rTable The Table control. + @param eObjType Type of table control + */ + GridControlAccessibleElement( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType ); + +public: + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + +protected: + virtual ~GridControlAccessibleElement() override; + +protected: + // XAccessible + + /** @return The XAccessibleContext interface of this object. */ + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext() override; + +private: + GridControlAccessibleElement( const GridControlAccessibleElement& ) = delete; + GridControlAccessibleElement& operator=( const GridControlAccessibleElement& ) = delete; +}; + +// inlines + +inline ::vcl::table::AccessibleTableControlObjType AccessibleGridControlBase::getType() const +{ + return m_eObjType; +} + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControlHeader.hxx b/accessibility/inc/extended/AccessibleGridControlHeader.hxx new file mode 100644 index 0000000000..7e1c3e7ab2 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControlHeader.hxx @@ -0,0 +1,155 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleGridControlTableBase.hxx> + +namespace accessibility { + +/** This class represents the accessible object of a header bar of a Grid Control + (row or column header bar). This object supports the + XAccessibleSelection interface. Selecting a child of this object selects + complete rows or columns of the data table. */ +class AccessibleGridControlHeader final : public AccessibleGridControlTableBase +{ +public: + /** @param rxParent accessible parent control + @param rTable accessible table + @param eObjType One of the two allowed types AccessibleTableControlObjType::ROWHEADERBAR or + AccessibleTableControlObjType::COLUMNHEADERBAR. */ + AccessibleGridControlHeader( + const css::uno::Reference< + css::accessibility::XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType ); + +private: + virtual ~AccessibleGridControlHeader() override = default; + +public: + // XAccessibleContext + + /** @return + The XAccessible interface of the specified child. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + // XAccessibleComponent + + /** @return The accessible child rendered under the given point. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + /** Grabs the focus to (the current cell of) the data table. */ + virtual void SAL_CALL grabFocus() override; + + // XAccessibleTable + + /** @return The description text of the specified row. */ + virtual OUString SAL_CALL + getAccessibleRowDescription( sal_Int32 nRow ) override; + + /** @return The description text of the specified column. */ + virtual OUString SAL_CALL + getAccessibleColumnDescription( sal_Int32 nColumn ) override; + + /** @return The XAccessibleTable interface of the row header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleRowHeaders() override; + + /** @return The XAccessibleTable interface of the column header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleColumnHeaders() override; + + /** @return An index list of completely selected rows. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleRows() override; + + /** @return An index list of completely selected columns. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleColumns() override; + + /** @return TRUE, if the specified row is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleRowSelected( sal_Int32 nRow ) override; + + /** @return TRUE, if the specified column is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleColumnSelected( sal_Int32 nColumn ) override; + + /** @return The XAccessible interface of the cell object at the specified + cell position. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return TRUE, if the specified cell is selected. */ + virtual sal_Bool SAL_CALL isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) override; + + // XServiceInfo + + /** @return The name of this class. */ + virtual OUString SAL_CALL getImplementationName() override; + + /** @return a unique implementation ID. */ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + +private: + /** Returns the specified row or column. Uses one of the parameters, + depending on object type. + @attention This method requires locked mutex's and a living object. + @return The XAccessible interface of the specified column/row. */ + css::uno::Reference< css::accessibility::XAccessible > + implGetChild( sal_Int32 nRow, sal_uInt32 nColumnPos ); + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() override; + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + // internal helper methods + + /** @return TRUE, if the objects is a header bar for rows. */ + inline bool isRowBar() const; + /** @return TRUE, if the objects is a header bar for columns. */ + inline bool isColumnBar() const; +}; + +// inlines + +inline bool AccessibleGridControlHeader::isRowBar() const +{ + return getType() == ::vcl::table::AccessibleTableControlObjType::ROWHEADERBAR; +} + +inline bool AccessibleGridControlHeader::isColumnBar() const +{ + return getType() == ::vcl::table::AccessibleTableControlObjType::COLUMNHEADERBAR; +} + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControlHeaderCell.hxx b/accessibility/inc/extended/AccessibleGridControlHeaderCell.hxx new file mode 100644 index 0000000000..6e78029a84 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControlHeaderCell.hxx @@ -0,0 +1,79 @@ +/* -*- 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 . + */ +#pragma once + +#include <extended/AccessibleGridControlTableCell.hxx> + +namespace accessibility +{ + class AccessibleGridControlHeaderCell final : public AccessibleGridControlCell, public css::accessibility::XAccessible + { + sal_Int32 m_nColumnRowId; + public: + AccessibleGridControlHeaderCell(sal_Int32 _nColumnRowId, + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& _rTable, + ::vcl::table::AccessibleTableControlObjType _eObjType); + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + /** Grabs the focus to the GridControl. */ + virtual void SAL_CALL grabFocus() override; + + // XInterface + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + // XAccessible + + /** @return The XAccessibleContext interface of this object. */ + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext() override; + + /** @return + The name of this class. + */ + virtual OUString SAL_CALL getImplementationName() override; + + /** Return a bitset of states of the current object. + */ + sal_Int64 implCreateStateSet() override; + + private: + virtual tools::Rectangle implGetBoundingBox() override; + + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + }; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControlTable.hxx b/accessibility/inc/extended/AccessibleGridControlTable.hxx new file mode 100644 index 0000000000..ef029ec4a7 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControlTable.hxx @@ -0,0 +1,172 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleGridControlTableBase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <extended/AccessibleGridControlTableCell.hxx> + + +namespace accessibility { + + +typedef ::cppu::ImplHelper1 < css::accessibility::XAccessibleSelection > + AccessibleGridControlTableSelectionImplHelper; +/** This class represents the accessible object of the data table of a + Grid control. */ +class AccessibleGridControlTable final : public AccessibleGridControlTableBase, + public AccessibleGridControlTableSelectionImplHelper +{ +public: + AccessibleGridControlTable( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& rTable); + +private: + virtual ~AccessibleGridControlTable() override = default; + std::vector< rtl::Reference<AccessibleGridControlTableCell> > m_aCellVector; +public: + // XAccessibleContext + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + // XAccessibleComponent + + /** @return The accessible child rendered under the given point. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint( const css::awt::Point& rPoint ) override; + + /** Grabs the focus to (the current cell of) the data table. */ + virtual void SAL_CALL grabFocus() override; + + // XAccessibleTable + + /** @return The description text of the specified row. */ + virtual OUString SAL_CALL getAccessibleRowDescription( sal_Int32 nRow ) override; + + /** @return The description text of the specified column. */ + virtual OUString SAL_CALL getAccessibleColumnDescription( sal_Int32 nColumn ) override; + + /** @return The XAccessibleTable interface of the row header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleRowHeaders() override; + + /** @return The XAccessibleTable interface of the column header bar. */ + virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL + getAccessibleColumnHeaders() override; + + /** @return An index list of completely selected rows. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleRows() override; + + /** @return An index list of completely selected columns. */ + virtual css::uno::Sequence< sal_Int32 > SAL_CALL + getSelectedAccessibleColumns() override; + + /** @return TRUE, if the specified row is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleRowSelected( sal_Int32 nRow ) override; + + /** @return TRUE, if the specified column is completely selected. */ + virtual sal_Bool SAL_CALL isAccessibleColumnSelected( sal_Int32 nColumn ) override; + + /** @return The XAccessible interface of the cell object at the specified + cell position. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return TRUE, if the specified cell is selected. */ + virtual sal_Bool SAL_CALL isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) override; + + // XAccessibleSelection + + /** Selects the specified child (row or column of the table). */ + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + + /** @return TRUE, if the specified child (row/column) is selected. */ + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + + /** Clears the complete selection. */ + virtual void SAL_CALL clearAccessibleSelection() override; + + /** Selects all children or first, if multiselection is not supported. */ + virtual void SAL_CALL selectAllAccessibleChildren() override; + + /** @return The number of selected rows/columns. */ + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount() override; + + /** @return The specified selected row/column. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + + /** Removes the specified row/column from the selection. */ + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + // XInterface + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + // XServiceInfo + + /** @return The name of this class. */ + virtual OUString SAL_CALL getImplementationName() override; + + // XComponent + virtual void SAL_CALL dispose() override; + + virtual void commitEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue) override; + +private: + // internal virtual methods + + /** @attention This method requires locked mutex's and a living object. + @return The bounding box (VCL rect.) relative to the parent window. */ + virtual tools::Rectangle implGetBoundingBox() override; + ///** @attention This method requires locked mutex's and a living object. + // @return The bounding box (VCL rect.) in screen coordinates. */ + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + + //// internal helper methods + ///** @attention This method requires a locked mutex. + // @return The XAccessibleTable interface of the specified header bar. */ + /// @throws css::uno::RuntimeException + css::uno::Reference< css::accessibility::XAccessibleTable > + implGetHeaderBar( sal_Int32 nChildIndex ); +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControlTableBase.hxx b/accessibility/inc/extended/AccessibleGridControlTableBase.hxx new file mode 100644 index 0000000000..39de903ec8 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControlTableBase.hxx @@ -0,0 +1,175 @@ +/* -*- 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 . + */ + + +#pragma once + +#include <extended/AccessibleGridControlBase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> + + +namespace accessibility { + +typedef ::cppu::ImplHelper1 < css::accessibility::XAccessibleTable > + AccessibleGridControlTableImplHelper; + +/** The Grid Control accessible table objects inherit from this base class. It + implements basic functionality for the XAccessibleTable interface. + Grid COntrol table objects are: the data table, the column header bar and the + row header bar. */ +class AccessibleGridControlTableBase : + public GridControlAccessibleElement, + public AccessibleGridControlTableImplHelper +{ +public: + /** Constructor sets specified name and description. + @param rxParent XAccessible interface of the parent object. + @param rTable The Table control. + @param eObjType Type of table control object */ + AccessibleGridControlTableBase( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType ); + +protected: + virtual ~AccessibleGridControlTableBase() override = default; + +public: + // XAccessibleContext + + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The role of this object (a table). */ + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + /* Derived classes have to implement: + - getAccessibleChild, + - getAccessibleIndexInParent. */ + + // XAccessibleComponent + + /* Derived classes have to implement: + - getAccessibleAt, + - grabFocus. */ + + // XAccessibleTable + + /** @return The number of used rows in the table (0 = empty table). */ + virtual sal_Int32 SAL_CALL getAccessibleRowCount() override; + + /** @return The number of used columns in the table (0 = empty table). */ + virtual sal_Int32 SAL_CALL getAccessibleColumnCount() override; + + /** @return The row extent of the specified cell (always 1). */ + virtual sal_Int32 SAL_CALL + getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return The column extent of the specified cell (always 1). */ + virtual sal_Int32 SAL_CALL + getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return The caption cell of the table (not supported). */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleCaption() override; + + /** @return The summary object of the table (not supported). */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleSummary() override; + + /** @return The child index of the specified cell. */ + virtual sal_Int64 SAL_CALL getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) override; + + /** @return The row index of the specified child cell. */ + virtual sal_Int32 SAL_CALL getAccessibleRow( sal_Int64 nChildIndex ) override; + + /** @return The column index of the specified child cell. */ + virtual sal_Int32 SAL_CALL getAccessibleColumn( sal_Int64 nChildIndex ) override; + + /* Derived classes have to implement: + - getAccessibleRowDescription, + - getAccessibleColumnDescription, + - getAccessibleRowHeaders, + - getAccessibleColumnHeaders, + - getSelectedAccessibleRows, + - getSelectedAccessibleColumns, + - isAccessibleRowSelected, + - isAccessibleColumnSelected, + - getAccessibleCellAt, + - isAccessibleSelected. */ + + // XInterface + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + + // XTypeProvider + + /** @return a sequence of possible types (received from base classes). */ + virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override; + + /** @return a unique implementation ID. */ + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + +protected: + // internal helper methods + + /** @attention This method requires locked mutex's and a living object. + @return The row index of the specified cell index. */ + sal_Int32 implGetRow( sal_Int64 nChildIndex ); + /** @attention This method requires locked mutex's and a living object. + @return The column index of the specified cell index. */ + sal_Int32 implGetColumn( sal_Int64 nChildIndex ); + + /** Fills a sequence with sorted indexes of completely selected rows. + @attention This method requires locked mutex's and a living object. + @param rSeq Out-parameter that takes the sorted row index list. */ + void implGetSelectedRows( css::uno::Sequence< sal_Int32 >& rSeq ); + + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified row index is invalid. */ + void ensureIsValidRow( sal_Int32 nRow ); + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified column index is invalid. */ + void ensureIsValidColumn( sal_Int32 nColumn ); + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified cell address is invalid. */ + void ensureIsValidAddress( sal_Int32 nRow, sal_Int32 nColumn ); + /** @attention This method requires locked mutex's and a living object. + @throws <type>IndexOutOfBoundsException</type> + If the specified child index is invalid. */ + void ensureIsValidIndex( sal_Int64 nChildIndex ); +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleGridControlTableCell.hxx b/accessibility/inc/extended/AccessibleGridControlTableCell.hxx new file mode 100644 index 0000000000..f9f8c4f7f1 --- /dev/null +++ b/accessibility/inc/extended/AccessibleGridControlTableCell.hxx @@ -0,0 +1,147 @@ +/* -*- 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 . + */ +#pragma once + +#include <comphelper/accessibletexthelper.hxx> +#include <cppuhelper/implbase2.hxx> +#include <extended/AccessibleGridControlBase.hxx> +#include <vcl/accessibletable.hxx> +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> + +namespace accessibility +{ + class AccessibleGridControlCell : public AccessibleGridControlBase + { + private: + sal_Int32 m_nRowPos; // the row number of the table cell + sal_Int32 m_nColPos; // the column id of the table cell + + protected: + // attribute access + sal_Int32 getRowPos( ) const { return m_nRowPos; } + sal_Int32 getColumnPos( ) const { return m_nColPos; } + + // XAccessibleComponent + virtual void SAL_CALL grabFocus() override; + + public: + // XAccessibleContext + virtual OUString SAL_CALL getAccessibleName() override; + + protected: + AccessibleGridControlCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + ::vcl::table::IAccessibleTable& _rTable, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + ::vcl::table::AccessibleTableControlObjType _eType + ); + + virtual ~AccessibleGridControlCell() override = default; + + private: + AccessibleGridControlCell( const AccessibleGridControlCell& ) = delete; + AccessibleGridControlCell& operator=( const AccessibleGridControlCell& ) = delete; + }; + + typedef ::cppu::ImplHelper2 < css::accessibility::XAccessibleText + , css::accessibility::XAccessible + > AccessibleTextHelper_BASE; + // implementation of a table cell of GridControl + class AccessibleGridControlTableCell final :public AccessibleGridControlCell + ,public AccessibleTextHelper_BASE + ,public ::comphelper::OCommonAccessibleText + { + private: + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override final; + virtual tools::Rectangle implGetBoundingBox() override; + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + public: + AccessibleGridControlTableCell( const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + ::vcl::table::IAccessibleTable& _rTable, + sal_Int32 _nRowId, + sal_uInt16 _nColId); + + // XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override; + + /** Acquires the object (calls acquire() on base class). */ + virtual void SAL_CALL acquire() noexcept override; + + /** Releases the object (calls release() on base class). */ + virtual void SAL_CALL release() noexcept override; + + /** @return The index of this object among the parent's children. */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + /** @return + The name of this class. + */ + virtual OUString SAL_CALL getImplementationName() override; + + /** @return + The count of visible children. + */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return + The XAccessible interface of the specified child. + */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + /** Return a bitset of states of the current object. + */ + sal_Int64 implCreateStateSet() override; + + // XAccessible ------------------------------------------------------------ + + /** @return The XAccessibleContext interface of this object. */ + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext() override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/AccessibleIconView.hxx b/accessibility/inc/extended/AccessibleIconView.hxx new file mode 100644 index 0000000000..d5ab5eafb1 --- /dev/null +++ b/accessibility/inc/extended/AccessibleIconView.hxx @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include <sal/config.h> + +#include "accessiblelistbox.hxx" + +namespace accessibility +{ +class AccessibleIconView final : public AccessibleListBox +{ +public: + AccessibleIconView(SvTreeListBox const& _rListBox, + const css::uno::Reference<css::accessibility::XAccessible>& _xParent); + +protected: + // VCLXAccessibleComponent + virtual void ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent) override; +}; +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/accessibility/inc/extended/accessiblebrowseboxcell.hxx b/accessibility/inc/extended/accessiblebrowseboxcell.hxx new file mode 100644 index 0000000000..4db205c1d7 --- /dev/null +++ b/accessibility/inc/extended/accessiblebrowseboxcell.hxx @@ -0,0 +1,74 @@ +/* -*- 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 . + */ + +#pragma once + +#include <extended/AccessibleBrowseBoxBase.hxx> +#include <vcl/AccessibleBrowseBoxObjType.hxx> + +namespace accessibility +{ + + + // = AccessibleBrowseBoxCell + + /** common accessibility-functionality for browse box elements which occupy a cell + */ + class AccessibleBrowseBoxCell : public AccessibleBrowseBoxBase + { + private: + sal_Int32 m_nRowPos; // the row number of the table cell + sal_uInt16 m_nColPos; // the column id of the table cell + + protected: + // attribute access + sal_Int32 getRowPos( ) const { return m_nRowPos; } + sal_Int32 getColumnPos( ) const { return m_nColPos; } + + protected: + // AccessibleBrowseBoxBase overridables + virtual tools::Rectangle implGetBoundingBox() override; + virtual AbsoluteScreenPixelRectangle implGetBoundingBoxOnScreen() override; + + // XAccessibleComponent + virtual void SAL_CALL grabFocus() override; + + protected: + AccessibleBrowseBoxCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + AccessibleBrowseBoxObjType _eType = AccessibleBrowseBoxObjType::TableCell + ); + + virtual ~AccessibleBrowseBoxCell() override; + + private: + AccessibleBrowseBoxCell( const AccessibleBrowseBoxCell& ) = delete; + AccessibleBrowseBoxCell& operator=( const AccessibleBrowseBoxCell& ) = delete; + }; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibleeditbrowseboxcell.hxx b/accessibility/inc/extended/accessibleeditbrowseboxcell.hxx new file mode 100644 index 0000000000..615266637b --- /dev/null +++ b/accessibility/inc/extended/accessibleeditbrowseboxcell.hxx @@ -0,0 +1,131 @@ +/* -*- 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 . + */ +#pragma once + +#include <extended/accessiblebrowseboxcell.hxx> +#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> +#include <comphelper/compbase.hxx> +#include <comphelper/accessiblewrapper.hxx> + +namespace accessibility +{ + + // = EditBrowseBoxTableCell + + class EditBrowseBoxTableCell final : public AccessibleBrowseBoxCell + ,public ::comphelper::OAccessibleContextWrapperHelper + { + public: + EditBrowseBoxTableCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + const css::uno::Reference< css::accessibility::XAccessible >& _rxOwningAccessible, + const css::uno::Reference< css::accessibility::XAccessibleContext >& _xControlChild, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos + ); + + private: + virtual ~EditBrowseBoxTableCell() override; + + // XAccessibleComponent + virtual sal_Int32 SAL_CALL getForeground( ) override ; + virtual sal_Int32 SAL_CALL getBackground( ) override ; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleContext + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + + sal_Int16 SAL_CALL getAccessibleRole() override; + + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // OComponentHelper + virtual void SAL_CALL disposing() override; + + // XComponent/OComponentProxyAggregationHelper (needs to be disambiguated) + virtual void SAL_CALL dispose() final override; + + // OAccessibleContextWrapperHelper(); + void notifyTranslatedEvent( const css::accessibility::AccessibleEventObject& _rEvent ) override; + + EditBrowseBoxTableCell( const EditBrowseBoxTableCell& ) = delete; + EditBrowseBoxTableCell& operator=( const EditBrowseBoxTableCell& ) = delete; + }; + + + // = EditBrowseBoxTableCell + + // XAccessible providing an EditBrowseBoxTableCell + class EditBrowseBoxTableCellAccess final : + public comphelper::WeakComponentImplHelper<css::accessibility::XAccessible> + { + css::uno::WeakReference< css::accessibility::XAccessibleContext > + m_aContext; + css::uno::Reference< css::accessibility::XAccessible > + m_xParent; + css::uno::Reference< css::accessibility::XAccessible > + m_xControlAccessible; + css::uno::Reference< css::awt::XWindow > + m_xFocusWindow; + ::vcl::IAccessibleTableProvider* m_pBrowseBox; + sal_Int32 m_nRowPos; + sal_uInt16 m_nColPos; + + public: + EditBrowseBoxTableCellAccess( + css::uno::Reference< css::accessibility::XAccessible > _xParent, + css::uno::Reference< css::accessibility::XAccessible > _xControlAccessible, + css::uno::Reference< css::awt::XWindow > _xFocusWindow, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos + ); + + private: + virtual ~EditBrowseBoxTableCellAccess() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XComponent/WeakComponentImplHelper + virtual void disposing(std::unique_lock<std::mutex>&) override; + + EditBrowseBoxTableCellAccess( const EditBrowseBoxTableCellAccess& ) = delete; + EditBrowseBoxTableCellAccess& operator=( const EditBrowseBoxTableCellAccess& ) = delete; + }; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibleiconchoicectrl.hxx b/accessibility/inc/extended/accessibleiconchoicectrl.hxx new file mode 100644 index 0000000000..5ead84ee34 --- /dev/null +++ b/accessibility/inc/extended/accessibleiconchoicectrl.hxx @@ -0,0 +1,94 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <cppuhelper/implbase.hxx> +#include <vcl/vclevent.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> + +// class AccessibleListBox ----------------------------------------------- + +class SvtIconChoiceCtrl; + +namespace accessibility +{ + /** the class OAccessibleListBoxEntry represents the base class for an accessible object of a listbox entry + */ + class AccessibleIconChoiceCtrl final : + public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessible, + css::accessibility::XAccessibleSelection> + { + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + + virtual ~AccessibleIconChoiceCtrl() override = default; + + /** this function is called upon disposing the component */ + virtual void SAL_CALL disposing() override; + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + VclPtr< SvtIconChoiceCtrl > getCtrl() const; + + public: + /** OAccessibleBase needs a valid view + @param _rIconCtrl + is the box for which we implement an accessible object + @param _xParent + is our parent accessible object + */ + AccessibleIconChoiceCtrl( SvtIconChoiceCtrl const & _rIconCtrl, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + + // XAccessibleSelection + void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + void SAL_CALL clearAccessibleSelection( ) override; + void SAL_CALL selectAllAccessibleChildren( ) override; + sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + }; + + +}// namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibleiconchoicectrlentry.hxx b/accessibility/inc/extended/accessibleiconchoicectrlentry.hxx new file mode 100644 index 0000000000..b2430481e5 --- /dev/null +++ b/accessibility/inc/extended/accessibleiconchoicectrlentry.hxx @@ -0,0 +1,178 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <tools/gen.hxx> +#include <vcl/vclptr.hxx> + +// forward + +class SvxIconChoiceCtrlEntry; +class SvtIconChoiceCtrl; + +namespace accessibility +{ + + + typedef ::cppu::WeakComponentImplHelper< css::accessibility::XAccessible + , css::accessibility::XAccessibleContext + , css::accessibility::XAccessibleComponent + , css::accessibility::XAccessibleEventBroadcaster + , css::accessibility::XAccessibleText + , css::accessibility::XAccessibleAction + , css::lang::XServiceInfo + , css::lang::XEventListener > AccessibleIconChoiceCtrlEntry_BASE; + + /** the class AccessibleListBoxEntry represents the class for an accessible object of a listbox entry */ + class AccessibleIconChoiceCtrlEntry final : public ::cppu::BaseMutex, + public AccessibleIconChoiceCtrlEntry_BASE, + public ::comphelper::OCommonAccessibleText + { + /** The treelistbox control */ + VclPtr<SvtIconChoiceCtrl> m_pIconCtrl; + sal_Int32 m_nIndex; + + /// client id in the AccessibleEventNotifier queue + sal_uInt32 m_nClientId; + + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + + tools::Rectangle GetBoundingBox_Impl() const; + AbsoluteScreenPixelRectangle GetBoundingBoxOnScreen_Impl() const; + bool IsAlive_Impl() const; + bool IsShowing_Impl() const; + + /// @throws css::lang::DisposedException + /// @throws css::uno::RuntimeException + tools::Rectangle GetBoundingBox(); + /// @throws css::lang::DisposedException + /// @throws css::uno::RuntimeException + AbsoluteScreenPixelRectangle GetBoundingBoxOnScreen(); + /// @throws css::lang::DisposedException + void EnsureIsAlive() const; + + virtual ~AccessibleIconChoiceCtrlEntry() override; + /** this function is called upon disposing the component + */ + virtual void SAL_CALL disposing() override; + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override final; + + public: + /** Ctor() + @param _rIconCtrl + the icon control + @param _nPos + the entry number + @param _xParent + is our parent accessible object + */ + AccessibleIconChoiceCtrlEntry( SvtIconChoiceCtrl& _rIconCtrl, + sal_Int32 _nPos, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent ); + + // XTypeProvider + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Rectangle SAL_CALL getBounds( ) override; + virtual css::awt::Point SAL_CALL getLocation( ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual css::awt::Size SAL_CALL getSize( ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + }; + + +}// namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessiblelistbox.hxx b/accessibility/inc/extended/accessiblelistbox.hxx new file mode 100644 index 0000000000..55112facac --- /dev/null +++ b/accessibility/inc/extended/accessiblelistbox.hxx @@ -0,0 +1,119 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <cppuhelper/implbase.hxx> +#include <vcl/vclevent.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> + +#include <unordered_map> + +// class AccessibleListBox ----------------------------------------------- + +class SvTreeListBox; +class SvTreeListEntry; + +namespace accessibility +{ + class AccessibleListBoxEntry; + + /** the class OAccessibleListBoxEntry represents the base class for an accessible object of a listbox entry + */ + class AccessibleListBox : + public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessible, + css::accessibility::XAccessibleSelection> + { + + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + // OComponentHelper overridables + /** this function is called upon disposing the component */ + virtual void SAL_CALL disposing() override; + + protected: + // VCLXAccessibleComponent + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + private: + VclPtr< SvTreeListBox > getListBox() const; + + void RemoveChildEntries(SvTreeListEntry*); + + sal_Int32 GetRoleType() const; + + public: + /** OAccessibleBase needs a valid view + @param _rListBox + is the box for which we implement an accessible object + @param _xParent + is our parent accessible object + */ + AccessibleListBox( SvTreeListBox const & _rListBox, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent ); + + virtual ~AccessibleListBox() override; + + rtl::Reference<AccessibleListBoxEntry> implGetAccessible(SvTreeListEntry & rEntry); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + + // XAccessibleSelection + void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + void SAL_CALL clearAccessibleSelection( ) override; + void SAL_CALL selectAllAccessibleChildren( ) override; + sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + + private: + + typedef std::unordered_map<SvTreeListEntry*, rtl::Reference<AccessibleListBoxEntry>> MAP_ENTRY; + MAP_ENTRY m_mapEntry; + + rtl::Reference<AccessibleListBoxEntry> m_xFocusedEntry; + + accessibility::AccessibleListBoxEntry* GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ); + + }; + + +}// namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessiblelistboxentry.hxx b/accessibility/inc/extended/accessiblelistboxentry.hxx new file mode 100644 index 0000000000..050dc948d9 --- /dev/null +++ b/accessibility/inc/extended/accessiblelistboxentry.hxx @@ -0,0 +1,224 @@ +/* -*- 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 . + */ + +#pragma once + +#include <deque> +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <vcl/toolkit/treelistentry.hxx> +#include <tools/gen.hxx> +#include <unotools/weakref.hxx> + +// forward --------------------------------------------------------------- + +namespace com::sun::star::awt { + struct Point; + struct Rectangle; + struct Size; + class XFocusListener; +} + +class SvTreeListBox; +class SvTreeListEntry; + + +namespace accessibility +{ + class AccessibleListBox; + +// class AccessibleListBoxEntry ------------------------------------------ + typedef ::cppu::WeakComponentImplHelper< css::accessibility::XAccessible + , css::accessibility::XAccessibleContext + , css::accessibility::XAccessibleComponent + , css::accessibility::XAccessibleEventBroadcaster + , css::accessibility::XAccessibleAction + , css::accessibility::XAccessibleSelection + , css::accessibility::XAccessibleText + , css::accessibility::XAccessibleValue + , css::lang::XServiceInfo > AccessibleListBoxEntry_BASE; + + /** the class AccessibleListBoxEntry represents the class for an accessible object of a listbox entry */ + class AccessibleListBoxEntry final : public ::cppu::BaseMutex + ,public AccessibleListBoxEntry_BASE + ,public ::comphelper::OCommonAccessibleText + { + friend class AccessibleListBox; + + private: + VclPtr<SvTreeListBox> m_pTreeListBox; + /** The treelistbox control */ + std::deque< sal_Int32 > m_aEntryPath; + SvTreeListEntry* m_pSvLBoxEntry; // Needed for a11y focused item... + + + /// client id in the AccessibleEventNotifier queue + sal_uInt32 m_nClientId; + + unotools::WeakReference<AccessibleListBox> m_wListBox; + + tools::Rectangle GetBoundingBox_Impl() const; + tools::Rectangle GetBoundingBoxOnScreen_Impl() const; + bool IsAlive_Impl() const; + bool IsShowing_Impl() const; + + /// @throws css::lang::DisposedException + /// @throws css::uno::RuntimeException + tools::Rectangle GetBoundingBox(); + /// @throws css::lang::DisposedException + /// @throws css::uno::RuntimeException + tools::Rectangle GetBoundingBoxOnScreen(); + /// @throws css::lang::IndexOutOfBoundsException + void CheckActionIndex(sal_Int32 nIndex); + /// @throws css::lang::DisposedException + void EnsureIsAlive() const; + + void NotifyAccessibleEvent( sal_Int16 _nEventId, const css::uno::Any& _aOldValue, const css::uno::Any& _aNewValue ); + + virtual ~AccessibleListBoxEntry() override; + + /** this function is called upon disposing the component + */ + virtual void SAL_CALL disposing() override; + + DECL_LINK( WindowEventListener, VclWindowEvent&, void ); + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + + public: + /** Ctor() + @param _rListBox + the view control + @param rEntry + the entry + @param rListBox + the a11y object for _rListBox + */ + AccessibleListBoxEntry( SvTreeListBox& _rListBox, + SvTreeListEntry& rEntry, + AccessibleListBox & rListBox); + + SvTreeListEntry* GetSvLBoxEntry() const { return m_pSvLBoxEntry; } + + + private: + // XTypeProvider + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Rectangle SAL_CALL getBounds( ) override; + virtual css::awt::Point SAL_CALL getLocation( ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual css::awt::Size SAL_CALL getSize( ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleSelection + void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + void SAL_CALL clearAccessibleSelection( ) override; + void SAL_CALL selectAllAccessibleChildren( ) override; + sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; + + css::uno::Reference< css::accessibility::XAccessible > implGetParentAccessible( ) const; + SvTreeListEntry* GetRealChild(sal_Int32 nIndex); + sal_Int32 GetRoleType() const; + }; + + +}// namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibletabbar.hxx b/accessibility/inc/extended/accessibletabbar.hxx new file mode 100644 index 0000000000..b921fdb167 --- /dev/null +++ b/accessibility/inc/extended/accessibletabbar.hxx @@ -0,0 +1,94 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase.hxx> +#include <extended/accessibletabbarbase.hxx> + +#include <vector> + + +namespace accessibility +{ + + + + + class AccessibleTabBar final : public cppu::ImplInheritanceHelper< + AccessibleTabBarBase, + css::accessibility::XAccessible, + css::lang::XServiceInfo> + { + typedef std::vector< css::uno::Reference< css::accessibility::XAccessible > > AccessibleChildren; + + AccessibleChildren m_aAccessibleChildren; + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + void FillAccessibleStateSet( sal_Int64& rStateSet ); + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + + public: + AccessibleTabBar( TabBar* pTabBar ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + }; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibletabbarbase.hxx b/accessibility/inc/extended/accessibletabbarbase.hxx new file mode 100644 index 0000000000..d08f20e3e3 --- /dev/null +++ b/accessibility/inc/extended/accessibletabbarbase.hxx @@ -0,0 +1,61 @@ +/* -*- 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 . + */ + +#pragma once + +#include <comphelper/accessiblecomponenthelper.hxx> +#include <tools/link.hxx> +#include <vcl/vclptr.hxx> + +class TabBar; +class VclSimpleEvent; +class VclWindowEvent; + + +namespace accessibility +{ + +class AccessibleTabBarBase : public comphelper::OAccessibleExtendedComponentHelper +{ +public: + explicit AccessibleTabBarBase( TabBar* pTabBar ); + virtual ~AccessibleTabBarBase() override; + +protected: + DECL_LINK( WindowEventListener, VclWindowEvent&, void ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); + + // XComponent + virtual void SAL_CALL disposing() override; + +private: + void SetTabBarPointer( TabBar* pTabBar ); + void ClearTabBarPointer(); + +protected: + VclPtr<TabBar> m_pTabBar; +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibletabbarpage.hxx b/accessibility/inc/extended/accessibletabbarpage.hxx new file mode 100644 index 0000000000..052650c19d --- /dev/null +++ b/accessibility/inc/extended/accessibletabbarpage.hxx @@ -0,0 +1,106 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase.hxx> +#include <extended/accessibletabbarbase.hxx> + + +namespace accessibility +{ + + + + + class AccessibleTabBarPage final : public cppu::ImplInheritanceHelper< + AccessibleTabBarBase, + css::accessibility::XAccessible, + css::lang::XServiceInfo> + { + friend class AccessibleTabBarPageList; + + private: + sal_uInt16 m_nPageId; + bool m_bShowing; + bool m_bSelected; + OUString m_sPageText; + + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + + bool IsEnabled(); + bool IsShowing() const; + bool IsSelected() const; + + void SetShowing( bool bShowing ); + void SetSelected( bool bSelected ); + void SetPageText( const OUString& sPageText ); + + void FillAccessibleStateSet( sal_Int64& rStateSet ); + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + + public: + AccessibleTabBarPage( TabBar* pTabBar, sal_uInt16 nPageId, + const css::uno::Reference< css::accessibility::XAccessible >& rxParent ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + }; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibletabbarpagelist.hxx b/accessibility/inc/extended/accessibletabbarpagelist.hxx new file mode 100644 index 0000000000..b3045aa77c --- /dev/null +++ b/accessibility/inc/extended/accessibletabbarpagelist.hxx @@ -0,0 +1,114 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase.hxx> +#include <extended/accessibletabbarbase.hxx> +#include <extended/accessibletabbarpage.hxx> + +#include <vector> + +namespace accessibility +{ + class AccessibleTabBarPageList final : public cppu::ImplInheritanceHelper< + AccessibleTabBarBase, + css::accessibility::XAccessible, + css::accessibility::XAccessibleSelection, + css::lang::XServiceInfo> + { + private: + typedef std::vector< rtl::Reference< AccessibleTabBarPage > > AccessibleChildren; + + AccessibleChildren m_aAccessibleChildren; + sal_Int32 m_nIndexInParent; + + void UpdateShowing( bool bShowing ); + void UpdateSelected( sal_Int32 i, bool bSelected ); + void UpdatePageText( sal_Int32 i ); + + void InsertChild( sal_Int32 i ); + void RemoveChild( sal_Int32 i ); + void MoveChild( sal_Int32 i, sal_Int32 j ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + void FillAccessibleStateSet( sal_Int64& rStateSet ); + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + + public: + AccessibleTabBarPageList( TabBar* pTabBar, sal_Int32 nIndexInParent ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nChildIndex ) override; + + private: + rtl::Reference< AccessibleTabBarPage > getAccessibleChildImpl( sal_Int64 i ); + }; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibletablistbox.hxx b/accessibility/inc/extended/accessibletablistbox.hxx new file mode 100644 index 0000000000..b38c1c5ef5 --- /dev/null +++ b/accessibility/inc/extended/accessibletablistbox.hxx @@ -0,0 +1,102 @@ +/* -*- 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 . + */ + +#pragma once + +#include <extended/AccessibleBrowseBox.hxx> +#include <cppuhelper/implbase1.hxx> +#include <vcl/accessibletableprovider.hxx> + +class SvHeaderTabListBox; + + +namespace accessibility { + +class AccessibleBrowseBoxTable; + +typedef ::cppu::ImplHelper1 < css::accessibility::XAccessible + > AccessibleTabListBox_Base; + +/** !!! */ +class AccessibleTabListBox final + :public AccessibleBrowseBox + ,public AccessibleTabListBox_Base + ,public ::vcl::IAccessibleTabListBox +{ +private: + VclPtr<SvHeaderTabListBox> m_pTabListBox; + +public: + /** ctor() + @param rxParent XAccessible interface of the parent object. + @param rBox The HeaderTabListBox control. */ + AccessibleTabListBox( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + SvHeaderTabListBox& rBox ); + + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleContext ----------------------------------------------------- + + /** @return The count of visible children. */ + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + /** @return The XAccessible interface of the specified child. */ + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int64 nChildIndex ) override; + + // XAccessibleContext + css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override; + + // IAccessibleTabListBox + virtual css::uno::Reference< css::accessibility::XAccessible > + getMyself() override + { + return this; + } + + css::uno::Reference< css::accessibility::XAccessible > + getHeaderBar() override + { + return AccessibleBrowseBox::getHeaderBar( AccessibleBrowseBoxObjType::ColumnHeaderBar ); + } + + css::uno::Reference<css::accessibility::XAccessible> getTable() override + { + return implGetTable(); + } + +private: + /** dtor() */ + virtual ~AccessibleTabListBox() override; + + /** This method creates and returns an accessible table. + @return An AccessibleBrowseBoxTable. */ + virtual rtl::Reference<AccessibleBrowseBoxTable> createAccessibleTable() override; +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/accessibletablistboxtable.hxx b/accessibility/inc/extended/accessibletablistboxtable.hxx new file mode 100644 index 0000000000..b2f2b4277a --- /dev/null +++ b/accessibility/inc/extended/accessibletablistboxtable.hxx @@ -0,0 +1,108 @@ +/* -*- 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 . + */ + +#pragma once + +#include <extended/AccessibleBrowseBoxTable.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> + +class SvHeaderTabListBox; + + +namespace accessibility { + +typedef ::cppu::ImplHelper1< css::accessibility::XAccessibleSelection > + AccessibleTabListBoxTableImplHelper; + +class AccessibleTabListBoxTable final : public AccessibleBrowseBoxTable, public AccessibleTabListBoxTableImplHelper +{ +private: + VclPtr<SvHeaderTabListBox> m_pTabListBox; + + css::uno::Reference< css::accessibility::XAccessible > m_xCurChild; + + void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); + DECL_LINK( WindowEventListener, VclWindowEvent&, void ); + + // helpers ---------------------------------------------------------------- + + /** Throws an exception, if nIndex is not a valid child index. */ + void ensureValidIndex( sal_Int64 _nIndex ) const; + + /** Selects the specified row. */ + void implSelectRow( sal_Int32 _nRow, bool _bSelect ); + + /** Returns the count of rows in the table. */ + sal_Int32 implGetRowCount() const override; + /** Returns the total column count in the table. */ + sal_Int32 implGetColumnCount() const override; + /** Returns the count of selected rows in the table. */ + sal_Int32 implGetSelRowCount() const; + + /** Returns the row index from cell index. */ + sal_Int32 implGetRow( sal_Int64 _nIndex ) const + { + auto nColCount = implGetColumnCount(); + assert(nColCount != 0); + return _nIndex / nColCount; + } + + /** Returns the absolute row index of the nSelRow-th selected row. */ + sal_Int32 implGetSelRow( sal_Int32 _nSelRow ) const; + +public: + /** ctor() + @param rxParent XAccessible interface of the parent object. + @param rBox The HeaderTabListBox control. */ + AccessibleTabListBoxTable( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + SvHeaderTabListBox& rBox ); + +private: + /** dtor() */ + virtual ~AccessibleTabListBoxTable() override; + +public: + // XInterface + DECLARE_XINTERFACE( ) + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + + // XAccessibleSelection + void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + void SAL_CALL clearAccessibleSelection( ) override; + void SAL_CALL selectAllAccessibleChildren( ) override; + sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; +}; + + +} // namespace accessibility + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/extended/textwindowaccessibility.hxx b/accessibility/inc/extended/textwindowaccessibility.hxx new file mode 100644 index 0000000000..52d5f21757 --- /dev/null +++ b/accessibility/inc/extended/textwindowaccessibility.hxx @@ -0,0 +1,599 @@ +/* -*- 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 . + */ + +#pragma once + +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <svl/lstner.hxx> +#include <vcl/textdata.hxx> +#include <vcl/texteng.hxx> +#include <vcl/textview.hxx> +#include <vcl/window.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> +#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp> +#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <toolkit/awt/vclxwindow.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <rtl/ref.hxx> +#include <unotools/weakref.hxx> + +#include <unotools/accessiblerelationsethelper.hxx> +#include <queue> +#include <memory> +#include <unordered_map> + +class TextEngine; +class TextView; + +namespace accessibility +{ + +class Document; + +class SfxListenerGuard +{ +public: + SfxListenerGuard(::SfxListener & rListener): + m_rListener(rListener), m_pNotifier(nullptr) {} + + ~SfxListenerGuard() { endListening(); } + + // Not thread safe: + void startListening(::SfxBroadcaster & rNotifier); + + // Not thread safe: + void endListening(); + +private: + ::SfxListener & m_rListener; + ::SfxBroadcaster * m_pNotifier; +}; + +class WindowListenerGuard +{ +public: + WindowListenerGuard(::Link<VclWindowEvent&,void> const & rListener): + m_aListener(rListener), m_pNotifier(nullptr) {} + + ~WindowListenerGuard() { endListening(); } + + // Not thread safe: + void startListening(vcl::Window & rNotifier); + + // Not thread safe: + void endListening(); + +private: + ::Link<VclWindowEvent&,void> m_aListener; + VclPtr<vcl::Window> m_pNotifier; +}; + +class Paragraph; + +class ParagraphInfo +{ +public: + ParagraphInfo(::sal_Int32 nHeight): m_nHeight(nHeight) {} + + unotools::WeakReference< Paragraph > const & + getParagraph() const { return m_xParagraph; } + + ::sal_Int32 getHeight() const { return m_nHeight; } + + void setParagraph( rtl::Reference< Paragraph > const & rParagraph) + { m_xParagraph = rParagraph.get(); } + + void changeHeight(::sal_Int32 nHeight) { m_nHeight = nHeight; } + +private: + unotools::WeakReference< Paragraph > m_xParagraph; + ::sal_Int32 m_nHeight; +}; + +typedef std::vector< ParagraphInfo > Paragraphs; + +typedef ::cppu::WeakComponentImplHelper< + css::accessibility::XAccessible, + css::accessibility::XAccessibleContext, + css::accessibility::XAccessibleComponent, + css::accessibility::XAccessibleEditableText, + css::accessibility::XAccessibleMultiLineText, + css::accessibility::XAccessibleTextAttributes, + css::accessibility::XAccessibleEventBroadcaster > ParagraphBase; + +// The Paragraph's number is the absolute position within the text engine (from +// 0 to N - 1), whereas the Paragraph's index is the position within the text +// view/accessible parent (from 0 to M - 1). Paragraphs outside the currently +// visible range have an index of -1. +class Paragraph final: + private cppu::BaseMutex, public ParagraphBase, private ::comphelper::OCommonAccessibleText +{ +public: + Paragraph(::rtl::Reference< Document > xDocument, + Paragraphs::size_type nNumber); + + // Not thread-safe. + Paragraphs::size_type getNumber() const { return m_nNumber; } + + // Not thread-safe. + void numberChanged(bool bIncremented); + + // Not thread-safe. + void textChanged(); + + // Thread-safe. + void notifyEvent(::sal_Int16 nEventId, css::uno::Any const & rOldValue, + css::uno::Any const & rNewValue); + +private: + // OCommonAccessibleText + virtual void implGetParagraphBoundary( const OUString& rText, + css::i18n::Boundary& rBoundary, + ::sal_Int32 nIndex ) override; + virtual void implGetLineBoundary( const OUString& rText, + css::i18n::Boundary& rBoundary, + ::sal_Int32 nIndex ) override; + + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + SAL_CALL getAccessibleContext() override; + + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleChild(sal_Int64 i) override; + + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleParent() override; + + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + + virtual ::sal_Int16 SAL_CALL getAccessibleRole() override; + + virtual OUString SAL_CALL getAccessibleDescription() override; + + virtual OUString SAL_CALL getAccessibleName() override; + + virtual + css::uno::Reference< css::accessibility::XAccessibleRelationSet > + SAL_CALL getAccessibleRelationSet() override; + + virtual sal_Int64 SAL_CALL getAccessibleStateSet() override; + + virtual css::lang::Locale SAL_CALL getLocale() override; + + virtual sal_Bool SAL_CALL containsPoint(css::awt::Point const & rPoint) override; + + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleAtPoint(css::awt::Point const & rPoint) override; + + virtual css::awt::Rectangle SAL_CALL getBounds() override; + + virtual css::awt::Point SAL_CALL getLocation() override; + + virtual css::awt::Point SAL_CALL getLocationOnScreen() override; + + virtual css::awt::Size SAL_CALL getSize() override; + + virtual void SAL_CALL grabFocus() override; + + virtual sal_Int32 SAL_CALL getForeground() override; + + virtual sal_Int32 SAL_CALL getBackground() override; + + virtual ::sal_Int32 SAL_CALL getCaretPosition() override; + + virtual sal_Bool SAL_CALL setCaretPosition(::sal_Int32 nIndex) override; + + virtual ::sal_Unicode SAL_CALL getCharacter(::sal_Int32 nIndex) override; + + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL + getCharacterAttributes(::sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + + virtual css::awt::Rectangle SAL_CALL + getCharacterBounds(::sal_Int32 nIndex) override; + + virtual ::sal_Int32 SAL_CALL getCharacterCount() override; + + virtual ::sal_Int32 SAL_CALL + getIndexAtPoint(css::awt::Point const & rPoint) override; + + virtual OUString SAL_CALL getSelectedText() override; + + virtual ::sal_Int32 SAL_CALL getSelectionStart() override; + + virtual ::sal_Int32 SAL_CALL getSelectionEnd() override; + + virtual sal_Bool SAL_CALL setSelection(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) override; + + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + virtual OUString SAL_CALL getText() override; + + virtual OUString SAL_CALL getTextRange(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) override; + + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + + virtual sal_Bool SAL_CALL copyText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) override; + + virtual sal_Bool SAL_CALL cutText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) override; + + virtual sal_Bool SAL_CALL pasteText(::sal_Int32 nIndex) override; + + virtual sal_Bool SAL_CALL deleteText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) override; + + virtual sal_Bool SAL_CALL insertText(OUString const & rText, + ::sal_Int32 nIndex) override; + + virtual sal_Bool SAL_CALL replaceText( + ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, + OUString const & rReplacement) override; + + virtual sal_Bool SAL_CALL setAttributes( + ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, + css::uno::Sequence< css::beans::PropertyValue > const & + rAttributeSet) override; + + virtual sal_Bool SAL_CALL setText(OUString const & rText) override; + + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL + getDefaultAttributes(const css::uno::Sequence< OUString >& RequestedAttributes) override; + + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL + getRunAttributes(::sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes) override; + + virtual ::sal_Int32 SAL_CALL getLineNumberAtIndex( ::sal_Int32 nIndex ) override; + + virtual css::accessibility::TextSegment SAL_CALL getTextAtLineNumber( ::sal_Int32 nLineNo ) override; + + virtual css::accessibility::TextSegment SAL_CALL getTextAtLineWithCaret( ) override; + + virtual ::sal_Int32 SAL_CALL getNumberOfLineWithCaret( ) override; + + virtual void SAL_CALL addAccessibleEventListener( + css::uno::Reference< + css::accessibility::XAccessibleEventListener > const & rListener) override; + + virtual void SAL_CALL removeAccessibleEventListener( + css::uno::Reference< + css::accessibility::XAccessibleEventListener > const & rListener) override; + + virtual void SAL_CALL disposing() override; + + virtual OUString implGetText() override; + + virtual css::lang::Locale implGetLocale() override; + + virtual void implGetSelection(::sal_Int32 & rStartIndex, + ::sal_Int32 & rEndIndex) override; + + // Throws css::lang::DisposedException: + void checkDisposed(); + + ::rtl::Reference< Document > m_xDocument; + Paragraphs::size_type m_nNumber; + + /// client id in the AccessibleEventNotifier queue + sal_uInt32 m_nClientId; + + OUString m_aParagraphText; +}; + + +typedef std::unordered_map< OUString, + css::beans::PropertyValue > tPropValMap; + +class Document final : public ::VCLXAccessibleComponent, public ::SfxListener +{ +public: + Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine, + ::TextView & rView); + + const css::uno::Reference< css::accessibility::XAccessible >& + getAccessible() const { return m_xAccessible; } + + // Must be called only after init has been called. + css::lang::Locale retrieveLocale(); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const *" instead of a + // "::rtl::Reference< Paragraph > const &". + ::sal_Int32 retrieveParagraphIndex(Paragraph const * pParagraph); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const *" instead of a + // "::rtl::Reference< Paragraph > const &". + ::sal_Int64 retrieveParagraphState(Paragraph const * pParagraph); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + css::awt::Rectangle + retrieveParagraphBounds(Paragraph const * pParagraph, bool bAbsolute); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + OUString retrieveParagraphText(Paragraph const * pParagraph); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + void retrieveParagraphSelection(Paragraph const * pParagraph, + ::sal_Int32 * pBegin, ::sal_Int32 * pEnd); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const *" instead of a + // "::rtl::Reference< Paragraph > const &". + ::sal_Int32 retrieveParagraphCaretPosition(Paragraph const * pParagraph); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + css::awt::Rectangle + retrieveCharacterBounds(Paragraph const * pParagraph, + ::sal_Int32 nIndex); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + ::sal_Int32 retrieveCharacterIndex(Paragraph const * pParagraph, + css::awt::Point const & rPoint); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + css::uno::Sequence< css::beans::PropertyValue > retrieveCharacterAttributes( + Paragraph const * pParagraph, ::sal_Int32 nIndex, + const css::uno::Sequence< OUString >& aRequestedAttributes); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + css::uno::Sequence< css::beans::PropertyValue > retrieveRunAttributes( + Paragraph const * pParagraph, ::sal_Int32 Index, + const css::uno::Sequence< OUString >& RequestedAttributes); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + void changeParagraphText(Paragraph const * pParagraph, + OUString const & rText); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + void changeParagraphText(Paragraph const * pParagraph, ::sal_Int32 nBegin, + ::sal_Int32 nEnd, bool bCut, bool bPaste, + OUString const & rText); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + void copyParagraphText(Paragraph const * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + void changeParagraphAttributes( + Paragraph const * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd, + css::uno::Sequence< css::beans::PropertyValue > const & + rAttributeSet); + + // Must be called only after init has been called. + // To make it possible for this method to be (indirectly) called from + // within Paragraph's constructor (i.e., when the Paragraph's ref count is + // still zero), pass a "Paragraph const &" instead of a + // "::rtl::Reference< Paragraph > const &". + // Throws css::lang::IndexOutOfBoundsException. + void changeParagraphSelection(Paragraph const * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd); + + css::i18n::Boundary + retrieveParagraphLineBoundary( Paragraph const * pParagraph, + ::sal_Int32 nIndex, ::sal_Int32 *pLineNo); + + css::i18n::Boundary + retrieveParagraphBoundaryOfLine( Paragraph const * pParagraph, + ::sal_Int32 nIndex ); + + sal_Int32 retrieveParagraphLineWithCursor( Paragraph const * pParagraph ); + + css::uno::Reference< css::accessibility::XAccessibleRelationSet > + retrieveParagraphRelationSet( Paragraph const * pParagraph ); + +private: + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + SAL_CALL getAccessibleChild(sal_Int64 i) override; + + virtual ::sal_Int16 SAL_CALL getAccessibleRole() override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + SAL_CALL getAccessibleAtPoint(css::awt::Point const & rPoint) override; + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) override; + + // ??? Will be called with both the external (Solar) and internal mutex + // locked: + virtual void SAL_CALL disposing() override; + + // ??? Will be called with the external (Solar) mutex locked. + // init will already have been called. + virtual void Notify(::SfxBroadcaster & rBC, ::SfxHint const & rHint) override; + + // Assuming that this will only be called with the external (Solar) mutex + // locked. + // init will already have been called. + DECL_LINK(WindowEventHandler, VclWindowEvent&, void); + + // Must be called with both the external (Solar) and internal mutex + // locked. + void init(); + + // Must be called with both the external (Solar) and internal mutex + // locked, and after init has been called: + static ::rtl::Reference< Paragraph > + getParagraph(Paragraphs::iterator const & rIt); + + // Must be called with both the external (Solar) and internal mutex + // locked, and after init has been called. + // Throws css::uno::RuntimeException. + css::uno::Reference< css::accessibility::XAccessible > + getAccessibleChild(Paragraphs::iterator const & rIt); + + // Must be called with both the external (Solar) and internal mutex + // locked, and after init has been called: + void determineVisibleRange(); + + // Must be called with both the external (Solar) and internal mutex + // locked, and after init has been called: + void notifyVisibleRangeChanges( + Paragraphs::iterator const & rOldVisibleBegin, + Paragraphs::iterator const & rOldVisibleEnd, + Paragraphs::iterator const & rInserted); + + // Must be called with both the external (Solar) and internal mutex + // locked, and after init has been called: + void changeParagraphText(::sal_uInt32 nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd, + bool bCut, bool bPaste, + OUString const & rText); + + void + handleParagraphNotifications(); + + void handleSelectionChangeNotification(); + + void sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId); + + void disposeParagraphs(); + + static css::uno::Any mapFontColor(::Color const & rColor); + + static ::Color mapFontColor(css::uno::Any const & rColor); + + static css::uno::Any mapFontWeight(::FontWeight nWeight); + + static ::FontWeight mapFontWeight(css::uno::Any const & rWeight); + + void retrieveRunAttributesImpl( + Paragraph const * pParagraph, ::sal_Int32 Index, + const css::uno::Sequence< OUString >& RequestedAttributes, + tPropValMap& rRunAttrSeq); + + css::uno::Reference< css::accessibility::XAccessible > m_xAccessible; + ::TextEngine & m_rEngine; + ::TextView & m_rView; + + SfxListenerGuard m_aEngineListener; + WindowListenerGuard m_aViewListener; + + // All the following members have valid values only after calling init: + + std::unique_ptr< Paragraphs > m_xParagraphs; + + // m_nViewOffset is from the start of the document (0) to the start of the + // current view, and m_nViewHeight is the height of the view: + ::sal_Int32 m_nViewOffset; + ::sal_Int32 m_nViewHeight; + + // m_aVisibleBegin points to the first Paragraph that is (partially) + // contained in the view, and m_aVisibleEnd points past the last Paragraph + // that is (partially) contained. If no Paragraphs are (partially) in the + // view, both m_aVisibleBegin and m_aVisibleEnd are set to + // m_xParagraphs->end(). These values are only changed by + // determineVisibleRange. + Paragraphs::iterator m_aVisibleBegin; + Paragraphs::iterator m_aVisibleEnd; + + // m_nVisibleBeginOffset is from m_nViewOffset back to the start of the + // Paragraph pointed to by m_aVisibleBegin (and always has a non-negative + // value). If m_aVisibleBegin == m_xParagraphs->end(), + // m_nVisibleBeginOffset is set to 0. These values are only changed by + // determineVisibleRange. + ::sal_Int32 m_nVisibleBeginOffset; + + // If no selection has yet been set, all the following four variables are + // set to -1. m_nSelectionLastPara/Pos is also the cursor position. + ::sal_Int32 m_nSelectionFirstPara; + ::sal_Int32 m_nSelectionFirstPos; + ::sal_Int32 m_nSelectionLastPara; + ::sal_Int32 m_nSelectionLastPos; + + Paragraphs::iterator m_aFocused; + + std::queue< ::TextHint > m_aParagraphNotifications; + bool m_bSelectionChangedNotification; +}; + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/helper/IComboListBoxHelper.hxx b/accessibility/inc/helper/IComboListBoxHelper.hxx new file mode 100644 index 0000000000..43d30aadab --- /dev/null +++ b/accessibility/inc/helper/IComboListBoxHelper.hxx @@ -0,0 +1,69 @@ +/* -*- 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 . + */ +#pragma once + +#include <com/sun/star/uno/Reference.hxx> + +#include <rtl/ustring.hxx> +#include <vcl/wintypes.hxx> +#include <tools/long.hxx> + +namespace com::sun::star::datatransfer::clipboard { + class XClipboard; +} + +class AbsoluteScreenPixelRectangle; +class Point; +namespace tools { class Rectangle; } +namespace vcl { class Window; } +namespace accessibility +{ + class IComboListBoxHelper + { + public: + virtual ~IComboListBoxHelper() = 0; + + virtual OUString GetEntry( sal_Int32 nPos ) const = 0; + virtual tools::Rectangle GetDropDownPosSizePixel( ) const = 0; + virtual tools::Rectangle GetBoundingRectangle( sal_uInt16 nItem ) const = 0; + virtual AbsoluteScreenPixelRectangle GetWindowExtentsAbsolute() = 0; + virtual bool IsEnabled() const = 0; + virtual bool IsEntryVisible( sal_Int32 nPos ) const = 0; + virtual sal_uInt16 GetDisplayLineCount() const = 0; + virtual void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const = 0; + virtual WinBits GetStyle() const = 0; + virtual bool IsMultiSelectionEnabled() const = 0; + virtual sal_Int32 GetTopEntry() const = 0; + virtual bool IsEntryPosSelected( sal_Int32 nPos ) const = 0; + virtual sal_Int32 GetEntryCount() const = 0; + virtual void Select() = 0; + virtual void SelectEntryPos( sal_Int32 nPos, bool bSelect = true ) = 0; + virtual sal_Int32 GetSelectedEntryCount() const = 0; + virtual void SetNoSelection() = 0; + virtual sal_Int32 GetSelectedEntryPos( sal_Int32 nSelIndex ) const = 0; + virtual bool IsInDropDown() const = 0; + virtual tools::Rectangle GetEntryCharacterBounds( const sal_Int32 _nEntryPos, const sal_Int32 _nCharacterIndex ) const = 0; + virtual tools::Long GetIndexForPoint( const Point& rPoint, sal_Int32 & nPos ) const = 0; + virtual css::uno::Reference< css::datatransfer::clipboard::XClipboard > + GetClipboard() = 0; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + diff --git a/accessibility/inc/helper/accresmgr.hxx b/accessibility/inc/helper/accresmgr.hxx new file mode 100644 index 0000000000..75ccc2df63 --- /dev/null +++ b/accessibility/inc/helper/accresmgr.hxx @@ -0,0 +1,27 @@ +/* -*- 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 . + */ + +#pragma once + +#include <rtl/ustring.hxx> +#include <unotools/resmgr.hxx> + +OUString AccResId(TranslateId aId); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/helper/characterattributeshelper.hxx b/accessibility/inc/helper/characterattributeshelper.hxx new file mode 100644 index 0000000000..a73ee76c09 --- /dev/null +++ b/accessibility/inc/helper/characterattributeshelper.hxx @@ -0,0 +1,44 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <vcl/font.hxx> + +#include <map> +#include <vector> + +class CharacterAttributesHelper +{ +private: + typedef std::map<OUString, css::uno::Any> AttributeMap; + + AttributeMap m_aAttributeMap; + +public: + CharacterAttributesHelper(const vcl::Font& rFont, sal_Int32 nBackColor, sal_Int32 nColor); + + std::vector<css::beans::PropertyValue> GetCharacterAttributes(); + css::uno::Sequence<css::beans::PropertyValue> + GetCharacterAttributes(const css::uno::Sequence<OUString>& aRequestedAttributes); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/helper/listboxhelper.hxx b/accessibility/inc/helper/listboxhelper.hxx new file mode 100644 index 0000000000..4f1c5dde1e --- /dev/null +++ b/accessibility/inc/helper/listboxhelper.hxx @@ -0,0 +1,186 @@ +/* -*- 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 . + */ + +#pragma once + +#include <helper/IComboListBoxHelper.hxx> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <tools/gen.hxx> + + +// globals + + +const sal_Int32 DEFAULT_INDEX_IN_PARENT = -1; + + + + +template< class T > class VCLListBoxHelper final : public ::accessibility::IComboListBoxHelper +{ +private: + T& m_aComboListBox; + +public: + VCLListBoxHelper( T& _pListBox ) : + m_aComboListBox( _pListBox ){} + + + virtual OUString GetEntry( sal_Int32 nPos ) const override + { + return m_aComboListBox.GetEntry( nPos ); + } + + virtual tools::Rectangle GetDropDownPosSizePixel() const override + { + AbsoluteScreenPixelRectangle aTemp = m_aComboListBox.GetWindowExtentsAbsolute(); + tools::Rectangle aRet = m_aComboListBox.GetDropDownPosSizePixel(); + aRet.Move(aTemp.Left(), aTemp.Top()); + return aRet; + } + + virtual tools::Rectangle GetBoundingRectangle( sal_uInt16 nItem ) const override + { + tools::Rectangle aRect; + if ( m_aComboListBox.IsInDropDown() && IsEntryVisible( nItem ) ) + { + tools::Rectangle aTemp = m_aComboListBox.GetDropDownPosSizePixel(); + Size aSize = aTemp.GetSize(); + sal_uInt16 nLineCount = m_aComboListBox.GetDisplayLineCount(); + assert(nLineCount && "div-by-zero"); + aSize.setHeight( aSize.Height() / nLineCount ); + Point aTopLeft = aTemp.TopLeft(); + aTopLeft.AdjustY( aSize.Height() * ( nItem - m_aComboListBox.GetTopEntry() ) ); + aRect = tools::Rectangle( aTopLeft, aSize ); + } + else + aRect = m_aComboListBox.GetBoundingRectangle( nItem ); + return aRect; + } + + virtual AbsoluteScreenPixelRectangle GetWindowExtentsAbsolute() override + { + return m_aComboListBox.GetWindowExtentsAbsolute(); + } + + virtual bool IsEnabled() const override + { + return m_aComboListBox.IsEnabled(); + } + + virtual bool IsEntryVisible( sal_Int32 nPos ) const override + { + sal_Int32 nTopEntry = m_aComboListBox.GetTopEntry(); + sal_uInt16 nLines = m_aComboListBox.GetDisplayLineCount(); + return ( nPos >= nTopEntry && nPos < ( nTopEntry + nLines ) ); + } + + virtual sal_uInt16 GetDisplayLineCount() const override + { + return m_aComboListBox.GetDisplayLineCount(); + } + + virtual void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const override + { + m_aComboListBox.GetMaxVisColumnsAndLines(rnCols,rnLines); + } + + virtual WinBits GetStyle() const override + { + return m_aComboListBox.GetStyle(); + } + + virtual bool IsMultiSelectionEnabled() const override + { + return m_aComboListBox.IsMultiSelectionEnabled(); + } + + virtual sal_Int32 GetTopEntry() const override + { + return m_aComboListBox.GetTopEntry(); + } + + virtual bool IsEntryPosSelected( sal_Int32 nPos ) const override + { + return m_aComboListBox.IsEntryPosSelected(nPos); + } + + virtual sal_Int32 GetEntryCount() const override + { + return m_aComboListBox.GetEntryCount(); + } + + virtual void Select() override + { + m_aComboListBox.Select(); + } + + virtual void SelectEntryPos( sal_Int32 nPos, bool bSelect = true ) override + { + m_aComboListBox.SelectEntryPos(nPos,bSelect); + } + + virtual sal_Int32 GetSelectedEntryCount() const override + { + return m_aComboListBox.GetSelectedEntryCount(); + } + + virtual void SetNoSelection() override + { + m_aComboListBox.SetNoSelection(); + } + + virtual sal_Int32 GetSelectedEntryPos( sal_Int32 nSelIndex = 0 ) const override + { + return m_aComboListBox.GetSelectedEntryPos(nSelIndex); + } + + virtual bool IsInDropDown() const override + { + return m_aComboListBox.IsInDropDown(); + } + + virtual tools::Rectangle GetEntryCharacterBounds( const sal_Int32 _nEntryPos, const sal_Int32 _nCharacterIndex ) const override + { + tools::Rectangle aRect; + + Pair aEntryCharacterRange = m_aComboListBox.GetLineStartEnd( _nEntryPos ); + if ( aEntryCharacterRange.A() + _nCharacterIndex <= aEntryCharacterRange.B() ) + { + tools::Long nIndex = aEntryCharacterRange.A() + _nCharacterIndex; + aRect = m_aComboListBox.GetCharacterBounds( nIndex ); + } + return aRect; + } + + tools::Long GetIndexForPoint( const Point& rPoint, sal_Int32& nPos ) const override + { + return m_aComboListBox.GetIndexForPoint( rPoint, nPos ); + } + + css::uno::Reference< css::datatransfer::clipboard::XClipboard > + GetClipboard() override + { + return m_aComboListBox.GetClipboard(); + } + +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/pch/precompiled_acc.cxx b/accessibility/inc/pch/precompiled_acc.cxx new file mode 100644 index 0000000000..fc8ac40106 --- /dev/null +++ b/accessibility/inc/pch/precompiled_acc.cxx @@ -0,0 +1,12 @@ +/* -*- 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/. + */ + +#include "precompiled_acc.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/pch/precompiled_acc.hxx b/accessibility/inc/pch/precompiled_acc.hxx new file mode 100644 index 0000000000..c9589365ab --- /dev/null +++ b/accessibility/inc/pch/precompiled_acc.hxx @@ -0,0 +1,348 @@ +/* -*- 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 has been autogenerated by update_pch.sh. It is possible to edit it + manually (such as when an include file has been moved/renamed/removed). All such + manual changes will be rewritten by the next run of update_pch.sh (which presumably + also fixes all possible problems, so it's usually better to use it). + + Generated on 2023-07-19 09:19:19 using: + ./bin/update_pch accessibility acc --cutoff=4 --exclude:system --include:module --include:local + + If after updating build fails, use the following command to locate conflicting headers: + ./bin/update_pch_bisect ./accessibility/inc/pch/precompiled_acc.hxx "make accessibility.build" --find-conflicts +*/ + +#include <sal/config.h> +#if PCH_LEVEL >= 1 +#include <algorithm> +#include <array> +#include <cassert> +#include <cmath> +#include <cstddef> +#include <cstdlib> +#include <cstring> +#include <deque> +#include <float.h> +#include <functional> +#include <initializer_list> +#include <iomanip> +#include <limits.h> +#include <limits> +#include <map> +#include <math.h> +#include <memory> +#include <mutex> +#include <new> +#include <numeric> +#include <optional> +#include <ostream> +#include <span> +#include <stddef.h> +#include <string.h> +#include <string> +#include <string_view> +#include <type_traits> +#include <utility> +#include <vector> +#endif // PCH_LEVEL >= 1 +#if PCH_LEVEL >= 2 +#include <osl/diagnose.h> +#include <osl/doublecheckedlocking.h> +#include <osl/endian.h> +#include <osl/getglobalmutex.hxx> +#include <osl/interlck.h> +#include <osl/mutex.h> +#include <osl/mutex.hxx> +#include <rtl/alloc.h> +#include <rtl/instance.hxx> +#include <rtl/math.h> +#include <rtl/ref.hxx> +#include <rtl/strbuf.h> +#include <rtl/strbuf.hxx> +#include <rtl/string.h> +#include <rtl/string.hxx> +#include <rtl/stringconcat.hxx> +#include <rtl/stringutils.hxx> +#include <rtl/textcvt.h> +#include <rtl/textenc.h> +#include <rtl/ustrbuf.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> +#include <rtl/uuid.h> +#include <sal/backtrace.hxx> +#include <sal/detail/log.h> +#include <sal/log.hxx> +#include <sal/macros.h> +#include <sal/saldllapi.h> +#include <sal/types.h> +#include <sal/typesizes.h> +#include <vcl/AccessibleBrowseBoxObjType.hxx> +#include <vcl/EnumContext.hxx> +#include <vcl/NotebookbarContextControl.hxx> +#include <vcl/Scanline.hxx> +#include <vcl/WindowPosSize.hxx> +#include <vcl/accessibletable.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <vcl/alpha.hxx> +#include <vcl/bitmap.hxx> +#include <vcl/bitmap/BitmapTypes.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/cairo.hxx> +#include <vcl/checksum.hxx> +#include <vcl/ctrl.hxx> +#include <vcl/dllapi.h> +#include <vcl/dndhelp.hxx> +#include <vcl/dockwin.hxx> +#include <vcl/event.hxx> +#include <vcl/fntstyle.hxx> +#include <vcl/font.hxx> +#include <vcl/gradient.hxx> +#include <vcl/idle.hxx> +#include <vcl/image.hxx> +#include <vcl/kernarray.hxx> +#include <vcl/keycod.hxx> +#include <vcl/keycodes.hxx> +#include <vcl/mapmod.hxx> +#include <vcl/menu.hxx> +#include <vcl/metaactiontypes.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/outdev.hxx> +#include <vcl/quickselectionengine.hxx> +#include <vcl/region.hxx> +#include <vcl/rendercontext/AddFontSubstituteFlags.hxx> +#include <vcl/rendercontext/AntialiasingFlags.hxx> +#include <vcl/rendercontext/DrawGridFlags.hxx> +#include <vcl/rendercontext/DrawImageFlags.hxx> +#include <vcl/rendercontext/DrawModeFlags.hxx> +#include <vcl/rendercontext/DrawTextFlags.hxx> +#include <vcl/rendercontext/GetDefaultFontFlags.hxx> +#include <vcl/rendercontext/ImplMapRes.hxx> +#include <vcl/rendercontext/InvertFlags.hxx> +#include <vcl/rendercontext/RasterOp.hxx> +#include <vcl/rendercontext/SalLayoutFlags.hxx> +#include <vcl/rendercontext/State.hxx> +#include <vcl/rendercontext/SystemTextColorFlags.hxx> +#include <vcl/salgtype.hxx> +#include <vcl/salnativewidgets.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <vcl/syswin.hxx> +#include <vcl/task.hxx> +#include <vcl/textfilter.hxx> +#include <vcl/timer.hxx> +#include <vcl/toolboxid.hxx> +#include <vcl/toolkit/lstbox.hxx> +#include <vcl/toolkit/treelist.hxx> +#include <vcl/toolkit/treelistbox.hxx> +#include <vcl/toolkit/treelistentries.hxx> +#include <vcl/transfer.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/vclenum.hxx> +#include <vcl/vclevent.hxx> +#include <vcl/vclptr.hxx> +#include <vcl/vclreferencebase.hxx> +#include <vcl/virdev.hxx> +#include <vcl/wall.hxx> +#include <vcl/window.hxx> +#include <vcl/windowstate.hxx> +#include <vcl/wintypes.hxx> +#endif // PCH_LEVEL >= 2 +#if PCH_LEVEL >= 3 +#include <basegfx/basegfxdllapi.h> +#include <basegfx/color/bcolor.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/hommatrixtemplate.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/point/b2ipoint.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/range/Range2D.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/basicrange.hxx> +#include <basegfx/tuple/Size2D.hxx> +#include <basegfx/tuple/Tuple2D.hxx> +#include <basegfx/tuple/Tuple3D.hxx> +#include <basegfx/tuple/b2dtuple.hxx> +#include <basegfx/tuple/b2ituple.hxx> +#include <basegfx/tuple/b3dtuple.hxx> +#include <basegfx/utils/common.hxx> +#include <basegfx/vector/b2dsize.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <basegfx/vector/b2enums.hxx> +#include <basegfx/vector/b2isize.hxx> +#include <basegfx/vector/b2ivector.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/TextSegment.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleContext2.hpp> +#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <com/sun/star/awt/DeviceInfo.hpp> +#include <com/sun/star/awt/GradientStyle.hpp> +#include <com/sun/star/awt/Key.hpp> +#include <com/sun/star/awt/KeyGroup.hpp> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/XDockableWindow.hpp> +#include <com/sun/star/awt/XFocusListener.hpp> +#include <com/sun/star/awt/XLayoutConstrains.hpp> +#include <com/sun/star/awt/XStyleSettingsSupplier.hpp> +#include <com/sun/star/awt/XUnitConversion.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/awt/XView.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/datatransfer/DataFlavor.hpp> +#include <com/sun/star/datatransfer/XTransferable2.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDragEvent.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDropEvent.hpp> +#include <com/sun/star/datatransfer/dnd/XDragGestureListener.hpp> +#include <com/sun/star/datatransfer/dnd/XDragSourceListener.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp> +#include <com/sun/star/drawing/LineCap.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/EventObject.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Type.h> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/uno/TypeClass.hdl> +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/uno/XWeak.hpp> +#include <com/sun/star/uno/genfunc.h> +#include <com/sun/star/uno/genfunc.hxx> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/accessiblekeybindinghelper.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <comphelper/comphelperdllapi.h> +#include <comphelper/errcode.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/uno3.hxx> +#include <cppu/cppudllapi.h> +#include <cppu/unotype.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/compbase_ex.hxx> +#include <cppuhelper/cppuhelperdllapi.h> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase_ex.hxx> +#include <cppuhelper/implbase_ex_post.hxx> +#include <cppuhelper/implbase_ex_pre.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/weakagg.hxx> +#include <cppuhelper/weakref.hxx> +#include <extended/AccessibleBrowseBoxBase.hxx> +#include <extended/AccessibleBrowseBoxTableBase.hxx> +#include <extended/AccessibleGridControlBase.hxx> +#include <extended/AccessibleGridControlTableBase.hxx> +#include <extended/AccessibleGridControlTableCell.hxx> +#include <extended/accessiblebrowseboxcell.hxx> +#include <helper/accresmgr.hxx> +#include <helper/characterattributeshelper.hxx> +#include <i18nlangtag/lang.h> +#include <i18nlangtag/languagetag.hxx> +#include <o3tl/cow_wrapper.hxx> +#include <o3tl/deleter.hxx> +#include <o3tl/safeint.hxx> +#include <o3tl/strong_int.hxx> +#include <o3tl/typed_flags_set.hxx> +#include <o3tl/underlyingenumvalue.hxx> +#include <o3tl/unit_conversion.hxx> +#include <salhelper/salhelperdllapi.h> +#include <salhelper/simplereferenceobject.hxx> +#include <sot/exchange.hxx> +#include <sot/formats.hxx> +#include <sot/sotdllapi.h> +#include <standard/accessiblemenubasecomponent.hxx> +#include <standard/accessiblemenuitemcomponent.hxx> +#include <standard/vclxaccessiblebox.hxx> +#include <standard/vclxaccessibletextcomponent.hxx> +#include <svl/SfxBroadcaster.hxx> +#include <svl/hint.hxx> +#include <svl/svldllapi.h> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <toolkit/awt/vclxdevice.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <toolkit/dllapi.h> +#include <toolkit/helper/convert.hxx> +#include <tools/color.hxx> +#include <tools/contnr.hxx> +#include <tools/degree.hxx> +#include <tools/fontenum.hxx> +#include <tools/gen.hxx> +#include <tools/globname.hxx> +#include <tools/lineend.hxx> +#include <tools/link.hxx> +#include <tools/long.hxx> +#include <tools/mapunit.hxx> +#include <tools/poly.hxx> +#include <tools/ref.hxx> +#include <tools/solar.h> +#include <tools/toolsdllapi.h> +#include <typelib/typeclass.h> +#include <typelib/typedescription.h> +#include <typelib/uik.h> +#include <uno/any2.h> +#include <uno/data.h> +#include <uno/sequence2.h> +#include <unotools/accessiblerelationsethelper.hxx> +#include <unotools/fontdefs.hxx> +#include <unotools/unotoolsdllapi.h> +#endif // PCH_LEVEL >= 3 +#if PCH_LEVEL >= 4 +#include <strings.hxx> +#endif // PCH_LEVEL >= 4 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/accessiblemenubasecomponent.hxx b/accessibility/inc/standard/accessiblemenubasecomponent.hxx new file mode 100644 index 0000000000..337ee0a80d --- /dev/null +++ b/accessibility/inc/standard/accessiblemenubasecomponent.hxx @@ -0,0 +1,126 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/Point.hpp> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <cppuhelper/implbase.hxx> +#include <tools/link.hxx> +#include <vcl/vclptr.hxx> + +#include <vector> + +class Menu; +class VclSimpleEvent; +class VclMenuEvent; + +class OAccessibleMenuItemComponent; + +class OAccessibleMenuBaseComponent : public cppu::ImplInheritanceHelper< + comphelper::OAccessibleExtendedComponentHelper, + css::accessibility::XAccessible, + css::lang::XServiceInfo> +{ + friend class OAccessibleMenuItemComponent; + friend class VCLXAccessibleMenuItem; + friend class VCLXAccessibleMenu; + +protected: + typedef std::vector< rtl::Reference< OAccessibleMenuItemComponent > > AccessibleChildren; + + AccessibleChildren m_aAccessibleChildren1; + VclPtr<Menu> m_pMenu; + + bool m_bEnabled; + bool m_bFocused; + bool m_bVisible; + bool m_bSelected; + bool m_bChecked; + + virtual bool IsEnabled(); + virtual bool IsFocused(); + virtual bool IsVisible(); + virtual bool IsSelected(); + virtual bool IsChecked(); + + void SetEnabled( bool bEnabled ); + void SetFocused( bool bFocused ); + void SetVisible( bool bVisible ); + void SetSelected( bool bSelected ); + void SetChecked( bool bChecked ); + + void UpdateEnabled( sal_Int32 i, bool bEnabled ); + void UpdateFocused( sal_Int32 i, bool bFocused ); + void UpdateVisible(); + void UpdateSelected( sal_Int32 i, bool bSelected ); + void UpdateChecked( sal_Int32 i, bool bChecked ); + void UpdateAccessibleName( sal_Int32 i ); + void UpdateItemRole(sal_Int32 i); + void UpdateItemText( sal_Int32 i ); + + sal_Int64 GetChildCount() const; + + css::uno::Reference< css::accessibility::XAccessible > GetChild( sal_Int64 i ); + css::uno::Reference< css::accessibility::XAccessible > GetChildAt( const css::awt::Point& rPoint ); + + void InsertChild( sal_Int32 i ); + void RemoveChild( sal_Int32 i ); + + virtual bool IsHighlighted(); + bool IsChildHighlighted(); + + virtual bool IsMenuHideDisabledEntries(); + + void SelectChild( sal_Int32 i ); + void DeSelectAll(); + bool IsChildSelected( sal_Int32 i ); + + virtual void Click(); + virtual bool IsPopupMenuOpen(); + + DECL_LINK( MenuEventListener, VclMenuEvent&, void ); + + void ProcessMenuEvent( const VclMenuEvent& rVclMenuEvent ); + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) = 0; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + OAccessibleMenuBaseComponent( Menu* pMenu ); + virtual ~OAccessibleMenuBaseComponent() override; + + void SetStates(); + + // XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/accessiblemenucomponent.hxx b/accessibility/inc/standard/accessiblemenucomponent.hxx new file mode 100644 index 0000000000..90c8992265 --- /dev/null +++ b/accessibility/inc/standard/accessiblemenucomponent.hxx @@ -0,0 +1,78 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/accessiblemenubasecomponent.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <cppuhelper/implbase.hxx> + + + +class OAccessibleMenuComponent : public cppu::ImplInheritanceHelper< + OAccessibleMenuBaseComponent, + css::accessibility::XAccessibleSelection> +{ +protected: + virtual bool IsEnabled() override; + virtual bool IsVisible() override; + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + +public: + + OAccessibleMenuComponent( Menu* pMenu ): ImplInheritanceHelper(pMenu) {} + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nChildIndex ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/accessiblemenuitemcomponent.hxx b/accessibility/inc/standard/accessiblemenuitemcomponent.hxx new file mode 100644 index 0000000000..b6adebbde8 --- /dev/null +++ b/accessibility/inc/standard/accessiblemenuitemcomponent.hxx @@ -0,0 +1,87 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/accessiblemenubasecomponent.hxx> + + + + +class OAccessibleMenuItemComponent : public OAccessibleMenuBaseComponent +{ + friend class OAccessibleMenuBaseComponent; + +protected: + VclPtr<Menu> m_pParent; + sal_uInt16 m_nItemPos; + OUString m_sAccessibleName; + OUString m_sItemText; + + virtual bool IsEnabled() override; + virtual bool IsVisible() override; + void Select(); + void DeSelect(); + virtual void Click() override; + + void SetItemPos( sal_uInt16 nItemPos ); + void SetAccessibleName( const OUString& sAccessibleName ); + OUString GetAccessibleName(); + void SetItemText( const OUString& sItemText ); + OUString GetItemText(); + + virtual bool IsMenuHideDisabledEntries() override; + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + OAccessibleMenuItemComponent( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu ); + virtual ~OAccessibleMenuItemComponent() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/svtaccessiblenumericfield.hxx b/accessibility/inc/standard/svtaccessiblenumericfield.hxx new file mode 100644 index 0000000000..29225a5c60 --- /dev/null +++ b/accessibility/inc/standard/svtaccessiblenumericfield.hxx @@ -0,0 +1,48 @@ +/* -*- 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 . + */ + +#pragma once + +#include <cppuhelper/implbase.hxx> +#include <vcl/vclevent.hxx> + +#include <standard/vclxaccessibleedit.hxx> + +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +class SVTXAccessibleNumericField final + : public cppu::ImplInheritanceHelper<VCLXAccessibleEdit, css::accessibility::XAccessibleValue> +{ +public: + SVTXAccessibleNumericField(VCLXWindow* pVCLXindow); + + virtual void ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent) override; + + // XAccessibleContext + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + // XAccessibleValue + virtual ::css::uno::Any SAL_CALL getCurrentValue() override; + virtual ::sal_Bool SAL_CALL setCurrentValue(const css::uno::Any& aNumber) override; + virtual ::css::uno::Any SAL_CALL getMaximumValue() override; + virtual ::css::uno::Any SAL_CALL getMinimumValue() override; + virtual ::css::uno::Any SAL_CALL getMinimumIncrement() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblebox.hxx b/accessibility/inc/standard/vclxaccessiblebox.hxx new file mode 100644 index 0000000000..3825be0d4f --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblebox.hxx @@ -0,0 +1,151 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <cppuhelper/implbase.hxx> + +class VCLXAccessibleList; + +/** Base class for list- and combo boxes. This class manages the box' + children. The classed derived from this one have only to implement the + IsValid method and return the correct implementation name. +*/ +class VCLXAccessibleBox + : public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessible, + css::accessibility::XAccessibleValue, + css::accessibility::XAccessibleAction> +{ +public: + enum BoxType {COMBOBOX, LISTBOX}; + + /** The constructor is initialized with the box type which may be + either COMBOBOX or LISTBOX and a flag + indicating whether the box is a drop down box. + */ + VCLXAccessibleBox (VCLXWindow* pVCLXindow, BoxType aType, bool bIsDropDownBox); + + + // XAccessible + + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext( ) override; + + // XAccessibleContext + + /** Each object has one or two children: an optional text field and the + actual list. The text field is not provided for non drop down list + boxes. + */ + sal_Int64 SAL_CALL getAccessibleChildCount() final override; + /** For drop down list boxes the text field is a not editable + VCLXAccessibleTextField, for combo boxes it is an + editable VCLXAccessibleEdit. + */ + css::uno::Reference< css::accessibility::XAccessible> SAL_CALL + getAccessibleChild (sal_Int64 i) override; + /** The role is always AccessibleRole::COMBO_BOX. + */ + sal_Int16 SAL_CALL getAccessibleRole() override; + + // XAccessibleAction + + /** There is one action for drop down boxes and none for others. + */ + virtual sal_Int32 SAL_CALL getAccessibleActionCount() final override; + /** The action for drop down boxes lets the user toggle the visibility of the + popup menu. + */ + virtual sal_Bool SAL_CALL doAccessibleAction (sal_Int32 nIndex) override; + /** The returned string is associated with resource + RID_STR_ACC_ACTION_TOGGLEPOPUP. + */ + virtual OUString SAL_CALL getAccessibleActionDescription (sal_Int32 nIndex) override; + /** No keybinding returned so far. + */ + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL + getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + + virtual sal_Bool SAL_CALL setCurrentValue( + const css::uno::Any& aNumber ) override; + + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; + +protected: + virtual ~VCLXAccessibleBox() override; + + /** Returns true when the object is valid. + */ + virtual bool IsValid() const = 0; + + virtual void ProcessWindowChildEvent (const VclWindowEvent& rVclWindowEvent) override; + virtual void ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) override; + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + sal_Int64 implGetAccessibleChildCount(); + +private: + /** Specifies whether the box is a combo box or a list box. List boxes + have multi selection. + */ + BoxType m_aBoxType; + + /// Specifies whether the box is a drop down box and thus has an action. + bool m_bIsDropDownBox; + + /// The child that represents the text field if there is one. + css::uno::Reference< css::accessibility::XAccessible> + m_xText; + + /// The child that contains the items of this box. + rtl::Reference<VCLXAccessibleList> m_xList; + + /** This flag specifies whether an object has a text field as child + regardless of whether that child being currently instantiated or + not. + */ + bool m_bHasTextChild; + + /** This flag specifies whether an object has a list as child regardless + of whether that child being currently instantiated or not. This + flag is always true in the current implementation because the list + child is just another wrapper around this object and thus has the + same life time. + */ + bool m_bHasListChild; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblebutton.hxx b/accessibility/inc/standard/vclxaccessiblebutton.hxx new file mode 100644 index 0000000000..460c90c67c --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblebutton.hxx @@ -0,0 +1,67 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> + +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleButton final : public cppu::ImplInheritanceHelper< + VCLXAccessibleTextComponent, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleValue> +{ + virtual ~VCLXAccessibleButton() override = default; + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + +public: + VCLXAccessibleButton( VCLXWindow* pVCLXWindow ): ImplInheritanceHelper(pVCLXWindow) {} + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual OUString SAL_CALL getAccessibleName( ) override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblecheckbox.hxx b/accessibility/inc/standard/vclxaccessiblecheckbox.hxx new file mode 100644 index 0000000000..dc7b0d3c35 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblecheckbox.hxx @@ -0,0 +1,76 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> + +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleCheckBox final : public cppu::ImplInheritanceHelper< + VCLXAccessibleTextComponent, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleValue> +{ +private: + bool m_bChecked; + bool m_bIndeterminate; + + virtual ~VCLXAccessibleCheckBox() override = default; + + sal_Int32 implGetMaximumValue(); + + bool IsChecked() const; + bool IsIndeterminate() const; + + void SetChecked( bool bChecked ); + void SetIndeterminate( bool bIndeterminate ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + +public: + VCLXAccessibleCheckBox( VCLXWindow* pVCLXindow ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblecombobox.hxx b/accessibility/inc/standard/vclxaccessiblecombobox.hxx new file mode 100644 index 0000000000..67c2ef93b1 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblecombobox.hxx @@ -0,0 +1,46 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessiblebox.hxx> + +/** The accessible combobox has two children. The first is the text field + represented by an object of the VCLXAccessibleEdit class. + The second is the list containing all items and is represented by an + object of the VCLXAccessibleList class which does not + support selection at the moment. +*/ +class VCLXAccessibleComboBox final : public VCLXAccessibleBox +{ +public: + VCLXAccessibleComboBox(VCLXWindow* pVCLXindow); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + // Return combo box specific services. + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +private: + virtual ~VCLXAccessibleComboBox() override = default; + + virtual bool IsValid() const override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibledropdowncombobox.hxx b/accessibility/inc/standard/vclxaccessibledropdowncombobox.hxx new file mode 100644 index 0000000000..76c1c14594 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibledropdowncombobox.hxx @@ -0,0 +1,48 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessiblebox.hxx> + +/** The accessible drop down combobox has two children. The first is the + text field represented by an object of the + VCLXAccessibleEdit class. The second is the list + containing all items and is represented by an object of the + VCLXAccessibleList class which does not support selection + at the moment. +*/ +class VCLXAccessibleDropDownComboBox final : public VCLXAccessibleBox +{ +public: + VCLXAccessibleDropDownComboBox(VCLXWindow* pVCLXindow); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + // Return drop down combo box specific services. + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +private: + virtual ~VCLXAccessibleDropDownComboBox() override = default; + + virtual bool IsValid() const override; + virtual void ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibledropdownlistbox.hxx b/accessibility/inc/standard/vclxaccessibledropdownlistbox.hxx new file mode 100644 index 0000000000..d971e80cca --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibledropdownlistbox.hxx @@ -0,0 +1,47 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessiblebox.hxx> + +/** The accessible drop down combobox has two children. The first is the + text field represented by an object of the + VCLXAccessibleTextField class which can not be edited. The + second is the list containing all items and is represented by an object + of the VCLXAccessibleListBoxList class which does support + selection. +*/ +class VCLXAccessibleDropDownListBox final : public VCLXAccessibleBox +{ +public: + VCLXAccessibleDropDownListBox(VCLXWindow* pVCLXindow); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + // Return drop down list box specific services. + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +private: + virtual ~VCLXAccessibleDropDownListBox() override = default; + + virtual bool IsValid() const override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibleedit.hxx b/accessibility/inc/standard/vclxaccessibleedit.hxx new file mode 100644 index 0000000000..b3b6a239b9 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibleedit.hxx @@ -0,0 +1,105 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> + +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleEdit : public cppu::ImplInheritanceHelper< + VCLXAccessibleTextComponent, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleEditableText> +{ + friend class VCLXAccessibleBox; + +private: + sal_Int32 m_nCaretPosition; + +protected: + virtual ~VCLXAccessibleEdit() override = default; + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + sal_Int16 implGetAccessibleRole(); + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + +public: + VCLXAccessibleEdit( VCLXWindow* pVCLXindow ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition( ) override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount( ) override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText( ) override; + virtual sal_Int32 SAL_CALL getSelectionStart( ) override; + virtual sal_Int32 SAL_CALL getSelectionEnd( ) override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText( ) override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + // XAccessibleEditableText + virtual sal_Bool SAL_CALL cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL pasteText( sal_Int32 nIndex ) override; + virtual sal_Bool SAL_CALL deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL insertText( const OUString& sText, sal_Int32 nIndex ) override; + virtual sal_Bool SAL_CALL replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString& sReplacement ) override; + virtual sal_Bool SAL_CALL setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const css::uno::Sequence< css::beans::PropertyValue >& aAttributeSet ) override; + virtual sal_Bool SAL_CALL setText( const OUString& sText ) override; + +private: + bool isEditable(); +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblefixedhyperlink.hxx b/accessibility/inc/standard/vclxaccessiblefixedhyperlink.hxx new file mode 100644 index 0000000000..15f6ee17e4 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblefixedhyperlink.hxx @@ -0,0 +1,36 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> + +class VCLXAccessibleFixedHyperlink final : public VCLXAccessibleTextComponent +{ + virtual ~VCLXAccessibleFixedHyperlink() override = default; + +public: + using VCLXAccessibleTextComponent::VCLXAccessibleTextComponent; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblefixedtext.hxx b/accessibility/inc/standard/vclxaccessiblefixedtext.hxx new file mode 100644 index 0000000000..bce6ef6ec1 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblefixedtext.hxx @@ -0,0 +1,38 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> + +class VCLXAccessibleFixedText final : public VCLXAccessibleTextComponent +{ + virtual ~VCLXAccessibleFixedText() override = default; + + virtual void FillAccessibleStateSet(sal_Int64& rStateSet) override; + +public: + using VCLXAccessibleTextComponent::VCLXAccessibleTextComponent; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibleheaderbar.hxx b/accessibility/inc/standard/vclxaccessibleheaderbar.hxx new file mode 100644 index 0000000000..505e0f2859 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibleheaderbar.hxx @@ -0,0 +1,54 @@ +/* -*- 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 . + */ +#pragma once + +#include <vcl/headbar.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <toolkit/awt/vclxwindow.hxx> + +typedef std::vector<css::uno::WeakReference<css::accessibility::XAccessible>> ListItems; + +class VCLXAccessibleHeaderBar final : public VCLXAccessibleComponent +{ + VclPtr<HeaderBar> m_pHeadBar; + +public: + virtual ~VCLXAccessibleHeaderBar() override; + + VCLXAccessibleHeaderBar(VCLXWindow* pVCLXindow); + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override; + virtual css::uno::Reference<css::accessibility::XAccessible> + SAL_CALL getAccessibleChild(sal_Int64 i) override; + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +public: + virtual void SAL_CALL disposing() override; + css::uno::Reference<css::accessibility::XAccessible> CreateChild(sal_Int32 i); + +private: + ListItems m_aAccessibleChildren; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibleheaderbaritem.hxx b/accessibility/inc/standard/vclxaccessibleheaderbaritem.hxx new file mode 100644 index 0000000000..563e86ff52 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibleheaderbaritem.hxx @@ -0,0 +1,88 @@ +/* -*- 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 . + */ +#pragma once + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <cppuhelper/implbase.hxx> + +#include <vcl/vclptr.hxx> + +class HeaderBar; +class VclSimpleEvent; +class VclWindowEvent; + + +// ---------------------------------------------------- +// class VCLXAccessibleHeaderBarItem +// ---------------------------------------------------- + +class VCLXAccessibleHeaderBarItem final : public cppu::ImplInheritanceHelper< + comphelper::OAccessibleExtendedComponentHelper, + css::accessibility::XAccessible, + css::lang::XServiceInfo> +{ +private: + VclPtr<HeaderBar> m_pHeadBar; + sal_Int32 m_nIndexInParent; + + void FillAccessibleStateSet( sal_Int64& rStateSet ); + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + +public: + VCLXAccessibleHeaderBarItem( HeaderBar* pHeadBar, sal_Int32 _nIndexInParent ); + virtual ~VCLXAccessibleHeaderBarItem() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override {}; + virtual sal_Int32 SAL_CALL getForeground() override; + virtual sal_Int32 SAL_CALL getBackground() override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblelist.hxx b/accessibility/inc/standard/vclxaccessiblelist.hxx new file mode 100644 index 0000000000..f668e75d7c --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblelist.hxx @@ -0,0 +1,174 @@ +/* -*- 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 . + */ + +#pragma once + +#include <memory> +#include <vector> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <cppuhelper/implbase.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> + +class VCLXAccessibleListItem; + +namespace accessibility +{ + class IComboListBoxHelper; +} + + +/** Base class for the list contained in list- and combo boxes. This class + does not support selection because lists of combo boxes give no direct + access to their underlying list implementation. Look into derived + classes for selection. +*/ +class VCLXAccessibleList final + : public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessible, + css::accessibility::XAccessibleSelection> +{ +public: + enum BoxType {COMBOBOX, LISTBOX}; + + VCLXAccessibleList (VCLXWindow* pVCLXindow, BoxType aBoxType, + const css::uno::Reference< + css::accessibility::XAccessible >& _xParent); + + /** The index that is passed to this method is returned on following + calls to getAccessibleIndexInParent. + */ + void SetIndexInParent (sal_Int32 nIndex); + + /** Process some of the events and delegate the rest to the base classes. + */ + virtual void ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) override; + virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) override; + + /** Called on reception of selection events this method checks all known + list items for a possible change in their selection state and + updates that accordingly. No accessibility events are sent because + the XAccessibleSelection interface is not supported and the items + are transient. + @param sTextOfSelectedItem + This string contains the text of the currently selected + item. It is used to retrieve the index of that item. + */ + void UpdateSelection (std::u16string_view sTextOfSelectedItem); + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext> SAL_CALL + getAccessibleContext() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount() override final; + css::uno::Reference< css::accessibility::XAccessible> SAL_CALL + getAccessibleChild (sal_Int64 i) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleParent( ) override; + + /** The index returned as index in parent is always the one set with the + SetIndexInParent() method. + */ + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + // Return list specific services. + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + bool IsInDropDown() const; + void HandleDropOpen(); + void ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent, bool b_IsDropDownList); + void UpdateSelection_Acc (std::u16string_view sTextOfSelectedItem, bool b_IsDropDownList); + void UpdateSelection_Impl_Acc (bool b_IsDropDownList); + + static void NotifyListItem(css::uno::Any const & val); + ::accessibility::IComboListBoxHelper* getListBoxHelper() { return m_pListBoxHelper.get(); } +private: + BoxType m_aBoxType; + std::unique_ptr<::accessibility::IComboListBoxHelper> m_pListBoxHelper; + std::vector<rtl::Reference<VCLXAccessibleListItem>> m_aAccessibleChildren; + sal_Int32 m_nVisibleLineCount; + /// Index in parent. This is settable from the outside. + sal_Int32 m_nIndexInParent; + sal_Int32 m_nLastTopEntry; + sal_Int32 m_nLastSelectedPos; + bool m_bDisableProcessEvent; + bool m_bVisible; + sal_Int32 m_nCurSelectedPos; + + + virtual ~VCLXAccessibleList() override = default; + + sal_Int64 implGetAccessibleChildCount(); + + /** This function is called from the implementation helper during a + XComponent::dispose call. Free the list of items and the items themselves. + */ + virtual void SAL_CALL disposing() override; + + /** This method adds the states + AccessibleStateType::FOCUSABLE and possibly + AccessibleStateType::MULTI_SELECTABLE to the state set + of the base classes. + */ + virtual void FillAccessibleStateSet (sal_Int64& rStateSet) override; + + /** Create the specified child and insert it into the list of children. + Sets the child's states. + */ + rtl::Reference<VCLXAccessibleListItem> CreateChild (sal_Int32 i); + + /** Call this method when the item list has been changed, i.e. items + have been deleted or inserted. + */ + void HandleChangedItemList(); + + // VCLXAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + /** We need to save the accessible parent to return it in getAccessibleParent(), + because this method of the base class returns the wrong parent. + */ + css::uno::Reference< css::accessibility::XAccessible > m_xParent; + + void UpdateEntryRange_Impl(); + void UpdateSelection_Impl(sal_Int32 nPos = 0); + bool checkEntrySelected(sal_Int32 _nPos, + css::uno::Any& _rNewValue, + css::uno::Reference< css::accessibility::XAccessible >& _rxNewAcc); + void notifyVisibleStates(bool _bSetNew ); + void UpdateVisibleLineCount(); +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblelistbox.hxx b/accessibility/inc/standard/vclxaccessiblelistbox.hxx new file mode 100644 index 0000000000..9405947b2b --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblelistbox.hxx @@ -0,0 +1,45 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessiblebox.hxx> + +/** The accessible drop down combobox has one children. It is the list + containing all items and is represented by an object of the + VCLXAccessibleListBoxList class which does support + selection. +*/ +class VCLXAccessibleListBox final : public VCLXAccessibleBox +{ +public: + VCLXAccessibleListBox(VCLXWindow* pVCLXindow); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + // Return list box specific services. + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +private: + virtual ~VCLXAccessibleListBox() override = default; + + virtual bool IsValid() const override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblelistitem.hxx b/accessibility/inc/standard/vclxaccessiblelistitem.hxx new file mode 100644 index 0000000000..260c132bbf --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblelistitem.hxx @@ -0,0 +1,155 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <standard/vclxaccessiblelist.hxx> + +// forward --------------------------------------------------------------- + +namespace com::sun::star::awt { + struct Point; + struct Rectangle; + struct Size; + class XFocusListener; +} + +// class VCLXAccessibleListItem ------------------------------------------ + +typedef ::cppu::WeakComponentImplHelper< css::accessibility::XAccessible + , css::accessibility::XAccessibleContext + , css::accessibility::XAccessibleComponent + , css::accessibility::XAccessibleEventBroadcaster + , css::accessibility::XAccessibleText + , css::lang::XServiceInfo > VCLXAccessibleListItem_BASE; + +/** the class OAccessibleListBoxEntry represents the base class for an accessible object of a listbox entry +*/ +class VCLXAccessibleListItem final : public ::cppu::BaseMutex, + public ::comphelper::OCommonAccessibleText, + public VCLXAccessibleListItem_BASE +{ +private: + OUString m_sEntryText; + sal_Int32 m_nIndexInParent; + bool m_bSelected; + bool m_bVisible; + + /// client id in the AccessibleEventNotifier queue + sal_uInt32 m_nClientId; + + rtl::Reference< VCLXAccessibleList > m_xParent; + + virtual ~VCLXAccessibleListItem() override = default; + /** this function is called upon disposing the component + */ + virtual void SAL_CALL disposing() override; + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + +public: + /** OAccessibleBase needs a valid view + @param _nIndexInParent + is the position of the entry inside the listbox + @param _xParent + is our parent accessible object + */ + VCLXAccessibleListItem(sal_Int32 _nIndexInParent, + rtl::Reference< VCLXAccessibleList > _xParent); + + void NotifyAccessibleEvent( sal_Int16 _nEventId, const css::uno::Any& _aOldValue, const css::uno::Any& _aNewValue ); + + bool IsSelected() const { return m_bSelected; } + void SetSelected( bool _bSelected ); + void SetVisible( bool _bVisible ); + + // XTypeProvider + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Rectangle SAL_CALL getBounds( ) override; + virtual css::awt::Point SAL_CALL getLocation( ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual css::awt::Size SAL_CALL getSize( ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground() override; + virtual sal_Int32 SAL_CALL getBackground() override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblemenu.hxx b/accessibility/inc/standard/vclxaccessiblemenu.hxx new file mode 100644 index 0000000000..ce7b3f0580 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblemenu.hxx @@ -0,0 +1,68 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessiblemenuitem.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> + +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleMenu final : + public cppu::ImplInheritanceHelper< + VCLXAccessibleMenuItem, css::accessibility::XAccessibleSelection> +{ + virtual bool IsFocused() override; + virtual bool IsPopupMenuOpen() override; + sal_Int64 implGetSelectedAccessibleChildCount(); + +public: + VCLXAccessibleMenu( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu = nullptr ): + ImplInheritanceHelper(pParent, nItemPos, pMenu) {} + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nChildIndex ) override; + + // XAccessibleAction + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblemenubar.hxx b/accessibility/inc/standard/vclxaccessiblemenubar.hxx new file mode 100644 index 0000000000..c5b3984e0b --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblemenubar.hxx @@ -0,0 +1,62 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/accessiblemenucomponent.hxx> +#include <vcl/vclptr.hxx> + +class VclSimpleEvent; +class VclWindowEvent; +namespace vcl { class Window; } + + + + +class VCLXAccessibleMenuBar final : public OAccessibleMenuComponent +{ + VclPtr<vcl::Window> m_pWindow; + + virtual bool IsFocused() override; + + DECL_LINK( WindowEventListener, VclWindowEvent&, void ); + + void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleMenuBar( Menu* pMenu ); + virtual ~VCLXAccessibleMenuBar() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + + // XAccessibleExtendedComponent + virtual sal_Int32 SAL_CALL getBackground( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblemenuitem.hxx b/accessibility/inc/standard/vclxaccessiblemenuitem.hxx new file mode 100644 index 0000000000..4eec5fa674 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblemenuitem.hxx @@ -0,0 +1,101 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/accessiblemenuitemcomponent.hxx> + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +#include <cppuhelper/implbase.hxx> +#include <comphelper/accessibletexthelper.hxx> + + + + +class VCLXAccessibleMenuItem : public cppu::ImplInheritanceHelper< + OAccessibleMenuItemComponent, + css::accessibility::XAccessibleText, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleValue>, + public ::comphelper::OCommonAccessibleText +{ +protected: + virtual bool IsFocused() override; + virtual bool IsSelected() override; + virtual bool IsCheckable(); + virtual bool IsChecked() override; + + virtual bool IsHighlighted() override; + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + // OCommonAccessibleText + virtual OUString implGetText() final override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override final; + +public: + VCLXAccessibleMenuItem( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu = nullptr ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) final override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() final override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override final; + virtual sal_Int32 SAL_CALL getSelectionStart() override final; + virtual sal_Int32 SAL_CALL getSelectionEnd() override final; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() final override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) final override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblemenuseparator.hxx b/accessibility/inc/standard/vclxaccessiblemenuseparator.hxx new file mode 100644 index 0000000000..51071c19d1 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblemenuseparator.hxx @@ -0,0 +1,37 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/accessiblemenuitemcomponent.hxx> + +class VCLXAccessibleMenuSeparator final : public OAccessibleMenuItemComponent +{ +public: + VCLXAccessibleMenuSeparator(Menu* pParent, sal_uInt16 nItemPos); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int16 SAL_CALL getAccessibleRole() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblepopupmenu.hxx b/accessibility/inc/standard/vclxaccessiblepopupmenu.hxx new file mode 100644 index 0000000000..8e93af22d8 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblepopupmenu.hxx @@ -0,0 +1,43 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/accessiblemenucomponent.hxx> + +class VCLXAccessiblePopupMenu final : public OAccessibleMenuComponent +{ + virtual bool IsFocused() override; + +public: + using OAccessibleMenuComponent::OAccessibleMenuComponent; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override; + virtual sal_Int16 SAL_CALL getAccessibleRole() override; + + // XAccessibleExtendedComponent + virtual sal_Int32 SAL_CALL getBackground() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibleradiobutton.hxx b/accessibility/inc/standard/vclxaccessibleradiobutton.hxx new file mode 100644 index 0000000000..4e93579fa9 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibleradiobutton.hxx @@ -0,0 +1,65 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> + +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleRadioButton final : public cppu::ImplInheritanceHelper< + VCLXAccessibleTextComponent, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleValue> +{ + virtual ~VCLXAccessibleRadioButton() override = default; + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + +public: + VCLXAccessibleRadioButton( VCLXWindow* pVCLXWindow ): ImplInheritanceHelper(pVCLXWindow) {} + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblescrollbar.hxx b/accessibility/inc/standard/vclxaccessiblescrollbar.hxx new file mode 100644 index 0000000000..ffaa7f689a --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblescrollbar.hxx @@ -0,0 +1,68 @@ +/* -*- 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 . + */ + +#pragma once + +#include <toolkit/awt/vclxaccessiblecomponent.hxx> + +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleScrollBar final : public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleValue> +{ + virtual ~VCLXAccessibleScrollBar() override = default; + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + +public: + VCLXAccessibleScrollBar( VCLXWindow* pVCLXWindow ): ImplInheritanceHelper(pVCLXWindow) {} + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; + + // XAccessibleContext + OUString SAL_CALL getAccessibleName( ) override; + +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblestatusbar.hxx b/accessibility/inc/standard/vclxaccessiblestatusbar.hxx new file mode 100644 index 0000000000..17f77af4fb --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblestatusbar.hxx @@ -0,0 +1,68 @@ +/* -*- 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 . + */ + +#pragma once + +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <vcl/status.hxx> +#include <vcl/vclptr.hxx> + +#include <vector> + + +class VCLXAccessibleStatusBarItem; + +class VCLXAccessibleStatusBar final : public VCLXAccessibleComponent +{ +private: + typedef std::vector< rtl::Reference< VCLXAccessibleStatusBarItem > > AccessibleChildren; + + AccessibleChildren m_aAccessibleChildren; + VclPtr<StatusBar> m_pStatusBar; + + void UpdateShowing( sal_Int32 i, bool bShowing ); + void UpdateItemName( sal_Int32 i ); + void UpdateItemText( sal_Int32 i ); + + void InsertChild( sal_Int32 i ); + void RemoveChild( sal_Int32 i ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleStatusBar( VCLXWindow* pVCLXWindow ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; +}; + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessiblestatusbaritem.hxx b/accessibility/inc/standard/vclxaccessiblestatusbaritem.hxx new file mode 100644 index 0000000000..0ab119fe19 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessiblestatusbaritem.hxx @@ -0,0 +1,120 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <comphelper/accessibletexthelper.hxx> +#include <cppuhelper/implbase.hxx> +#include <vcl/status.hxx> +#include <vcl/vclptr.hxx> + + + + +typedef ::comphelper::OAccessibleTextHelper AccessibleTextHelper_BASE; + +class VCLXAccessibleStatusBarItem final : public cppu::ImplInheritanceHelper< + AccessibleTextHelper_BASE, + css::accessibility::XAccessible, + css::lang::XServiceInfo> +{ + friend class VCLXAccessibleStatusBar; + +private: + VclPtr<StatusBar> m_pStatusBar; + sal_uInt16 m_nItemId; + OUString m_sItemName; + OUString m_sItemText; + bool m_bShowing; + + bool IsShowing(); + void SetShowing( bool bShowing ); + void SetItemName( const OUString& sItemName ); + OUString GetItemName(); + void SetItemText( const OUString& sItemText ); + OUString GetItemText(); + + void FillAccessibleStateSet( sal_Int64& rStateSet ); + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleStatusBarItem( StatusBar* pStatusBar, sal_uInt16 nItemId ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int64) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletabcontrol.hxx b/accessibility/inc/standard/vclxaccessibletabcontrol.hxx new file mode 100644 index 0000000000..32565c6d80 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletabcontrol.hxx @@ -0,0 +1,87 @@ +/* -*- 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 . + */ + +#pragma once + +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <cppuhelper/implbase.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/vclptr.hxx> + +#include <vector> + +class VCLXAccessibleTabPage; + + +class VCLXAccessibleTabControl final : public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessibleSelection> +{ +private: + typedef std::vector< rtl::Reference< VCLXAccessibleTabPage > > AccessibleChildren; + + AccessibleChildren m_aAccessibleChildren; + VclPtr<TabControl> m_pTabControl; + + css::uno::Reference< css::accessibility::XAccessible > implGetAccessibleChild( sal_Int64 i ); + bool implIsAccessibleChildSelected( sal_Int32 nChildIndex ); + + + void UpdateFocused(); + void UpdateSelected( sal_Int32 i, bool bSelected ); + void UpdatePageText( sal_Int32 i ); + void UpdateTabPage( sal_Int32 i, bool bNew ); + + void InsertChild( sal_Int32 i ); + void RemoveChild( sal_Int32 i ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleTabControl( VCLXWindow* pVCLXWindow ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nChildIndex ) override; +}; + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletabpage.hxx b/accessibility/inc/standard/vclxaccessibletabpage.hxx new file mode 100644 index 0000000000..bb3d720055 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletabpage.hxx @@ -0,0 +1,128 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <comphelper/accessibletexthelper.hxx> +#include <cppuhelper/implbase.hxx> +#include <vcl/vclptr.hxx> + + +class TabControl; + + + +typedef ::comphelper::OAccessibleTextHelper AccessibleTextHelper_BASE; + +class VCLXAccessibleTabPage final : public cppu::ImplInheritanceHelper< + AccessibleTextHelper_BASE, + css::accessibility::XAccessible, + css::lang::XServiceInfo> +{ + friend class VCLXAccessibleTabControl; + +private: + VclPtr<TabControl> m_pTabControl; + sal_uInt16 m_nPageId; + bool m_bFocused; + bool m_bSelected; + OUString m_sPageText; + + sal_Int64 implGetAccessibleChildCount(); + + bool IsFocused() const; + bool IsSelected() const; + + void SetFocused( bool bFocused ); + void SetSelected( bool bSelected ); + void SetPageText( const OUString& sPageText ); + OUString GetPageText(); + + void Update( bool bNew ); + + sal_uInt16 GetPageId() const { return m_nPageId; } + + void FillAccessibleStateSet( sal_Int64& rStateSet ); + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleTabPage( TabControl* pTabControl, sal_uInt16 nPageId ); + virtual ~VCLXAccessibleTabPage() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + + // XAccessibleText + virtual OUString SAL_CALL getText() override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletabpagewindow.hxx b/accessibility/inc/standard/vclxaccessibletabpagewindow.hxx new file mode 100644 index 0000000000..826aa8daad --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletabpagewindow.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ + +#pragma once + +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/vclptr.hxx> + + + + +class VCLXAccessibleTabPageWindow final : public VCLXAccessibleComponent +{ +private: + VclPtr<TabControl> m_pTabControl; + VclPtr<TabPage> m_pTabPage; + sal_uInt16 m_nPageId; + + // OCommonAccessibleComponent + virtual css::awt::Rectangle implGetBounds( ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleTabPageWindow( VCLXWindow* pVCLXWindow ); + + // XAccessibleContext + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; +}; + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletextcomponent.hxx b/accessibility/inc/standard/vclxaccessibletextcomponent.hxx new file mode 100644 index 0000000000..3585dd7785 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletextcomponent.hxx @@ -0,0 +1,79 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <cppuhelper/implbase.hxx> + + + + +class VCLXAccessibleTextComponent : public cppu::ImplInheritanceHelper< + VCLXAccessibleComponent, + css::accessibility::XAccessibleText>, + public ::comphelper::OCommonAccessibleText +{ + OUString m_sText; + + // accessible name the object had when SetText was called last time + OUString m_sOldName; + +protected: + void SetText( const OUString& sText ); + + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleTextComponent( VCLXWindow* pVCLXWindow ); + + // XAccessibleText + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual OUString SAL_CALL getSelectedText() override; + virtual sal_Int32 SAL_CALL getSelectionStart() override; + virtual sal_Int32 SAL_CALL getSelectionEnd() override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getText() override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; +}; + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletextfield.hxx b/accessibility/inc/standard/vclxaccessibletextfield.hxx new file mode 100644 index 0000000000..b730bd107e --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletextfield.hxx @@ -0,0 +1,72 @@ +/* -*- 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 . + */ + +#pragma once + +#include <standard/vclxaccessibletextcomponent.hxx> + +#include <cppuhelper/implbase.hxx> + +/** This class represents non editable text fields. The object passed to + the constructor is expected to be a list (a ListBox to be + more specific). From this always the selected item is token to be made + accessible by this class. When the selected item changes then also the + exported text changes. +*/ +class VCLXAccessibleTextField final : + public cppu::ImplInheritanceHelper<VCLXAccessibleTextComponent, css::accessibility::XAccessible> +{ +public: + VCLXAccessibleTextField (VCLXWindow* pVCLXindow, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent); + + // XAccessible + css::uno::Reference< css::accessibility::XAccessibleContext> SAL_CALL + getAccessibleContext() override; + + // XAccessibleContext + sal_Int64 SAL_CALL getAccessibleChildCount() override; + css::uno::Reference< css::accessibility::XAccessible> SAL_CALL + getAccessibleChild (sal_Int64 i) override; + sal_Int16 SAL_CALL getAccessibleRole() override; + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + getAccessibleParent( ) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + // Return text field specific services. + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + virtual ~VCLXAccessibleTextField() override = default; + + /** With this method the text of the currently selected item is made + available to the VCLXAccessibleTextComponent base class. + */ + OUString implGetText() override; + + /** We need to save the accessible parent to return it in getAccessibleParent(), + because this method of the base class returns the wrong parent. + */ + css::uno::Reference< css::accessibility::XAccessible > m_xParent; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletoolbox.hxx b/accessibility/inc/standard/vclxaccessibletoolbox.hxx new file mode 100644 index 0000000000..4918e511ba --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletoolbox.hxx @@ -0,0 +1,94 @@ +/* -*- 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 . + */ +#pragma once + +#include <map> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <vcl/toolbox.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <cppuhelper/implbase.hxx> + + +class VCLXAccessibleToolBoxItem; +class ToolBox; + +typedef std::map< sal_Int32, rtl::Reference< VCLXAccessibleToolBoxItem > > ToolBoxItemsMap; + +class VCLXAccessibleToolBox final : public cppu::ImplInheritanceHelper<VCLXAccessibleComponent, css::accessibility::XAccessibleSelection> +{ +private: + ToolBoxItemsMap m_aAccessibleChildren; + + VCLXAccessibleToolBoxItem* GetItem_Impl( ToolBox::ImplToolItems::size_type _nPos ); + + void UpdateFocus_Impl(); + void ReleaseFocus_Impl( ToolBox::ImplToolItems::size_type _nPos ); + void UpdateChecked_Impl( ToolBox::ImplToolItems::size_type _nPos ); + void UpdateIndeterminate_Impl( ToolBox::ImplToolItems::size_type _nPos ); + void UpdateItem_Impl( ToolBox::ImplToolItems::size_type _nPos ); + void UpdateAllItems_Impl(); + void UpdateItemName_Impl( ToolBox::ImplToolItems::size_type _nPos ); + void UpdateItemEnabled_Impl( ToolBox::ImplToolItems::size_type _nPos ); + void UpdateCustomPopupItemp_Impl( vcl::Window* pWindow, bool bOpen ); + void HandleSubToolBarEvent( const VclWindowEvent& rVclWindowEvent ); + void ReleaseSubToolBox( ToolBox* _pSubToolBox ); + sal_Int64 implGetAccessibleChildCount(); + + virtual ~VCLXAccessibleToolBox() override; + + virtual void FillAccessibleStateSet( sal_Int64& rStateSet ) override; + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; + virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) override; + + virtual css::uno::Reference< css::accessibility::XAccessible > GetChildAccessible( const VclWindowEvent& rVclWindowEvent ) override; + css::uno::Reference< css::accessibility::XAccessible > GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent ); + + // XComponent + virtual void SAL_CALL disposing() override; + +public: + VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int64 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int64 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int64 nChildIndex ) override; + +private: + void implReleaseToolboxItem( + ToolBoxItemsMap::iterator const & _rMapPos, + bool _bNotifyRemoval + ); +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/standard/vclxaccessibletoolboxitem.hxx b/accessibility/inc/standard/vclxaccessibletoolboxitem.hxx new file mode 100644 index 0000000000..5bff8ef953 --- /dev/null +++ b/accessibility/inc/standard/vclxaccessibletoolboxitem.hxx @@ -0,0 +1,150 @@ +/* -*- 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 . + */ +#pragma once + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/vclptr.hxx> + + +typedef ::comphelper::OAccessibleTextHelper AccessibleTextHelper_BASE; + +class VCLXAccessibleToolBoxItem final : public cppu::ImplInheritanceHelper< + AccessibleTextHelper_BASE, + css::accessibility::XAccessible, + css::accessibility::XAccessibleAction, + css::accessibility::XAccessibleValue, + css::lang::XServiceInfo> +{ +private: + OUString m_sOldName; + VclPtr<ToolBox> m_pToolBox; + sal_Int32 m_nIndexInParent; + sal_Int16 m_nRole; + ToolBoxItemId m_nItemId; + bool m_bHasFocus; + bool m_bIsChecked; + bool m_bIndeterminate; + + css::uno::Reference< css::accessibility::XAccessible > m_xChild; + OUString GetText() const; + +public: + sal_Int32 getIndexInParent() const { return m_nIndexInParent; } + void setIndexInParent( sal_Int32 _nNewIndex ) { m_nIndexInParent = _nNewIndex; } + +private: + virtual ~VCLXAccessibleToolBoxItem() override; + + virtual void SAL_CALL disposing() override; + + /// implements the calculation of the bounding rectangle + virtual css::awt::Rectangle implGetBounds( ) override; + + // OCommonAccessibleText + virtual OUString implGetText() override; + virtual css::lang::Locale implGetLocale() override; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override; + +public: + VCLXAccessibleToolBoxItem( ToolBox* _pToolBox, sal_Int32 _nPos ); + + void SetFocus( bool _bFocus ); + bool HasFocus() const { return m_bHasFocus; } + void SetChecked( bool _bCheck ); + void SetIndeterminate( bool _bIndeterminate ); + void ReleaseToolBox() { m_pToolBox = nullptr; } + void NameChanged(); + void SetChild( const css::uno::Reference< css::accessibility::XAccessible >& _xChild ); + const css::uno::Reference< css::accessibility::XAccessible >& + GetChild() const { return m_xChild; } + void NotifyChildEvent( const css::uno::Reference< css::accessibility::XAccessible >& _xChild, bool _bShow ); + + void ToggleEnableState(); + + // XInterface + css::uno::Any SAL_CALL queryInterface(css::uno::Type const & aType) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleContext + virtual sal_Int64 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual sal_Int64 SAL_CALL getAccessibleStateSet( ) override; + + // XAccessibleText + virtual OUString SAL_CALL getText() override; + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getCharacterCount() override; + virtual sal_Int32 SAL_CALL getCaretPosition() override; + virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; + virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; + virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override; + + // XAccessibleComponent + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleExtendedComponent + virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override; + virtual OUString SAL_CALL getTitledBorderText( ) override; + virtual OUString SAL_CALL getToolTipText( ) override; + + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override; + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override; + + // XAccessibleValue + virtual css::uno::Any SAL_CALL getCurrentValue( ) override; + virtual sal_Bool SAL_CALL setCurrentValue( const css::uno::Any& aNumber ) override; + virtual css::uno::Any SAL_CALL getMaximumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumValue( ) override; + virtual css::uno::Any SAL_CALL getMinimumIncrement( ) override; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/strings.hrc b/accessibility/inc/strings.hrc new file mode 100644 index 0000000000..7e51ade2d4 --- /dev/null +++ b/accessibility/inc/strings.hrc @@ -0,0 +1,36 @@ +/* -*- 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 . + */ + +#pragma once + +#define NC_(Context, String) TranslateId(Context, u8##String) + +#define RID_STR_ACC_NAME_BROWSEBUTTON NC_("RID_STR_ACC_NAME_BROWSEBUTTON", "Browse") +#define STR_SVT_ACC_ACTION_EXPAND NC_("STR_SVT_ACC_ACTION_EXPAND", "Expand" ) +#define STR_SVT_ACC_ACTION_COLLAPSE NC_("STR_SVT_ACC_ACTION_COLLAPSE", "Collapse") +#define RID_STR_ACC_ACTION_CHECK NC_("RID_STR_ACC_ACTION_CHECK", "Check") +#define RID_STR_ACC_ACTION_UNCHECK NC_("RID_STR_ACC_ACTION_UNCHECK", "Uncheck") +#define RID_STR_ACC_SCROLLBAR_NAME_VERTICAL NC_("RID_STR_ACC_SCROLLBAR_NAME_VERTICAL", "Vertical scroll bar") +#define RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL NC_("RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL", "Horizontal scroll bar") +#define RID_STR_ACC_PANEL_DESCRIPTION NC_("RID_STR_ACC_PANEL_DESCRIPTION", "Please press enter to go into child control for more operations") +#define RID_STR_ACC_COLUMN_NUM NC_("RID_STR_ACC_COLUMN_NUM", "Column %COLUMNNUMBER") +#define RID_STR_ACC_ROW_NUM NC_("RID_STR_ACC_ROW_NUM", "Row %ROWNUMBER") + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/inc/strings.hxx b/accessibility/inc/strings.hxx new file mode 100644 index 0000000000..6fd402a9ba --- /dev/null +++ b/accessibility/inc/strings.hxx @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include <rtl/ustring.hxx> + +inline constexpr OUString RID_STR_ACC_ACTION_CLICK = u"press"_ustr; +inline constexpr OUString RID_STR_ACC_ACTION_TOGGLEPOPUP = u"togglePopup"_ustr; +inline constexpr OUString RID_STR_ACC_ACTION_SELECT = u"select"_ustr; +inline constexpr OUString RID_STR_ACC_ACTION_INCLINE = u"incrementLine"_ustr; +inline constexpr OUString RID_STR_ACC_ACTION_DECLINE = u"decrementLine"_ustr; +inline constexpr OUString RID_STR_ACC_ACTION_INCBLOCK = u"incrementBlock"_ustr; +inline constexpr OUString RID_STR_ACC_ACTION_DECBLOCK = u"decrementBlock"_ustr; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/accessibility/source/extended/AccessibleBrowseBox.cxx b/accessibility/source/extended/AccessibleBrowseBox.cxx new file mode 100644 index 0000000000..6085ff9ec3 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBox.cxx @@ -0,0 +1,313 @@ +/* -*- 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 <extended/AccessibleBrowseBox.hxx> +#include <extended/AccessibleBrowseBoxTable.hxx> +#include <extended/AccessibleBrowseBoxHeaderBar.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <utility> +#include <vcl/accessibletableprovider.hxx> +#include <toolkit/helper/convert.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <sal/types.h> + + +namespace accessibility +{ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; + +// Ctor/Dtor/disposing + +AccessibleBrowseBox::AccessibleBrowseBox( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator, + ::vcl::IAccessibleTableProvider& _rBrowseBox ) + : AccessibleBrowseBoxBase( _rxParent, _rBrowseBox,nullptr, AccessibleBrowseBoxObjType::BrowseBox ), + m_aCreator(_rxCreator) +{ + m_xFocusWindow = VCLUnoHelper::GetInterface(mpBrowseBox->GetWindowInstance()); +} + +void AccessibleBrowseBox::setCreator( const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator ) +{ +#if OSL_DEBUG_LEVEL > 0 + css::uno::Reference< css::accessibility::XAccessible > xCreator(m_aCreator); + OSL_ENSURE( !xCreator.is(), "extended/AccessibleBrowseBox::setCreator: creator already set!" ); +#endif + m_aCreator = _rxCreator; +} + + +AccessibleBrowseBox::~AccessibleBrowseBox() +{ +} + + +void SAL_CALL AccessibleBrowseBox::disposing() +{ + ::osl::MutexGuard aGuard( getMutex() ); + + m_aCreator.clear(); + + if ( mxTable.is() ) + { + mxTable->dispose(); + mxTable.clear(); + } + if ( mxRowHeaderBar.is() ) + { + mxRowHeaderBar->dispose(); + mxRowHeaderBar.clear(); + } + if ( mxColumnHeaderBar.is() ) + { + mxColumnHeaderBar->dispose(); + mxColumnHeaderBar.clear(); + } + + AccessibleBrowseBoxBase::disposing(); +} + + +// css::accessibility::XAccessibleContext + +sal_Int64 SAL_CALL AccessibleBrowseBox::getAccessibleChildCount() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return vcl::BBINDEX_FIRSTCONTROL + mpBrowseBox->GetAccessibleControlCount(); +} + + +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +AccessibleBrowseBox::getAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) + throw lang::IndexOutOfBoundsException(); + + css::uno::Reference< css::accessibility::XAccessible > xRet; + if( nChildIndex >= 0 ) + { + if( nChildIndex < vcl::BBINDEX_FIRSTCONTROL ) + xRet = implGetFixedChild( nChildIndex ); + else + { + // additional controls + nChildIndex -= vcl::BBINDEX_FIRSTCONTROL; + if( nChildIndex < mpBrowseBox->GetAccessibleControlCount() ) + xRet = mpBrowseBox->CreateAccessibleControl( nChildIndex ); + } + } + + if( !xRet.is() ) + throw lang::IndexOutOfBoundsException(); + return xRet; +} + +// css::accessibility::XAccessibleComponent + +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + css::uno::Reference< css::accessibility::XAccessible > xChild; + sal_Int32 nIndex = 0; + if( mpBrowseBox->ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) ) + xChild = mpBrowseBox->CreateAccessibleControl( nIndex ); + else + { + // try whether point is in one of the fixed children + // (table, header bars, corner control) + Point aPoint( VCLPoint( rPoint ) ); + for( nIndex = 0; (nIndex < vcl::BBINDEX_FIRSTCONTROL) && !xChild.is(); ++nIndex ) + { + css::uno::Reference< css::accessibility::XAccessible > xCurrChild( implGetFixedChild( nIndex ) ); + css::uno::Reference< css::accessibility::XAccessibleComponent > + xCurrChildComp( xCurrChild, uno::UNO_QUERY ); + + if( xCurrChildComp.is() && + VCLRectangle( xCurrChildComp->getBounds() ).Contains( aPoint ) ) + xChild = xCurrChild; + } + } + return xChild; +} + + +void SAL_CALL AccessibleBrowseBox::grabFocus() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + mpBrowseBox->GrabFocus(); +} + +// XServiceInfo + +OUString SAL_CALL AccessibleBrowseBox::getImplementationName() +{ + return "com.sun.star.comp.svtools.AccessibleBrowseBox"; +} + + +// internal virtual methods + +tools::Rectangle AccessibleBrowseBox::implGetBoundingBox() +{ + vcl::Window* pParent = mpBrowseBox->GetAccessibleParentWindow(); + OSL_ENSURE( pParent, "implGetBoundingBox - missing parent window" ); + return mpBrowseBox->GetWindowExtentsRelative( *pParent ); +} + + +AbsoluteScreenPixelRectangle AccessibleBrowseBox::implGetBoundingBoxOnScreen() +{ + return mpBrowseBox->GetWindowExtentsAbsolute(); +} + +// internal helper methods +css::uno::Reference< css::accessibility::XAccessible > AccessibleBrowseBox::implGetTable() +{ + if( !mxTable.is() ) + { + mxTable = createAccessibleTable(); + + } + return mxTable; +} + +css::uno::Reference< css::accessibility::XAccessible > +AccessibleBrowseBox::implGetHeaderBar(AccessibleBrowseBoxObjType eObjType) +{ + if( eObjType == AccessibleBrowseBoxObjType::RowHeaderBar ) + { + if (!mxRowHeaderBar.is()) + mxRowHeaderBar = new AccessibleBrowseBoxHeaderBar(m_aCreator, *mpBrowseBox, eObjType); + return mxRowHeaderBar; + } + else if( eObjType == AccessibleBrowseBoxObjType::ColumnHeaderBar ) + { + if (!mxColumnHeaderBar.is()) + mxColumnHeaderBar = new AccessibleBrowseBoxHeaderBar(m_aCreator, *mpBrowseBox, eObjType); + return mxColumnHeaderBar; + } + + return css::uno::Reference<css::accessibility::XAccessible>(); +} + +css::uno::Reference< css::accessibility::XAccessible > +AccessibleBrowseBox::implGetFixedChild( sal_Int64 nChildIndex ) +{ + css::uno::Reference< css::accessibility::XAccessible > xRet; + switch( nChildIndex ) + { + case vcl::BBINDEX_COLUMNHEADERBAR: + xRet = implGetHeaderBar( AccessibleBrowseBoxObjType::ColumnHeaderBar ); + break; + case vcl::BBINDEX_ROWHEADERBAR: + xRet = implGetHeaderBar( AccessibleBrowseBoxObjType::RowHeaderBar ); + break; + case vcl::BBINDEX_TABLE: + xRet = implGetTable(); + break; + } + return xRet; +} + +rtl::Reference<AccessibleBrowseBoxTable> AccessibleBrowseBox::createAccessibleTable() +{ + css::uno::Reference< css::accessibility::XAccessible > xCreator(m_aCreator); + OSL_ENSURE( xCreator.is(), "extended/AccessibleBrowseBox::createAccessibleTable: my creator died - how this?" ); + return new AccessibleBrowseBoxTable( xCreator, *mpBrowseBox ); +} + +void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue) +{ + if ( mxTable.is() ) + { + mxTable->commitEvent(_nEventId,_rNewValue,_rOldValue); + } +} + +void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId, + const Any& _rNewValue, + const Any& _rOldValue,bool _bColumnHeaderBar) +{ + rtl::Reference< AccessibleBrowseBoxHeaderBar >& xHeaderBar = _bColumnHeaderBar ? mxColumnHeaderBar : mxRowHeaderBar; + if ( xHeaderBar.is() ) + xHeaderBar->commitEvent(_nEventId,_rNewValue,_rOldValue); +} + + +// = AccessibleBrowseBoxAccess + +AccessibleBrowseBoxAccess::AccessibleBrowseBoxAccess( css::uno::Reference< css::accessibility::XAccessible > _xParent, ::vcl::IAccessibleTableProvider& _rBrowseBox ) + :m_xParent(std::move( _xParent )) + ,m_rBrowseBox( _rBrowseBox ) +{ +} + + +AccessibleBrowseBoxAccess::~AccessibleBrowseBoxAccess() +{ +} + + +void AccessibleBrowseBoxAccess::dispose() +{ + std::unique_lock aGuard( m_aMutex ); + + if (m_xContext.is()) + { + m_xContext->dispose(); + m_xContext.clear(); + } + m_xParent.clear(); +} + + +css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL AccessibleBrowseBoxAccess::getAccessibleContext() +{ + std::unique_lock aGuard( m_aMutex ); + + // if the context died meanwhile (there is no listener, so it won't tell us explicitly when this happens), + // then reset and re-create. + if ( m_xContext.is() && !m_xContext->isAlive() ) + m_xContext = nullptr; + + if ( !m_xContext.is() ) + m_xContext = new AccessibleBrowseBox( m_xParent, this, m_rBrowseBox ); + + return m_xContext; +} + + + +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxBase.cxx b/accessibility/source/extended/AccessibleBrowseBoxBase.cxx new file mode 100644 index 0000000000..121655d788 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxBase.cxx @@ -0,0 +1,556 @@ +/* -*- 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 <extended/AccessibleBrowseBoxBase.hxx> +#include <toolkit/helper/convert.hxx> +#include <utility> +#include <vcl/accessibletableprovider.hxx> +#include <cppuhelper/supportsservice.hxx> + +#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/accessibility/IllegalAccessibleComponentStateException.hpp> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> +#include <sal/log.hxx> + + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + +namespace accessibility { + +using namespace com::sun::star::accessibility::AccessibleStateType; + + +// Ctor/Dtor/disposing + +AccessibleBrowseBoxBase::AccessibleBrowseBoxBase( + css::uno::Reference< css::accessibility::XAccessible > xParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + css::uno::Reference< css::awt::XWindow > _xFocusWindow, + AccessibleBrowseBoxObjType eObjType ) : + AccessibleBrowseBoxImplHelper( m_aMutex ), + mxParent(std::move( xParent )), + mpBrowseBox( &rBrowseBox ), + m_xFocusWindow(std::move(_xFocusWindow)), + maName( rBrowseBox.GetAccessibleObjectName( eObjType ) ), + maDescription( rBrowseBox.GetAccessibleObjectDescription( eObjType ) ), + meObjType( eObjType ), + m_aClientId(0) +{ + if ( m_xFocusWindow.is() ) + m_xFocusWindow->addFocusListener( this ); +} + +AccessibleBrowseBoxBase::AccessibleBrowseBoxBase( + css::uno::Reference< css::accessibility::XAccessible > rxParent, + ::vcl::IAccessibleTableProvider& rBrowseBox, + css::uno::Reference< css::awt::XWindow > _xFocusWindow, + AccessibleBrowseBoxObjType eObjType, + OUString rName, + OUString rDescription ) : + AccessibleBrowseBoxImplHelper( m_aMutex ), + mxParent(std::move( rxParent )), + mpBrowseBox( &rBrowseBox ), + m_xFocusWindow(std::move(_xFocusWindow)), + maName(std::move( rName )), + maDescription(std::move( rDescription )), + meObjType( eObjType ), + m_aClientId(0) +{ + if ( m_xFocusWindow.is() ) + m_xFocusWindow->addFocusListener( this ); +} + +AccessibleBrowseBoxBase::~AccessibleBrowseBoxBase() +{ + if( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } +} + +void SAL_CALL AccessibleBrowseBoxBase::disposing() +{ + ::osl::MutexGuard aGuard( getMutex() ); + if ( m_xFocusWindow.is() ) + { + SolarMutexGuard aSolarGuard; + m_xFocusWindow->removeFocusListener( this ); + } + + if ( getClientId( ) ) + { + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + mxParent = nullptr; + mpBrowseBox = nullptr; +} + +// css::accessibility::XAccessibleContext + +Reference< css::accessibility::XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleParent() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return mxParent; +} + +sal_Int64 SAL_CALL AccessibleBrowseBoxBase::getAccessibleIndexInParent() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + + // -1 for child not found/no parent (according to specification) + sal_Int64 nRet = -1; + + css::uno::Reference< uno::XInterface > xMeMyselfAndI( static_cast< css::accessibility::XAccessibleContext* >( this ), uno::UNO_QUERY ); + + // iterate over parent's children and search for this object + if( mxParent.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > + xParentContext( mxParent->getAccessibleContext() ); + if( xParentContext.is() ) + { + css::uno::Reference< uno::XInterface > xChild; + + sal_Int64 nChildCount = xParentContext->getAccessibleChildCount(); + for( sal_Int64 nChild = 0; nChild < nChildCount; ++nChild ) + { + xChild.set(xParentContext->getAccessibleChild( nChild ), css::uno::UNO_QUERY); + + if ( xMeMyselfAndI.get() == xChild.get() ) + { + nRet = nChild; + break; + } + } + } + } + return nRet; +} + +OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleDescription() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return maDescription; +} + +OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleName() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return maName; +} + +Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL +AccessibleBrowseBoxBase::getAccessibleRelationSet() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + // BrowseBox does not have relations. + return new utl::AccessibleRelationSetHelper; +} + +sal_Int64 SAL_CALL +AccessibleBrowseBoxBase::getAccessibleStateSet() +{ + SolarMethodGuard aGuard( getMutex() ); + // don't check whether alive -> StateSet may contain DEFUNC + return implCreateStateSet(); +} + +lang::Locale SAL_CALL AccessibleBrowseBoxBase::getLocale() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + if( mxParent.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > + xParentContext( mxParent->getAccessibleContext() ); + if( xParentContext.is() ) + return xParentContext->getLocale(); + } + throw IllegalAccessibleComponentStateException(); +} + +// css::accessibility::XAccessibleComponent + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::containsPoint( const css::awt::Point& rPoint ) +{ + return tools::Rectangle( Point(), getBoundingBox().GetSize() ).Contains( VCLPoint( rPoint ) ); +} + +awt::Rectangle SAL_CALL AccessibleBrowseBoxBase::getBounds() +{ + return AWTRectangle( getBoundingBox() ); +} + +awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocation() +{ + return AWTPoint( getBoundingBox().TopLeft() ); +} + +awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocationOnScreen() +{ + return AWTPoint( getBoundingBoxOnScreen().TopLeft() ); +} + +awt::Size SAL_CALL AccessibleBrowseBoxBase::getSize() +{ + return AWTSize( getBoundingBox().GetSize() ); +} + +void SAL_CALL AccessibleBrowseBoxBase::focusGained( const css::awt::FocusEvent& ) +{ + com::sun::star::uno::Any aFocused; + com::sun::star::uno::Any aEmpty; + aFocused <<= FOCUSED; + + commitEvent(AccessibleEventId::STATE_CHANGED,aFocused,aEmpty); +} + + +void SAL_CALL AccessibleBrowseBoxBase::focusLost( const css::awt::FocusEvent& ) +{ + com::sun::star::uno::Any aFocused; + com::sun::star::uno::Any aEmpty; + aFocused <<= FOCUSED; + + commitEvent(AccessibleEventId::STATE_CHANGED,aEmpty,aFocused); +} +// css::accessibility::XAccessibleEventBroadcaster + +void SAL_CALL AccessibleBrowseBoxBase::addAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener ) +{ + if ( _rxListener.is() ) + { + ::osl::MutexGuard aGuard( getMutex() ); + if ( !getClientId( ) ) + setClientId( AccessibleEventNotifier::registerClient( ) ); + + AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener ); + } +} + +void SAL_CALL AccessibleBrowseBoxBase::removeAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener ) +{ + if( !(_rxListener.is() && getClientId( )) ) + return; + + ::osl::MutexGuard aGuard( getMutex() ); + sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClient( nId ); + } +} + +// XTypeProvider + +Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxBase::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// XServiceInfo + +sal_Bool SAL_CALL AccessibleBrowseBoxBase::supportsService( + const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +Sequence< OUString > SAL_CALL AccessibleBrowseBoxBase::getSupportedServiceNames() +{ + return { "com.sun.star.accessibility.AccessibleContext" }; +} + +// other public methods + +void AccessibleBrowseBoxBase::setAccessibleName( const OUString& rName ) +{ + ::osl::ClearableMutexGuard aGuard( getMutex() ); + Any aOld; + aOld <<= maName; + maName = rName; + + aGuard.clear(); + + commitEvent( + AccessibleEventId::NAME_CHANGED, + uno::Any( maName ), + aOld ); +} + +void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString& rDescription ) +{ + ::osl::ClearableMutexGuard aGuard( getMutex() ); + Any aOld; + aOld <<= maDescription; + maDescription = rDescription; + + aGuard.clear(); + + commitEvent( + AccessibleEventId::DESCRIPTION_CHANGED, + uno::Any( maDescription ), + aOld ); +} + +// internal virtual methods + +bool AccessibleBrowseBoxBase::implIsShowing() +{ + bool bShowing = false; + if( mxParent.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleComponent > + xParentComp( mxParent->getAccessibleContext(), uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = implGetBoundingBox().Overlaps( + VCLRectangle( xParentComp->getBounds() ) ); + } + return bShowing; +} + +sal_Int64 AccessibleBrowseBoxBase::implCreateStateSet() +{ + sal_Int64 nStateSet = 0; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + nStateSet |= AccessibleStateType::SHOWING; + // BrowseBox fills StateSet with states depending on object type + mpBrowseBox->FillAccessibleStateSet( nStateSet, getType() ); + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; +} + +// internal helper methods + +bool AccessibleBrowseBoxBase::isAlive() const +{ + return !rBHelper.bDisposed && !rBHelper.bInDispose && mpBrowseBox; +} + +void AccessibleBrowseBoxBase::ensureIsAlive() const +{ + if( !isAlive() ) + throw lang::DisposedException(); +} + +tools::Rectangle AccessibleBrowseBoxBase::getBoundingBox() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + tools::Rectangle aRect = implGetBoundingBox(); + if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 ) + { + SAL_WARN( "accessibility", "rectangle doesn't exist" ); + } + return aRect; +} + +AbsoluteScreenPixelRectangle AccessibleBrowseBoxBase::getBoundingBoxOnScreen() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + AbsoluteScreenPixelRectangle aRect = implGetBoundingBoxOnScreen(); + if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 ) + { + SAL_WARN( "accessibility", "rectangle doesn't exist" ); + } + return aRect; +} + +void AccessibleBrowseBoxBase::commitEvent( + sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue ) +{ + osl::MutexGuard aGuard( getMutex() ); + if ( !getClientId( ) ) + // if we don't have a client id for the notifier, then we don't have listeners, then + // we don't need to notify anything + return; + + // build an event object + AccessibleEventObject aEvent(*this, _nEventId, _rNewValue, _rOldValue, -1); + + // let the notifier handle this event + + AccessibleEventNotifier::addEvent( getClientId( ), aEvent ); +} + +sal_Int16 SAL_CALL AccessibleBrowseBoxBase::getAccessibleRole() +{ + osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + sal_Int16 nRole = AccessibleRole::UNKNOWN; + switch ( meObjType ) + { + case AccessibleBrowseBoxObjType::RowHeaderCell: + nRole = AccessibleRole::ROW_HEADER; + break; + case AccessibleBrowseBoxObjType::ColumnHeaderCell: + nRole = AccessibleRole::COLUMN_HEADER; + break; + case AccessibleBrowseBoxObjType::ColumnHeaderBar: + case AccessibleBrowseBoxObjType::RowHeaderBar: + case AccessibleBrowseBoxObjType::Table: + nRole = AccessibleRole::TABLE; + break; + case AccessibleBrowseBoxObjType::TableCell: + nRole = AccessibleRole::TABLE_CELL; + break; + case AccessibleBrowseBoxObjType::BrowseBox: + nRole = AccessibleRole::PANEL; + break; + case AccessibleBrowseBoxObjType::CheckBoxCell: + nRole = AccessibleRole::CHECK_BOX; + break; + } + return nRole; +} + +Reference<XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleAtPoint( const css::awt::Point& ) +{ + return nullptr; +} + +void SAL_CALL AccessibleBrowseBoxBase::disposing( const css::lang::EventObject& ) +{ + m_xFocusWindow = nullptr; +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getForeground( ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Color nColor; + vcl::Window* pInst = mpBrowseBox->GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlForeground() ) + nColor = pInst->GetControlForeground(); + else + { + vcl::Font aFont; + if ( pInst->IsControlFont() ) + aFont = pInst->GetControlFont(); + else + aFont = pInst->GetFont(); + nColor = aFont.GetColor(); + } + } + + return sal_Int32(nColor); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getBackground( ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Color nColor; + vcl::Window* pInst = mpBrowseBox->GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlBackground() ) + nColor = pInst->GetControlBackground(); + else + nColor = pInst->GetBackground().GetColor(); + } + + return sal_Int32(nColor); +} + + +// XInterface +IMPLEMENT_FORWARD_XINTERFACE2( BrowseBoxAccessibleElement, AccessibleBrowseBoxBase, BrowseBoxAccessibleElement_Base ) + +// XTypeProvider +IMPLEMENT_FORWARD_XTYPEPROVIDER2( BrowseBoxAccessibleElement, AccessibleBrowseBoxBase, BrowseBoxAccessibleElement_Base ) + +// css::accessibility::XAccessible + +Reference< css::accessibility::XAccessibleContext > SAL_CALL BrowseBoxAccessibleElement::getAccessibleContext() +{ + osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return this; +} + + +BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, ::vcl::IAccessibleTableProvider& rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType eObjType ) + :AccessibleBrowseBoxBase( rxParent, rBrowseBox, _xFocusWindow, eObjType ) +{ +} + + +BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, ::vcl::IAccessibleTableProvider& rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType eObjType, + const OUString& rName, const OUString& rDescription ) + :AccessibleBrowseBoxBase( rxParent, rBrowseBox, _xFocusWindow, eObjType, rName, rDescription ) +{ +} + + +BrowseBoxAccessibleElement::~BrowseBoxAccessibleElement( ) +{ +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell.cxx new file mode 100644 index 0000000000..e597555556 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxCheckBoxCell.cxx @@ -0,0 +1,162 @@ +/* -*- 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 <extended/AccessibleBrowseBoxCheckBoxCell.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <vcl/accessibletableprovider.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +namespace accessibility +{ + using namespace com::sun::star::accessibility; + using namespace com::sun::star::uno; + using namespace com::sun::star::accessibility::AccessibleEventId; + + AccessibleCheckBoxCell::AccessibleCheckBoxCell(const Reference<XAccessible >& _rxParent, + vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos + ,const TriState& _eState, + bool _bIsTriState) + :AccessibleBrowseBoxCell(_rxParent, _rBrowseBox, _xFocusWindow, _nRowPos, _nColPos, AccessibleBrowseBoxObjType::CheckBoxCell) + ,m_eState(_eState) + ,m_bIsTriState(_bIsTriState) + { + } + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleCheckBoxCell, AccessibleBrowseBoxCell, AccessibleCheckBoxCell_BASE ) + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleCheckBoxCell, AccessibleBrowseBoxCell, AccessibleCheckBoxCell_BASE ) + + Reference< XAccessibleContext > SAL_CALL AccessibleCheckBoxCell::getAccessibleContext( ) + { + osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return this; + } + + sal_Int64 AccessibleCheckBoxCell::implCreateStateSet() + { + sal_Int64 nStateSet = AccessibleBrowseBoxCell::implCreateStateSet(); + if( isAlive() ) + { + nStateSet |= AccessibleStateType::CHECKABLE; + mpBrowseBox->FillAccessibleStateSetForCell( + nStateSet, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + if ( m_eState == TRISTATE_TRUE ) + nStateSet |= AccessibleStateType::CHECKED; + } + return nStateSet; + } + + // XAccessibleValue + + Any SAL_CALL AccessibleCheckBoxCell::getCurrentValue( ) + { + ::osl::MutexGuard aGuard( getMutex() ); + + sal_Int32 nValue = 0; + switch( m_eState ) + { + case TRISTATE_FALSE: + nValue = 0; + break; + case TRISTATE_TRUE: + nValue = 1; + break; + case TRISTATE_INDET: + nValue = 2; + break; + } + return Any(nValue); + } + + sal_Bool SAL_CALL AccessibleCheckBoxCell::setCurrentValue( const Any& ) + { + return false; + } + + Any SAL_CALL AccessibleCheckBoxCell::getMaximumValue( ) + { + ::osl::MutexGuard aGuard( getMutex() ); + + Any aValue; + + if ( m_bIsTriState ) + aValue <<= sal_Int32(2); + else + aValue <<= sal_Int32(1); + + return aValue; + } + + Any SAL_CALL AccessibleCheckBoxCell::getMinimumValue( ) + { + Any aValue; + aValue <<= sal_Int32(0); + + return aValue; + } + + Any SAL_CALL AccessibleCheckBoxCell::getMinimumIncrement( ) + { + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; + } + + // XAccessibleContext + sal_Int64 SAL_CALL AccessibleCheckBoxCell::getAccessibleChildCount( ) + { + return 0; + } + + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL AccessibleCheckBoxCell::getAccessibleChild( sal_Int64 ) + { + throw css::lang::IndexOutOfBoundsException(); + } + + OUString SAL_CALL AccessibleCheckBoxCell::getImplementationName() + { + return "com.sun.star.comp.svtools.TableCheckBoxCell"; + } + + sal_Int64 SAL_CALL AccessibleCheckBoxCell::getAccessibleIndexInParent() + { + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + + return (static_cast<sal_Int64>(getRowPos()) * static_cast<sal_Int64>(mpBrowseBox->GetColumnCount())) + getColumnPos(); + } + + void AccessibleCheckBoxCell::SetChecked( bool _bChecked ) + { + m_eState = _bChecked ? TRISTATE_TRUE : TRISTATE_FALSE; + Any aOldValue, aNewValue; + if ( _bChecked ) + aNewValue <<= AccessibleStateType::CHECKED; + else + aOldValue <<= AccessibleStateType::CHECKED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxHeaderBar.cxx b/accessibility/source/extended/AccessibleBrowseBoxHeaderBar.cxx new file mode 100644 index 0000000000..8bd19f8252 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxHeaderBar.cxx @@ -0,0 +1,363 @@ +/* -*- 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 <extended/AccessibleBrowseBoxHeaderBar.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + + +namespace accessibility { + + +// Ctor/Dtor/disposing -------------------------------------------------------- + +AccessibleBrowseBoxHeaderBar::AccessibleBrowseBoxHeaderBar( + const Reference< XAccessible >& rxParent, + vcl::IAccessibleTableProvider& rBrowseBox, + AccessibleBrowseBoxObjType eObjType ) : + AccessibleBrowseBoxTableBase( rxParent, rBrowseBox,eObjType ) +{ + OSL_ENSURE( isRowBar() || isColumnBar(), + "extended/AccessibleBrowseBoxHeaderBar - invalid object type" ); +} + +AccessibleBrowseBoxHeaderBar::~AccessibleBrowseBoxHeaderBar() +{ +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxHeaderBar::getAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidHeaderIndex( nChildIndex ); + return implGetChild( nChildIndex, implToVCLColumnPos( nChildIndex ) ); +} + +sal_Int64 SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleIndexInParent() +{ + return isRowBar() ? vcl::BBINDEX_ROWHEADERBAR : vcl::BBINDEX_COLUMNHEADERBAR; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxHeaderBar::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + sal_Int32 nRow = 0; + sal_uInt16 nColumnPos = 0; + bool bConverted = isRowBar() ? + mpBrowseBox->ConvertPointToRowHeader( nRow, VCLPoint( rPoint ) ) : + mpBrowseBox->ConvertPointToColumnHeader( nColumnPos, VCLPoint( rPoint ) ); + + return bConverted ? implGetChild( nRow, nColumnPos ) : Reference< XAccessible >(); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::grabFocus() +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + // focus on header not supported +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleRowDescription( sal_Int32 nRow ) +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + ensureIsValidRow( nRow ); + return OUString(); // no headers in headers +} + +OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleColumnDescription( sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return OUString(); // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleRowHeaders() +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + return nullptr; // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleColumnHeaders() +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + return nullptr; // no headers in headers +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleRows() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + // row of column header bar not selectable + if( isRowBar() ) + implGetSelectedRows( aSelSeq ); + return aSelSeq; +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleColumns() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + // column of row header bar ("handle column") not selectable + if( isColumnBar() ) + implGetSelectedColumns( aSelSeq ); + return aSelSeq; +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleRowSelected( sal_Int32 nRow ) +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + ensureIsValidRow( nRow ); + return isRowBar() && implIsRowSelected( nRow ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleColumnSelected( sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return isColumnBar() && implIsColumnSelected( nColumn ); +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + + return implGetChild( nRow, implToVCLColumnPos( nColumn ) ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleSelected( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidAddress( nRow, nColumn ); + return isRowBar() ? implIsRowSelected( nRow ) : implIsColumnSelected( nColumn ); +} + +// XAccessibleSelection ------------------------------------------------------- + +void SAL_CALL AccessibleBrowseBoxHeaderBar::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidHeaderIndex( nChildIndex ); + if( isRowBar() ) + implSelectRow( nChildIndex, true ); + else + implSelectColumn( implToVCLColumnPos( nChildIndex ), true ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + // using interface methods - no mutex + return isRowBar() ? + isAccessibleRowSelected( nChildIndex ) : + isAccessibleColumnSelected( nChildIndex ); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::clearAccessibleSelection() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + mpBrowseBox->SetNoSelection(); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::selectAllAccessibleChildren() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + // no multiselection of columns possible + if( isRowBar() ) + mpBrowseBox->SelectAll(); + else + implSelectColumn( implToVCLColumnPos( 0 ), true ); +} + +sal_Int64 SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleChildCount() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return isRowBar() ? implGetSelectedRowCount() : implGetSelectedColumnCount(); +} + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxHeaderBar::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + // method may throw lang::IndexOutOfBoundsException + sal_Int64 nIndex = implGetChildIndexFromSelectedIndex( nSelectedChildIndex ); + assert(nIndex < std::numeric_limits<sal_Int32>::max()); + return implGetChild( nIndex, implToVCLColumnPos( nIndex ) ); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::deselectAccessibleChild( + sal_Int64 nSelectedChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + // method may throw lang::IndexOutOfBoundsException + if ( isAccessibleChildSelected(nSelectedChildIndex) ) + { + if( isRowBar() ) + implSelectRow( nSelectedChildIndex, false ); + else + implSelectColumn( implToVCLColumnPos( nSelectedChildIndex ), false ); + } +} + +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleBrowseBoxHeaderBar::queryInterface( const uno::Type& rType ) +{ + Any aAny( AccessibleBrowseBoxTableBase::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleBrowseBoxHeaderBarImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::acquire() noexcept +{ + AccessibleBrowseBoxTableBase::acquire(); +} + +void SAL_CALL AccessibleBrowseBoxHeaderBar::release() noexcept +{ + AccessibleBrowseBoxTableBase::release(); +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getImplementationName() +{ + return "com.sun.star.comp.svtools.AccessibleBrowseBoxHeaderBar"; +} + +Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxHeaderBar::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// internal virtual methods --------------------------------------------------- + +tools::Rectangle AccessibleBrowseBoxHeaderBar::implGetBoundingBox() +{ + return mpBrowseBox->calcHeaderRect(isColumnBar(), false); +} + +AbsoluteScreenPixelRectangle AccessibleBrowseBoxHeaderBar::implGetBoundingBoxOnScreen() +{ + return AbsoluteScreenPixelRectangle(mpBrowseBox->calcHeaderRect(isColumnBar())); +} + +sal_Int32 AccessibleBrowseBoxHeaderBar::implGetRowCount() const +{ + // column header bar: only 1 row + return isRowBar() ? AccessibleBrowseBoxTableBase::implGetRowCount() : 1; +} + +sal_Int32 AccessibleBrowseBoxHeaderBar::implGetColumnCount() const +{ + // row header bar ("handle column"): only 1 column + return isColumnBar() ? AccessibleBrowseBoxTableBase::implGetColumnCount() : 1; +} + +// internal helper methods ---------------------------------------------------- + +Reference< XAccessible > AccessibleBrowseBoxHeaderBar::implGetChild( + sal_Int32 nRow, sal_uInt16 nColumnPos ) +{ + return isRowBar() ? + mpBrowseBox->CreateAccessibleRowHeader( nRow ) : + mpBrowseBox->CreateAccessibleColumnHeader( nColumnPos ); +} + +sal_Int64 AccessibleBrowseBoxHeaderBar::implGetChildIndexFromSelectedIndex( + sal_Int64 nSelectedChildIndex ) +{ + Sequence< sal_Int32 > aSelSeq; + if( isRowBar() ) + implGetSelectedRows( aSelSeq ); + else + implGetSelectedColumns( aSelSeq ); + + if( (nSelectedChildIndex < 0) || (nSelectedChildIndex >= aSelSeq.getLength()) ) + throw lang::IndexOutOfBoundsException(); + + return aSelSeq.getConstArray()[ nSelectedChildIndex ]; +} + +void AccessibleBrowseBoxHeaderBar::ensureIsValidHeaderIndex( sal_Int32 nIndex ) +{ + if( isRowBar() ) + ensureIsValidRow( nIndex ); + else + ensureIsValidColumn( nIndex ); +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx new file mode 100644 index 0000000000..536c3d4c25 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxHeaderCell.cxx @@ -0,0 +1,155 @@ +/* -*- 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 <extended/AccessibleBrowseBoxHeaderCell.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +namespace accessibility +{ + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::uno; + +AccessibleBrowseBoxHeaderCell::AccessibleBrowseBoxHeaderCell(sal_Int32 _nColumnRowId, + const Reference< XAccessible >& rxParent, + vcl::IAccessibleTableProvider& rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType eObjType) +: BrowseBoxAccessibleElement(rxParent, + rBrowseBox, + _xFocusWindow, + eObjType, + rBrowseBox.GetAccessibleObjectName( eObjType ,_nColumnRowId), + rBrowseBox.GetAccessibleObjectDescription( eObjType ,_nColumnRowId)) +, m_nColumnRowId(_nColumnRowId) +{ +} +/** Return a bitset of states of the current object. +*/ +sal_Int64 AccessibleBrowseBoxHeaderCell::implCreateStateSet() +{ + SolarMethodGuard aGuard( getMutex() ); + + sal_Int64 nStateSet = 0; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + nStateSet |= AccessibleStateType::SHOWING; + + mpBrowseBox->FillAccessibleStateSet( nStateSet, getType() ); + nStateSet |= AccessibleStateType::VISIBLE; + nStateSet |= AccessibleStateType::FOCUSABLE; + nStateSet |= AccessibleStateType::TRANSIENT; + nStateSet |= AccessibleStateType::SELECTABLE; + + bool bSelected = isRowBarCell() ? mpBrowseBox->IsRowSelected(m_nColumnRowId) : mpBrowseBox->IsColumnSelected(m_nColumnRowId); + if ( bSelected ) + nStateSet |= AccessibleStateType::SELECTED; + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; +} + +/** @return + The count of visible children. +*/ +sal_Int64 SAL_CALL AccessibleBrowseBoxHeaderCell::getAccessibleChildCount() +{ + return 0; +} + + +/** @return + The XAccessible interface of the specified child. +*/ +Reference<XAccessible > SAL_CALL AccessibleBrowseBoxHeaderCell::getAccessibleChild( sal_Int64 ) +{ + throw IndexOutOfBoundsException(); +} + + +/** Grabs the focus to the column header. */ +void SAL_CALL AccessibleBrowseBoxHeaderCell::grabFocus() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + if ( isRowBarCell() ) + mpBrowseBox->SelectRow(m_nColumnRowId); + else + mpBrowseBox->SelectColumn(static_cast<sal_uInt16>(m_nColumnRowId)); //!!! +} + +/** @return + The name of this class. +*/ +OUString SAL_CALL AccessibleBrowseBoxHeaderCell::getImplementationName() +{ + return "com.sun.star.comp.svtools.AccessibleBrowseBoxHeaderCell"; +} + +namespace +{ + tools::Rectangle getRectangle(vcl::IAccessibleTableProvider* _pBrowseBox,sal_Int32 _nRowColIndex, bool _bOnScreen,bool _bRowBar) + { + sal_Int32 nRow = 0; + sal_uInt16 nCol = static_cast<sal_uInt16>(_nRowColIndex); + if ( _bRowBar ) + { + nRow = _nRowColIndex + 1; + nCol = 0; + } + + tools::Rectangle aRet(_pBrowseBox->GetFieldRectPixel( nRow , nCol, true, _bOnScreen)); + return tools::Rectangle(aRet.TopLeft() - Point(0,aRet.GetHeight()),aRet.GetSize()); + } +} + +tools::Rectangle AccessibleBrowseBoxHeaderCell::implGetBoundingBox() +{ + return getRectangle(mpBrowseBox,m_nColumnRowId,false,isRowBarCell()); +} + + +AbsoluteScreenPixelRectangle AccessibleBrowseBoxHeaderCell::implGetBoundingBoxOnScreen() +{ + return AbsoluteScreenPixelRectangle(getRectangle(mpBrowseBox,m_nColumnRowId,true,isRowBarCell())); +} + +sal_Int64 SAL_CALL AccessibleBrowseBoxHeaderCell::getAccessibleIndexInParent() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + sal_Int64 nIndex = m_nColumnRowId; + if ( mpBrowseBox->HasRowHeader() ) + --nIndex; + return nIndex; +} + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxTable.cxx b/accessibility/source/extended/AccessibleBrowseBoxTable.cxx new file mode 100644 index 0000000000..09c7448be4 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxTable.cxx @@ -0,0 +1,234 @@ +/* -*- 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 <extended/AccessibleBrowseBoxTable.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + + +namespace accessibility { + + +// Ctor/Dtor/disposing -------------------------------------------------------- + +AccessibleBrowseBoxTable::AccessibleBrowseBoxTable( + const Reference< XAccessible >& rxParent, + vcl::IAccessibleTableProvider& rBrowseBox ) : + AccessibleBrowseBoxTableBase( rxParent, rBrowseBox, AccessibleBrowseBoxObjType::Table ) +{ +} + +AccessibleBrowseBoxTable::~AccessibleBrowseBoxTable() +{ +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxTable::getAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidIndex( nChildIndex ); + return mpBrowseBox->CreateAccessibleCell( + implGetRow( nChildIndex ), static_cast<sal_Int16>(implGetColumn( nChildIndex )) ); +} + +sal_Int64 SAL_CALL AccessibleBrowseBoxTable::getAccessibleIndexInParent() +{ + osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return vcl::BBINDEX_TABLE; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleBrowseBoxTable::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Reference< XAccessible > xChild; + sal_Int32 nRow = 0; + sal_uInt16 nColumnPos = 0; + if( mpBrowseBox->ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) ) + xChild = mpBrowseBox->CreateAccessibleCell( nRow, nColumnPos ); + + return xChild; +} + +void SAL_CALL AccessibleBrowseBoxTable::grabFocus() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + mpBrowseBox->GrabTableFocus(); +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxTable::getAccessibleRowDescription( sal_Int32 nRow ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + ensureIsValidRow( nRow ); + return mpBrowseBox->GetRowDescription( nRow ); +} + +OUString SAL_CALL AccessibleBrowseBoxTable::getAccessibleColumnDescription( sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidColumn( nColumn ); + return mpBrowseBox->GetColumnDescription( static_cast<sal_uInt16>(nColumn) ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxTable::getAccessibleRowHeaders() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return implGetHeaderBar( vcl::BBINDEX_ROWHEADERBAR ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxTable::getAccessibleColumnHeaders() +{ + ::osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return implGetHeaderBar( vcl::BBINDEX_COLUMNHEADERBAR ); +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxTable::getSelectedAccessibleRows() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + implGetSelectedRows( aSelSeq ); + return aSelSeq; +} + +Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxTable::getSelectedAccessibleColumns() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + Sequence< sal_Int32 > aSelSeq; + implGetSelectedColumns( aSelSeq ); + return aSelSeq; +} + +sal_Bool SAL_CALL AccessibleBrowseBoxTable::isAccessibleRowSelected( sal_Int32 nRow ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidRow( nRow ); + return implIsRowSelected( nRow ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxTable::isAccessibleColumnSelected( sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidColumn( nColumn ); + return implIsColumnSelected( nColumn ); +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxTable::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidAddress( nRow, nColumn ); + return mpBrowseBox->CreateAccessibleCell( nRow, static_cast<sal_Int16>(nColumn) ); +} + +sal_Bool SAL_CALL AccessibleBrowseBoxTable::isAccessibleSelected( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + ensureIsValidAddress( nRow, nColumn ); + return implIsRowSelected( nRow ) || implIsColumnSelected( nColumn ); +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleBrowseBoxTable::getImplementationName() +{ + return "com.sun.star.comp.svtools.AccessibleBrowseBoxTable"; +} + +// internal virtual methods --------------------------------------------------- + +tools::Rectangle AccessibleBrowseBoxTable::implGetBoundingBox() +{ + return mpBrowseBox->calcTableRect(false); +} + +AbsoluteScreenPixelRectangle AccessibleBrowseBoxTable::implGetBoundingBoxOnScreen() +{ + return AbsoluteScreenPixelRectangle(mpBrowseBox->calcTableRect()); +} + +// internal helper methods ---------------------------------------------------- + +Reference< XAccessibleTable > AccessibleBrowseBoxTable::implGetHeaderBar( + sal_Int32 nChildIndex ) +{ + assert(nChildIndex == vcl::BBINDEX_ROWHEADERBAR || nChildIndex == vcl::BBINDEX_COLUMNHEADERBAR); + + Reference< XAccessible > xRet; + Reference< XAccessibleContext > xContext( mxParent, uno::UNO_QUERY ); + if( xContext.is() ) + { + if (nChildIndex == vcl::BBINDEX_COLUMNHEADERBAR || mpBrowseBox->HasRowHeader()) + { + try + { + xRet = xContext->getAccessibleChild( nChildIndex ); + } + catch (const lang::IndexOutOfBoundsException&) + { + OSL_FAIL( "implGetHeaderBar - wrong child index" ); + } + // RuntimeException goes to caller + } + } + return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY ); +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxTableBase.cxx b/accessibility/source/extended/AccessibleBrowseBoxTableBase.cxx new file mode 100644 index 0000000000..a1ae5a969d --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxTableBase.cxx @@ -0,0 +1,292 @@ +/* -*- 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 <extended/AccessibleBrowseBoxTableBase.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <comphelper/sequence.hxx> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + + +using css::uno::Reference; +using css::uno::Sequence; +using css::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + + +namespace accessibility { + + +// Ctor/Dtor/disposing -------------------------------------------------------- + +AccessibleBrowseBoxTableBase::AccessibleBrowseBoxTableBase( + const Reference< XAccessible >& rxParent, + vcl::IAccessibleTableProvider& rBrowseBox, + AccessibleBrowseBoxObjType eObjType ) : + BrowseBoxAccessibleElement( rxParent, rBrowseBox,nullptr, eObjType ) +{ +} + +// XAccessibleContext --------------------------------------------------------- + +sal_Int64 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleChildCount() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + return implGetChildCount(); +} + +sal_Int16 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRole() +{ + osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return AccessibleRole::TABLE; +} + +// XAccessibleTable ----------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRowCount() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + return implGetRowCount(); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleColumnCount() +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + return implGetColumnCount(); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRowExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleColumnExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleCaption() +{ + ensureIsAlive(); + return nullptr; // not supported +} + +Reference< XAccessible > SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleSummary() +{ + ensureIsAlive(); + return nullptr; // not supported +} + +sal_Int64 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleIndex( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(implGetColumnCount()) + nColumn; +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleRow( sal_Int64 nChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetRow( nChildIndex ); +} + +sal_Int32 SAL_CALL AccessibleBrowseBoxTableBase::getAccessibleColumn( sal_Int64 nChildIndex ) +{ + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetColumn( nChildIndex ); +} + +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleBrowseBoxTableBase::queryInterface( const uno::Type& rType ) +{ + Any aAny( BrowseBoxAccessibleElement::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleBrowseBoxTableImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleBrowseBoxTableBase::acquire() noexcept +{ + BrowseBoxAccessibleElement::acquire(); +} + +void SAL_CALL AccessibleBrowseBoxTableBase::release() noexcept +{ + BrowseBoxAccessibleElement::release(); +} + +// XTypeProvider -------------------------------------------------------------- + +Sequence< uno::Type > SAL_CALL AccessibleBrowseBoxTableBase::getTypes() +{ + return ::comphelper::concatSequences( + BrowseBoxAccessibleElement::getTypes(), + AccessibleBrowseBoxTableImplHelper::getTypes() ); +} + +Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxTableBase::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// internal virtual methods --------------------------------------------------- + +sal_Int32 AccessibleBrowseBoxTableBase::implGetRowCount() const +{ + return mpBrowseBox->GetRowCount(); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetColumnCount() const +{ + sal_uInt16 nColumns = mpBrowseBox->GetColumnCount(); + // do not count the "handle column" + if( nColumns && implHasHandleColumn() ) + --nColumns; + return nColumns; +} + +// internal helper methods ---------------------------------------------------- + +bool AccessibleBrowseBoxTableBase::implHasHandleColumn() const +{ + return mpBrowseBox->HasRowHeader(); +} + +sal_uInt16 AccessibleBrowseBoxTableBase::implToVCLColumnPos( sal_Int32 nColumn ) const +{ + sal_uInt16 nVCLPos = 0; + if( (0 <= nColumn) && (nColumn < implGetColumnCount()) ) + { + // regard "handle column" + if( implHasHandleColumn() ) + ++nColumn; + nVCLPos = static_cast< sal_uInt16 >( nColumn ); + } + return nVCLPos; +} + +sal_Int64 AccessibleBrowseBoxTableBase::implGetChildCount() const +{ + return static_cast<sal_Int64>(implGetRowCount()) * static_cast<sal_Int64>(implGetColumnCount()); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetRow( sal_Int64 nChildIndex ) const +{ + sal_Int32 nColumns = implGetColumnCount(); + return nColumns ? (nChildIndex / nColumns) : 0; +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetColumn( sal_Int64 nChildIndex ) const +{ + sal_Int32 nColumns = implGetColumnCount(); + return nColumns ? (nChildIndex % nColumns) : 0; +} + +bool AccessibleBrowseBoxTableBase::implIsRowSelected( sal_Int32 nRow ) const +{ + return mpBrowseBox->IsRowSelected( nRow ); +} + +bool AccessibleBrowseBoxTableBase::implIsColumnSelected( sal_Int32 nColumn ) const +{ + if( implHasHandleColumn() ) + --nColumn; + return mpBrowseBox->IsColumnSelected( nColumn ); +} + +void AccessibleBrowseBoxTableBase::implSelectRow( sal_Int32 nRow, bool bSelect ) +{ + mpBrowseBox->SelectRow( nRow, bSelect ); +} + +void AccessibleBrowseBoxTableBase::implSelectColumn( sal_Int32 nColumnPos, bool bSelect ) +{ + mpBrowseBox->SelectColumn( static_cast<sal_uInt16>(nColumnPos), bSelect ); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetSelectedRowCount() const +{ + return mpBrowseBox->GetSelectedRowCount(); +} + +sal_Int32 AccessibleBrowseBoxTableBase::implGetSelectedColumnCount() const +{ + return mpBrowseBox->GetSelectedColumnCount(); +} + +void AccessibleBrowseBoxTableBase::implGetSelectedRows( Sequence< sal_Int32 >& rSeq ) +{ + mpBrowseBox->GetAllSelectedRows( rSeq ); +} + +void AccessibleBrowseBoxTableBase::implGetSelectedColumns( Sequence< sal_Int32 >& rSeq ) +{ + mpBrowseBox->GetAllSelectedColumns( rSeq ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidRow( sal_Int32 nRow ) +{ + if( nRow >= implGetRowCount() ) + throw lang::IndexOutOfBoundsException( "row index is invalid", *this ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidColumn( sal_Int32 nColumn ) +{ + if( nColumn >= implGetColumnCount() ) + throw lang::IndexOutOfBoundsException( "column index is invalid", *this ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidAddress( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + ensureIsValidRow( nRow ); + ensureIsValidColumn( nColumn ); +} + +void AccessibleBrowseBoxTableBase::ensureIsValidIndex( sal_Int64 nChildIndex ) +{ + if( nChildIndex >= implGetChildCount() ) + throw lang::IndexOutOfBoundsException( "child index is invalid", *this ); +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleBrowseBoxTableCell.cxx b/accessibility/source/extended/AccessibleBrowseBoxTableCell.cxx new file mode 100644 index 0000000000..12571484e6 --- /dev/null +++ b/accessibility/source/extended/AccessibleBrowseBoxTableCell.cxx @@ -0,0 +1,334 @@ +/* -*- 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 <extended/AccessibleBrowseBoxTableCell.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/accessibletableprovider.hxx> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +namespace accessibility +{ + namespace + { + /// @throws css::lang::IndexOutOfBoundsException + void checkIndex_Impl( sal_Int32 _nIndex, std::u16string_view _sText ) + { + if ( _nIndex >= static_cast<sal_Int32>(_sText.size()) ) + throw css::lang::IndexOutOfBoundsException(); + } + + sal_Int32 getIndex_Impl( sal_Int32 _nRow, sal_uInt16 _nColumn, sal_uInt16 _nColumnCount ) + { + return _nRow * _nColumnCount + _nColumn; + } + } + using namespace ::com::sun::star::lang; + using namespace comphelper; + using namespace ::com::sun::star::uno; + using ::com::sun::star::accessibility::XAccessible; + using namespace ::com::sun::star::accessibility; + + + // implementation of a table cell + OUString AccessibleBrowseBoxTableCell::implGetText() + { + return mpBrowseBox->GetAccessibleCellText( getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + } + + css::lang::Locale AccessibleBrowseBoxTableCell::implGetLocale() + { + return mpBrowseBox->GetAccessible()->getAccessibleContext()->getLocale(); + } + + void AccessibleBrowseBoxTableCell::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + + AccessibleBrowseBoxTableCell::AccessibleBrowseBoxTableCell(const Reference<XAccessible >& _rxParent, + vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + sal_Int32 _nOffset ) + :AccessibleBrowseBoxCell( _rxParent, _rBrowseBox, _xFocusWindow, _nRowPos, _nColPos ) + { + m_nOffset = ( _nOffset == OFFSET_DEFAULT ) ? sal_Int32(vcl::BBINDEX_FIRSTCONTROL) : _nOffset; + sal_Int32 nIndex = getIndex_Impl( _nRowPos, _nColPos, _rBrowseBox.GetColumnCount() ); + setAccessibleName( _rBrowseBox.GetAccessibleObjectName( AccessibleBrowseBoxObjType::TableCell, nIndex ) ); + setAccessibleDescription( _rBrowseBox.GetAccessibleObjectDescription( AccessibleBrowseBoxObjType::TableCell, nIndex ) ); + // Need to register as event listener + Reference< XComponent > xComponent(_rxParent, UNO_QUERY); + if( xComponent.is() ) + xComponent->addEventListener(static_cast< XEventListener *> (this)); + } + + // XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL AccessibleBrowseBoxTableCell::queryInterface( const css::uno::Type& rType ) + { + Any aRet = AccessibleBrowseBoxCell::queryInterface(rType); + if ( !aRet.hasValue() ) + aRet = AccessibleTextHelper_BASE::queryInterface(rType); + return aRet; + } + + /** Acquires the object (calls acquire() on base class). */ + void SAL_CALL AccessibleBrowseBoxTableCell::acquire() noexcept + { + AccessibleBrowseBoxCell::acquire(); + } + + /** Releases the object (calls release() on base class). */ + void SAL_CALL AccessibleBrowseBoxTableCell::release() noexcept + { + AccessibleBrowseBoxCell::release(); + } + + css::awt::Rectangle SAL_CALL AccessibleBrowseBoxTableCell::getCharacterBounds( sal_Int32 nIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + css::awt::Rectangle aRect; + + if ( mpBrowseBox ) + { + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + aRect = AWTRectangle( mpBrowseBox->GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) ); + } + + return aRect; + } + + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getIndexAtPoint( const css::awt::Point& _aPoint ) + { + //! TODO CTL bidi + // OSL_FAIL("Need to be done by base class!"); + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return mpBrowseBox->GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) ); + } + + /** @return + The name of this class. + */ + OUString SAL_CALL AccessibleBrowseBoxTableCell::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleBrowseBoxTableCell"; + } + + /** @return The count of visible children. */ + sal_Int64 SAL_CALL AccessibleBrowseBoxTableCell::getAccessibleChildCount() + { + return 0; + } + + /** @return The XAccessible interface of the specified child. */ + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL + AccessibleBrowseBoxTableCell::getAccessibleChild( sal_Int64 ) + { + throw css::lang::IndexOutOfBoundsException(); + } + + /** Return a bitset of states of the current object. + */ + sal_Int64 AccessibleBrowseBoxTableCell::implCreateStateSet() + { + SolarMethodGuard aGuard(getMutex()); + + sal_Int64 nStateSet = 0; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + nStateSet |= AccessibleStateType::SHOWING; + + mpBrowseBox->FillAccessibleStateSetForCell( nStateSet, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; + } + + + // XAccessible ------------------------------------------------------------ + + /** @return The XAccessibleContext interface of this object. */ + Reference< XAccessibleContext > SAL_CALL AccessibleBrowseBoxTableCell::getAccessibleContext() + { + osl::MutexGuard aGuard( getMutex() ); + ensureIsAlive(); + return this; + } + + // XAccessibleContext ----------------------------------------------------- + + sal_Int64 SAL_CALL AccessibleBrowseBoxTableCell::getAccessibleIndexInParent() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return /*vcl::BBINDEX_FIRSTCONTROL*/ m_nOffset + (static_cast<sal_Int64>(getRowPos()) * static_cast<sal_Int64>(mpBrowseBox->GetColumnCount())) + getColumnPos(); + } + + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getCaretPosition( ) + { + return -1; + } + + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::setCaretPosition ( sal_Int32 nIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + sal_Unicode SAL_CALL AccessibleBrowseBoxTableCell::getCharacter( sal_Int32 nIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); + } + css::uno::Sequence< css::beans::PropertyValue > SAL_CALL AccessibleBrowseBoxTableCell::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return css::uno::Sequence< css::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getCharacterCount( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return implGetText().getLength(); + } + + OUString SAL_CALL AccessibleBrowseBoxTableCell::getSelectedText( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::getSelectedText( ); + } + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getSelectionStart( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::getSelectionStart( ); + } + sal_Int32 SAL_CALL AccessibleBrowseBoxTableCell::getSelectionEnd( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::getSelectionEnd( ); + } + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + OUString SAL_CALL AccessibleBrowseBoxTableCell::getText( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return implGetText( ); + } + OUString SAL_CALL AccessibleBrowseBoxTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ); + } + css::accessibility::TextSegment SAL_CALL AccessibleBrowseBoxTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleBrowseBoxTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleBrowseBoxTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + OUString sText = implGetText(); + checkIndex_Impl( nStartIndex, sText ); + checkIndex_Impl( nEndIndex, sText ); + + //!!! don't know how to put a string into the clipboard + return false; + } + sal_Bool SAL_CALL AccessibleBrowseBoxTableCell::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) + { + return false; + } + void AccessibleBrowseBoxTableCell::disposing( const EventObject& _rSource ) + { + if ( _rSource.Source == mxParent ) + { + dispose(); + } + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControl.cxx b/accessibility/source/extended/AccessibleGridControl.cxx new file mode 100644 index 0000000000..00c982a943 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControl.cxx @@ -0,0 +1,356 @@ +/* -*- 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 <extended/AccessibleGridControl.hxx> +#include <extended/AccessibleGridControlTable.hxx> +#include <extended/AccessibleGridControlHeader.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <toolkit/helper/convert.hxx> +#include <utility> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> + +namespace accessibility +{ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::vcl; +using namespace ::vcl::table; + +AccessibleGridControl::AccessibleGridControl( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator, + ::vcl::table::IAccessibleTable& _rTable ) + : AccessibleGridControlBase(_rxParent, _rTable, AccessibleTableControlObjType::GRIDCONTROL), + m_aCreator(_rxCreator) +{ +} + + +void SAL_CALL AccessibleGridControl::disposing() +{ + SolarMutexGuard g; + + m_aCreator.clear(); + + if ( m_xTable.is() ) + { + m_xTable->dispose(); + m_xTable.clear(); + } + if ( m_xRowHeaderBar.is() ) + { + m_xRowHeaderBar->dispose(); + m_xRowHeaderBar.clear(); + } + if ( m_xColumnHeaderBar.is() ) + { + m_xColumnHeaderBar->dispose(); + m_xColumnHeaderBar.clear(); + } + AccessibleGridControlBase::disposing(); +} + +sal_Int64 AccessibleGridControl::implGetAccessibleChildCount() +{ + return m_aTable.GetAccessibleControlCount(); +} + +// css::accessibility::XAccessibleContext --------------------------------------------------------- + + +sal_Int64 SAL_CALL AccessibleGridControl::getAccessibleChildCount() +{ + SolarMutexGuard aSolarGuard; + ensureIsAlive(); + return implGetAccessibleChildCount(); +} + + +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +AccessibleGridControl::getAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + if (nChildIndex<0 || nChildIndex>=implGetAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + css::uno::Reference< css::accessibility::XAccessible > xChild; + if (isAlive()) + { + if(nChildIndex == 0 && m_aTable.HasColHeader()) + { + if(!m_xColumnHeaderBar.is()) + { + m_xColumnHeaderBar = new AccessibleGridControlHeader(m_aCreator, m_aTable, + vcl::table::AccessibleTableControlObjType::COLUMNHEADERBAR); + } + xChild = m_xColumnHeaderBar.get(); + } + else if(m_aTable.HasRowHeader() && (nChildIndex == 1 || nChildIndex == 0)) + { + if(!m_xRowHeaderBar.is()) + { + m_xRowHeaderBar = new AccessibleGridControlHeader(m_aCreator, m_aTable, + vcl::table::AccessibleTableControlObjType::ROWHEADERBAR); + } + xChild = m_xRowHeaderBar.get(); + } + else + { + if(!m_xTable.is()) + { + m_xTable = new AccessibleGridControlTable(m_aCreator, m_aTable); + } + xChild = m_xTable.get(); + } + } + return xChild; +} + + +sal_Int16 SAL_CALL AccessibleGridControl::getAccessibleRole() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return AccessibleRole::PANEL; +} + + +// css::accessibility::XAccessibleComponent ------------------------------------------------------- + +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +AccessibleGridControl::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + SolarMutexGuard aSolarGuard; + ensureIsAlive(); + + css::uno::Reference< css::accessibility::XAccessible > xChild; + sal_Int32 nIndex = 0; + if( m_aTable.ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) ) + xChild = m_aTable.CreateAccessibleControl( nIndex ); + else + { + // try whether point is in one of the fixed children + // (table, header bars, corner control) + Point aPoint( VCLPoint( rPoint ) ); + for( nIndex = 0; (nIndex < 3) && !xChild.is(); ++nIndex ) + { + css::uno::Reference< css::accessibility::XAccessible > xCurrChild( implGetFixedChild( nIndex ) ); + css::uno::Reference< css::accessibility::XAccessibleComponent > + xCurrChildComp( xCurrChild, uno::UNO_QUERY ); + + if( xCurrChildComp.is() && + VCLRectangle( xCurrChildComp->getBounds() ).Contains( aPoint ) ) + xChild = xCurrChild; + } + } + return xChild; +} + + +void SAL_CALL AccessibleGridControl::grabFocus() +{ + SolarMutexGuard aSolarGuard; + ensureIsAlive(); + m_aTable.GrabFocus(); +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControl::getImplementationName() +{ + return "com.sun.star.accessibility.AccessibleGridControl"; +} + + +// internal virtual methods --------------------------------------------------- + +tools::Rectangle AccessibleGridControl::implGetBoundingBox() +{ + vcl::Window* pParent = m_aTable.GetAccessibleParentWindow(); + OSL_ENSURE( pParent, "implGetBoundingBox - missing parent window" ); + return m_aTable.GetWindowExtentsRelative( *pParent ); +} + + +AbsoluteScreenPixelRectangle AccessibleGridControl::implGetBoundingBoxOnScreen() +{ + return m_aTable.GetWindowExtentsAbsolute(); +} +// internal helper methods ---------------------------------------------------- + +css::uno::Reference< css::accessibility::XAccessible > AccessibleGridControl::implGetTable() +{ + if( !m_xTable.is() ) + { + m_xTable = createAccessibleTable(); + } + return m_xTable; +} + + +css::uno::Reference< css::accessibility::XAccessible > +AccessibleGridControl::implGetHeaderBar( AccessibleTableControlObjType eObjType ) +{ + css::uno::Reference< css::accessibility::XAccessible > xRet; + rtl::Reference< AccessibleGridControlHeader >* pxMember = nullptr; + + if (eObjType == AccessibleTableControlObjType::ROWHEADERBAR) + pxMember = &m_xRowHeaderBar; + else if (eObjType == AccessibleTableControlObjType::COLUMNHEADERBAR) + pxMember = &m_xColumnHeaderBar; + + if( pxMember ) + { + if( !pxMember->is() ) + { + *pxMember = new AccessibleGridControlHeader( + m_aCreator, m_aTable, eObjType ); + } + xRet = pxMember->get(); + } + return xRet; +} + +css::uno::Reference< css::accessibility::XAccessible > +AccessibleGridControl::implGetFixedChild( sal_Int64 nChildIndex ) +{ + css::uno::Reference< css::accessibility::XAccessible > xRet; + switch( nChildIndex ) + { + /** Child index of the column header bar (first row). */ + case 0: + xRet = implGetHeaderBar(AccessibleTableControlObjType::COLUMNHEADERBAR); + break; + /** Child index of the row header bar ("handle column"). */ + case 1: + xRet = implGetHeaderBar(AccessibleTableControlObjType::ROWHEADERBAR); + break; + /** Child index of the data table. */ + case 2: + xRet = implGetTable(); + break; + } + return xRet; +} + +rtl::Reference<AccessibleGridControlTable> AccessibleGridControl::createAccessibleTable() +{ + css::uno::Reference< css::accessibility::XAccessible > xCreator(m_aCreator); + OSL_ENSURE( xCreator.is(), "extended/AccessibleGridControl::createAccessibleTable: my creator died - how this?" ); + return new AccessibleGridControlTable( xCreator, m_aTable ); +} + +void AccessibleGridControl::commitCellEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue) +{ + sal_Int64 nChildCount = implGetAccessibleChildCount(); + if(nChildCount != 0) + { + for(sal_Int64 i=0;i<nChildCount;i++) + { + css::uno::Reference< css::accessibility::XAccessible > xAccessible = getAccessibleChild(i); + if(css::uno::Reference< css::accessibility::XAccessible >(m_xTable) == xAccessible) + { + Reference<XAccessible> xCell = m_xTable->getAccessibleCellAt( + m_aTable.GetCurrentRow(), m_aTable.GetCurrentColumn()); + AccessibleGridControlTableCell* pCell = static_cast<AccessibleGridControlTableCell*>(xCell.get()); + pCell->commitEvent(_nEventId, _rNewValue, _rOldValue); + } + } + } + else + { + if ( m_xTable.is() ) + m_xTable->commitEvent(_nEventId,_rNewValue,_rOldValue); + } +} + +void AccessibleGridControl::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue) +{ + if ( !m_xTable.is() ) + return; + + if(_nEventId == AccessibleEventId::ACTIVE_DESCENDANT_CHANGED) + { + const sal_Int32 nCurrentRow = m_aTable.GetCurrentRow(); + const sal_Int32 nCurrentCol = m_aTable.GetCurrentColumn(); + css::uno::Reference< css::accessibility::XAccessible > xChild; + if (nCurrentRow > -1 && nCurrentCol > -1) + xChild = m_xTable->getAccessibleCellAt(nCurrentRow, nCurrentCol); + + m_xTable->commitEvent(_nEventId, Any(xChild),_rOldValue); + } + else + m_xTable->commitEvent(_nEventId,_rNewValue,_rOldValue); +} + +// = AccessibleGridControlAccess + + +AccessibleGridControlAccess::AccessibleGridControlAccess( + css::uno::Reference< css::accessibility::XAccessible > xParent, ::vcl::table::IAccessibleTable& rTable ) + : m_xParent(std::move( xParent )) + , m_pTable( & rTable ) +{ +} + + +AccessibleGridControlAccess::~AccessibleGridControlAccess() +{ +} + + +void AccessibleGridControlAccess::DisposeAccessImpl() +{ + SolarMutexGuard g; + + m_pTable = nullptr; + if (m_xContext.is()) + { + m_xContext->dispose(); + m_xContext.clear(); + } +} + + +css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL AccessibleGridControlAccess::getAccessibleContext() +{ + SolarMutexGuard g; + + // if the context died meanwhile (we're no listener, so it won't tell us explicitly when this happens), + // then reset and re-create. + if ( m_xContext.is() && !m_xContext->isAlive() ) + m_xContext = nullptr; + + if (!m_xContext.is() && m_pTable) + m_xContext = new AccessibleGridControl(m_xParent, this, *m_pTable); + + return m_xContext; +} + + +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControlBase.cxx b/accessibility/source/extended/AccessibleGridControlBase.cxx new file mode 100644 index 0000000000..2547582050 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlBase.cxx @@ -0,0 +1,460 @@ +/* -*- 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 <extended/AccessibleGridControlBase.hxx> +#include <toolkit/helper/convert.hxx> +#include <utility> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <sal/types.h> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp> +#include <unotools/accessiblerelationsethelper.hxx> +#include <sal/log.hxx> + +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; +using namespace ::vcl; +using namespace ::vcl::table; + + +namespace accessibility { + +using namespace com::sun::star::accessibility::AccessibleStateType; + + +AccessibleGridControlBase::AccessibleGridControlBase( + css::uno::Reference< css::accessibility::XAccessible > xParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType ) : + AccessibleGridControlImplHelper( m_aMutex ), + m_xParent(std::move( xParent )), + m_aTable( rTable), + m_eObjType( eObjType ), + m_aClientId(0) +{ +} + +AccessibleGridControlBase::~AccessibleGridControlBase() +{ + if( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } +} + +void SAL_CALL AccessibleGridControlBase::disposing() +{ + SolarMutexGuard g; + + if ( getClientId( ) ) + { + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + m_xParent = nullptr; + //m_aTable = NULL; +} + +// css::accessibility::XAccessibleContext + +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL AccessibleGridControlBase::getAccessibleParent() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return m_xParent; +} + +sal_Int64 SAL_CALL AccessibleGridControlBase::getAccessibleIndexInParent() +{ + SolarMutexGuard g; + + ensureIsAlive(); + + // -1 for child not found/no parent (according to specification) + sal_Int64 nRet = -1; + + css::uno::Reference< uno::XInterface > xMeMyselfAndI( static_cast< css::accessibility::XAccessibleContext* >( this ), uno::UNO_QUERY ); + + // iterate over parent's children and search for this object + if( m_xParent.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > + xParentContext( m_xParent->getAccessibleContext() ); + if( xParentContext.is() ) + { + css::uno::Reference< uno::XInterface > xChild; + + sal_Int64 nChildCount = xParentContext->getAccessibleChildCount(); + for( sal_Int64 nChild = 0; nChild < nChildCount; ++nChild ) + { + xChild.set(xParentContext->getAccessibleChild( nChild ), css::uno::UNO_QUERY); + if ( xMeMyselfAndI.get() == xChild.get() ) + { + nRet = nChild; + break; + } + } + } + } + return nRet; +} + +OUString SAL_CALL AccessibleGridControlBase::getAccessibleDescription() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return m_aTable.GetAccessibleObjectDescription(m_eObjType); +} + +OUString SAL_CALL AccessibleGridControlBase::getAccessibleName() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return m_aTable.GetAccessibleObjectName(m_eObjType, 0, 0); +} + +css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL +AccessibleGridControlBase::getAccessibleRelationSet() +{ + SolarMutexGuard g; + + ensureIsAlive(); + // GridControl does not have relations. + return new utl::AccessibleRelationSetHelper; +} + +sal_Int64 SAL_CALL +AccessibleGridControlBase::getAccessibleStateSet() +{ + SolarMutexGuard aSolarGuard; + + // don't check whether alive -> StateSet may contain DEFUNC + return implCreateStateSet(); +} + +lang::Locale SAL_CALL AccessibleGridControlBase::getLocale() +{ + SolarMutexGuard g; + + ensureIsAlive(); + if( m_xParent.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > + xParentContext( m_xParent->getAccessibleContext() ); + if( xParentContext.is() ) + return xParentContext->getLocale(); + } + throw IllegalAccessibleComponentStateException(); +} + +// css::accessibility::XAccessibleComponent + +sal_Bool SAL_CALL AccessibleGridControlBase::containsPoint( const awt::Point& rPoint ) +{ + return tools::Rectangle( Point(), getBoundingBox().GetSize() ).Contains( VCLPoint( rPoint ) ); +} + +awt::Rectangle SAL_CALL AccessibleGridControlBase::getBounds() +{ + return AWTRectangle( getBoundingBox() ); +} + +awt::Point SAL_CALL AccessibleGridControlBase::getLocation() +{ + return AWTPoint( getBoundingBox().TopLeft() ); +} + +awt::Point SAL_CALL AccessibleGridControlBase::getLocationOnScreen() +{ + return AWTPoint( getBoundingBoxOnScreen().TopLeft() ); +} + +awt::Size SAL_CALL AccessibleGridControlBase::getSize() +{ + return AWTSize( getBoundingBox().GetSize() ); +} + +// css::accessibility::XAccessibleEventBroadcaster + +void SAL_CALL AccessibleGridControlBase::addAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener ) +{ + if ( _rxListener.is() ) + { + SolarMutexGuard g; + + if ( !getClientId( ) ) + setClientId( AccessibleEventNotifier::registerClient( ) ); + + AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener ); + } +} + +void SAL_CALL AccessibleGridControlBase::removeAccessibleEventListener( + const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener ) +{ + if( !(_rxListener.is() && getClientId( )) ) + return; + + SolarMutexGuard g; + + sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + AccessibleEventNotifier::TClientId nId( getClientId( ) ); + setClientId( 0 ); + AccessibleEventNotifier::revokeClient( nId ); + } +} + +// XTypeProvider + +Sequence< sal_Int8 > SAL_CALL AccessibleGridControlBase::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// XServiceInfo + +sal_Bool SAL_CALL AccessibleGridControlBase::supportsService( + const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +Sequence< OUString > SAL_CALL AccessibleGridControlBase::getSupportedServiceNames() +{ + return { "com.sun.star.accessibility.AccessibleContext" }; +} +// internal virtual methods + +bool AccessibleGridControlBase::implIsShowing() +{ + bool bShowing = false; + if( m_xParent.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleComponent > + xParentComp( m_xParent->getAccessibleContext(), uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = implGetBoundingBox().Overlaps( + VCLRectangle( xParentComp->getBounds() ) ); + } + return bShowing; +} + +sal_Int64 AccessibleGridControlBase::implCreateStateSet() +{ + sal_Int64 nStateSet = 0; + + if( isAlive() ) + { + // SHOWING done with m_xParent + if( implIsShowing() ) + nStateSet |= AccessibleStateType::SHOWING; + // GridControl fills StateSet with states depending on object type + m_aTable.FillAccessibleStateSet( nStateSet, getType() ); + } + else + nStateSet |= AccessibleStateType::DEFUNC; + return nStateSet; +} + +// internal helper methods + +bool AccessibleGridControlBase::isAlive() const +{ + ::osl::MutexGuard g(m_aMutex); // guards rBHelper members + return !rBHelper.bDisposed && !rBHelper.bInDispose; +} + +void AccessibleGridControlBase::ensureIsAlive() const +{ + if( !isAlive() ) + throw lang::DisposedException(); +} + +tools::Rectangle AccessibleGridControlBase::getBoundingBox() +{ + SolarMutexGuard aSolarGuard; + ensureIsAlive(); + tools::Rectangle aRect = implGetBoundingBox(); + if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 ) + { + SAL_WARN( "accessibility", "rectangle doesn't exist" ); + } + return aRect; +} + +AbsoluteScreenPixelRectangle AccessibleGridControlBase::getBoundingBoxOnScreen() +{ + SolarMutexGuard aSolarGuard; + ensureIsAlive(); + AbsoluteScreenPixelRectangle aRect = implGetBoundingBoxOnScreen(); + if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 ) + { + SAL_WARN( "accessibility", "rectangle doesn't exist" ); + } + return aRect; +} + +void AccessibleGridControlBase::commitEvent( + sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue ) +{ + SolarMutexGuard g; + + if ( !getClientId( ) ) + // if we don't have a client id for the notifier, then we don't have listeners, then + // we don't need to notify anything + return; + + // build an event object + AccessibleEventObject aEvent(*this, _nEventId, _rNewValue, _rOldValue, -1); + + // let the notifier handle this event + + AccessibleEventNotifier::addEvent( getClientId( ), aEvent ); +} + +sal_Int16 SAL_CALL AccessibleGridControlBase::getAccessibleRole() +{ + ensureIsAlive(); + sal_Int16 nRole = AccessibleRole::UNKNOWN; + switch ( m_eObjType ) + { + case AccessibleTableControlObjType::ROWHEADERCELL: + nRole = AccessibleRole::ROW_HEADER; + break; + case AccessibleTableControlObjType::COLUMNHEADERCELL: + nRole = AccessibleRole::COLUMN_HEADER; + break; + case AccessibleTableControlObjType::COLUMNHEADERBAR: + case AccessibleTableControlObjType::ROWHEADERBAR: + case AccessibleTableControlObjType::TABLE: + nRole = AccessibleRole::TABLE; + break; + case AccessibleTableControlObjType::TABLECELL: + nRole = AccessibleRole::TABLE_CELL; + break; + case AccessibleTableControlObjType::GRIDCONTROL: + nRole = AccessibleRole::PANEL; + break; + } + return nRole; +} + +css::uno::Reference<css::accessibility::XAccessible > SAL_CALL AccessibleGridControlBase::getAccessibleAtPoint( const css::awt::Point& ) +{ + return nullptr; +} + +sal_Int32 SAL_CALL AccessibleGridControlBase::getForeground( ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + Color nColor; + vcl::Window* pInst = m_aTable.GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlForeground() ) + nColor = pInst->GetControlForeground(); + else + { + vcl::Font aFont; + if ( pInst->IsControlFont() ) + aFont = pInst->GetControlFont(); + else + aFont = pInst->GetFont(); + nColor = aFont.GetColor(); + } + } + return sal_Int32(nColor); +} + +sal_Int32 SAL_CALL AccessibleGridControlBase::getBackground( ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + Color nColor; + vcl::Window* pInst = m_aTable.GetWindowInstance(); + if ( pInst ) + { + if ( pInst->IsControlBackground() ) + nColor = pInst->GetControlBackground(); + else + nColor = pInst->GetBackground().GetColor(); + } + return sal_Int32(nColor); +} + + +GridControlAccessibleElement::GridControlAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType ) + :AccessibleGridControlBase( rxParent, rTable, eObjType ) +{ +} + +// XInterface +IMPLEMENT_FORWARD_XINTERFACE2( GridControlAccessibleElement, AccessibleGridControlBase, GridControlAccessibleElement_Base) + +// XTypeProvider +IMPLEMENT_FORWARD_XTYPEPROVIDER2( GridControlAccessibleElement, AccessibleGridControlBase, GridControlAccessibleElement_Base ) + +// css::accessibility::XAccessible + +css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL GridControlAccessibleElement::getAccessibleContext() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return this; +} + +GridControlAccessibleElement::~GridControlAccessibleElement( ) +{ +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControlHeader.cxx b/accessibility/source/extended/AccessibleGridControlHeader.cxx new file mode 100644 index 0000000000..ebe5f9d09d --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlHeader.cxx @@ -0,0 +1,239 @@ +/* -*- 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 <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <extended/AccessibleGridControlHeader.hxx> +#include <extended/AccessibleGridControlHeaderCell.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::vcl; +using namespace ::vcl::table; + + +namespace accessibility { + + +AccessibleGridControlHeader::AccessibleGridControlHeader( + const Reference< XAccessible >& rxParent, + ::vcl::table::IAccessibleTable& rTable, + ::vcl::table::AccessibleTableControlObjType eObjType): + AccessibleGridControlTableBase( rxParent, rTable, eObjType ) +{ + OSL_ENSURE( isRowBar() || isColumnBar(), + "extended/AccessibleGridControlHeaderBar - invalid object type" ); +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlHeader::getAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + if (nChildIndex<0 || nChildIndex>=getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + ensureIsAlive(); + Reference< XAccessible > xChild; + if (m_eObjType == vcl::table::AccessibleTableControlObjType::COLUMNHEADERBAR) + { + rtl::Reference<AccessibleGridControlHeaderCell> pColHeaderCell = new AccessibleGridControlHeaderCell(nChildIndex, this, m_aTable, + vcl::table::AccessibleTableControlObjType::COLUMNHEADERCELL); + xChild = pColHeaderCell; + } + else if (m_eObjType == vcl::table::AccessibleTableControlObjType::ROWHEADERBAR) + { + rtl::Reference<AccessibleGridControlHeaderCell> pRowHeaderCell = new AccessibleGridControlHeaderCell(nChildIndex, this, m_aTable, + vcl::table::AccessibleTableControlObjType::ROWHEADERCELL); + xChild = pRowHeaderCell; + } + return xChild; +} + +sal_Int64 SAL_CALL AccessibleGridControlHeader::getAccessibleIndexInParent() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + if (m_eObjType == vcl::table::AccessibleTableControlObjType::ROWHEADERBAR && m_aTable.HasColHeader()) + return 1; + else + return 0; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlHeader::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + sal_Int32 nRow = 0; + sal_Int32 nColumnPos = 0; + bool bConverted = m_aTable.ConvertPointToCellAddress(nRow, nColumnPos, VCLPoint(rPoint)); + return bConverted ? implGetChild( nRow, nColumnPos ) : Reference< XAccessible >(); +} + +void SAL_CALL AccessibleGridControlHeader::grabFocus() +{ + ensureIsAlive(); + // focus on header not supported +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlHeader::getAccessibleRowDescription( sal_Int32 nRow ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidRow( nRow ); + return OUString(); // no headers in headers +} + +OUString SAL_CALL AccessibleGridControlHeader::getAccessibleColumnDescription( sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return OUString(); // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlHeader::getAccessibleRowHeaders() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return nullptr; // no headers in headers +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlHeader::getAccessibleColumnHeaders() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return nullptr; // no headers in headers +} +//not selectable +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlHeader::getSelectedAccessibleRows() +{ + return {}; +} +//columns aren't selectable +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlHeader::getSelectedAccessibleColumns() +{ + return {}; +} +//row headers not selectable +sal_Bool SAL_CALL AccessibleGridControlHeader::isAccessibleRowSelected( sal_Int32 /*nRow*/ ) +{ + return false; +} +//columns aren't selectable +sal_Bool SAL_CALL AccessibleGridControlHeader::isAccessibleColumnSelected( sal_Int32 ) +{ + return false; +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlHeader::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn) +{ + SolarMutexGuard g; + + ensureIsAlive(); + ensureIsValidAddress(nRow, nColumn); + return implGetChild(nRow, nColumn); +} +// not selectable +sal_Bool SAL_CALL AccessibleGridControlHeader::isAccessibleSelected( + sal_Int32 /*nRow*/, sal_Int32 /*nColumn */) +{ + return false; +} + +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlHeader::getImplementationName() +{ + return "com.sun.star.accessibility.AccessibleGridControlHeader"; +} + +Sequence< sal_Int8 > SAL_CALL AccessibleGridControlHeader::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// internal virtual methods --------------------------------------------------- + +tools::Rectangle AccessibleGridControlHeader::implGetBoundingBox() +{ + vcl::Window* pParent = m_aTable.GetAccessibleParentWindow(); + tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( *pParent ) ); + tools::Rectangle aHeaderRect (m_aTable.calcHeaderRect(isColumnBar())); + if(isColumnBar()) + return tools::Rectangle(aGridRect.TopLeft(), Size(aGridRect.getOpenWidth(),aHeaderRect.getOpenHeight())); + else + return tools::Rectangle(aGridRect.TopLeft(), Size(aHeaderRect.getOpenWidth(),aGridRect.getOpenHeight())); + +} + +AbsoluteScreenPixelRectangle AccessibleGridControlHeader::implGetBoundingBoxOnScreen() +{ + AbsoluteScreenPixelRectangle aGridRect( m_aTable.GetWindowExtentsAbsolute() ); + tools::Rectangle aHeaderRect (m_aTable.calcHeaderRect(isColumnBar())); + if(isColumnBar()) + return AbsoluteScreenPixelRectangle(aGridRect.TopLeft(), Size(aGridRect.getOpenWidth(),aHeaderRect.getOpenHeight())); + else + return AbsoluteScreenPixelRectangle(aGridRect.TopLeft(), Size(aHeaderRect.getOpenWidth(),aGridRect.getOpenHeight())); +} + +// internal helper methods ---------------------------------------------------- +Reference< XAccessible > AccessibleGridControlHeader::implGetChild( + sal_Int32 nRow, sal_uInt32 nColumnPos ) +{ + Reference< XAccessible > xChild; + if (m_eObjType == vcl::table::AccessibleTableControlObjType::COLUMNHEADERBAR) + { + rtl::Reference<AccessibleGridControlHeaderCell> pColHeaderCell = new AccessibleGridControlHeaderCell(nColumnPos, this, m_aTable, + vcl::table::AccessibleTableControlObjType::COLUMNHEADERCELL); + xChild = pColHeaderCell; + } + else if (m_eObjType == vcl::table::AccessibleTableControlObjType::ROWHEADERBAR) + { + rtl::Reference<AccessibleGridControlHeaderCell> pRowHeaderCell = new AccessibleGridControlHeaderCell(nRow, this, m_aTable, + vcl::table::AccessibleTableControlObjType::ROWHEADERCELL); + xChild = pRowHeaderCell; + } + return xChild; +} + +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx b/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx new file mode 100644 index 0000000000..00b3e60d7d --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx @@ -0,0 +1,166 @@ +/* -*- 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 <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <extended/AccessibleGridControlHeaderCell.hxx> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> + +namespace accessibility +{ + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::uno; + using namespace ::vcl; + using namespace ::vcl::table; + +AccessibleGridControlHeaderCell::AccessibleGridControlHeaderCell(sal_Int32 _nColumnRowId, + const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable, + AccessibleTableControlObjType eObjType) +: AccessibleGridControlCell(rxParent, rTable, + (eObjType == AccessibleTableControlObjType::ROWHEADERCELL) ? _nColumnRowId : 0, + (eObjType == AccessibleTableControlObjType::ROWHEADERCELL) ? 0 : _nColumnRowId, + eObjType) +, m_nColumnRowId(_nColumnRowId) +{ + assert(eObjType == AccessibleTableControlObjType::ROWHEADERCELL || eObjType == AccessibleTableControlObjType::COLUMNHEADERCELL); +} +/** Return a bitset of states of the current object. +*/ +sal_Int64 AccessibleGridControlHeaderCell::implCreateStateSet() +{ + sal_Int64 nStateSet = 0; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + nStateSet |= AccessibleStateType::SHOWING; + + nStateSet |= AccessibleStateType::VISIBLE; + nStateSet |= AccessibleStateType::FOCUSABLE; + nStateSet |= AccessibleStateType::TRANSIENT; + nStateSet |= AccessibleStateType::SELECTABLE; + + if ( m_aTable.IsRowSelected(m_nColumnRowId) ) + nStateSet |= AccessibleStateType::SELECTED; + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; +} + +/** @return + The count of visible children. +*/ +sal_Int64 SAL_CALL AccessibleGridControlHeaderCell::getAccessibleChildCount() +{ + return 0; +} + + +/** @return + The XAccessible interface of the specified child. +*/ +Reference<XAccessible > SAL_CALL AccessibleGridControlHeaderCell::getAccessibleChild( sal_Int64 ) +{ + throw IndexOutOfBoundsException(); +} +// XInterface ------------------------------------------------------------- + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL AccessibleGridControlHeaderCell::queryInterface( const css::uno::Type& rType ) + { + Any aRet = AccessibleGridControlCell::queryInterface(rType); + return aRet; + } + + /** Acquires the object (calls acquire() on base class). */ + void SAL_CALL AccessibleGridControlHeaderCell::acquire() noexcept + { + AccessibleGridControlCell::acquire(); + } + + /** Releases the object (calls release() on base class). */ + void SAL_CALL AccessibleGridControlHeaderCell::release() noexcept + { + AccessibleGridControlCell::release(); + } + /** @return The XAccessibleContext interface of this object. */ + Reference< css::accessibility::XAccessibleContext > SAL_CALL AccessibleGridControlHeaderCell::getAccessibleContext() + { + ensureIsAlive(); + return this; + } + + +/** Grabs the focus to the column header. */ +void SAL_CALL AccessibleGridControlHeaderCell::grabFocus() +{ +} + +/** @return + The name of this class. +*/ +OUString SAL_CALL AccessibleGridControlHeaderCell::getImplementationName() +{ + return "com.sun.star.accessibility.AccessibleGridControlHeaderCell"; +} + +tools::Rectangle AccessibleGridControlHeaderCell::implGetBoundingBox() +{ + vcl::Window* pParent = m_aTable.GetAccessibleParentWindow(); + tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( *pParent ) ); + sal_Int32 nIndex = getAccessibleIndexInParent(); + tools::Rectangle aCellRect; + if (m_eObjType == AccessibleTableControlObjType::COLUMNHEADERCELL) + aCellRect = m_aTable.calcHeaderCellRect(true, nIndex); + else + aCellRect = m_aTable.calcHeaderCellRect(false, nIndex); + return tools::Rectangle(Point(aGridRect.Left()+aCellRect.Left(),aGridRect.Top()+aCellRect.Top()), aCellRect.GetSize()); +} + + +AbsoluteScreenPixelRectangle AccessibleGridControlHeaderCell::implGetBoundingBoxOnScreen() +{ + AbsoluteScreenPixelRectangle aGridRect( m_aTable.GetWindowExtentsAbsolute() ); + sal_Int32 nIndex = getAccessibleIndexInParent(); + tools::Rectangle aCellRect; + if (m_eObjType == AccessibleTableControlObjType::COLUMNHEADERCELL) + aCellRect = m_aTable.calcHeaderCellRect(true, nIndex); + else + aCellRect = m_aTable.calcHeaderCellRect(false, nIndex); + return AbsoluteScreenPixelRectangle(AbsoluteScreenPixelPoint(aGridRect.Left()+aCellRect.Left(),aGridRect.Top()+aCellRect.Top()), aCellRect.GetSize()); +} + +sal_Int64 SAL_CALL AccessibleGridControlHeaderCell::getAccessibleIndexInParent() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return m_nColumnRowId; +} + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControlTable.cxx b/accessibility/source/extended/AccessibleGridControlTable.cxx new file mode 100644 index 0000000000..11f0f0a1d5 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlTable.cxx @@ -0,0 +1,399 @@ +/* -*- 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 <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <extended/AccessibleGridControlTable.hxx> +#include <extended/AccessibleGridControlTableCell.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> +#include <tools/debug.hxx> + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::vcl; +using namespace ::vcl::table; + + +namespace accessibility { + + +AccessibleGridControlTable::AccessibleGridControlTable( + const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable) : + AccessibleGridControlTableBase(rxParent, rTable, AccessibleTableControlObjType::TABLE) +{ +} + +// XAccessibleContext --------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlTable::getAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + sal_Int64 nCount = getAccessibleChildCount(); + if(m_aCellVector.empty() || m_aCellVector.size() != static_cast<unsigned>(nCount)) + { + assert(o3tl::make_unsigned(nCount) < m_aCellVector.max_size()); + m_aCellVector.resize(nCount); + } + if(!m_aCellVector[nChildIndex].is()) + { + rtl::Reference<AccessibleGridControlTableCell> pCell = new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount()); + m_aCellVector[nChildIndex] = pCell; + } + return m_aCellVector[nChildIndex]; +} + +sal_Int64 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + if(m_aTable.HasRowHeader() && m_aTable.HasColHeader()) + return 0; + else if((!m_aTable.HasRowHeader() && m_aTable.HasColHeader()) || (m_aTable.HasRowHeader() && !m_aTable.HasColHeader()) ) + return 1; + else + return 2; +} + +// XAccessibleComponent ------------------------------------------------------- + +Reference< XAccessible > SAL_CALL +AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + Reference< XAccessible > xChild; + sal_Int32 nRow = 0; + sal_Int32 nColumnPos = 0; + if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) ) + xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos); + return xChild; +} + +void SAL_CALL AccessibleGridControlTable::grabFocus() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + m_aTable.GrabFocus(); +} + +// XAccessibleTable ----------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlTable::getAccessibleRowDescription( sal_Int32 nRow ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidRow( nRow ); + return "row description"; +} + +OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidColumn( nColumn ); + return "col description"; +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleRowHeaders() +{ + SolarMutexGuard g; + + ensureIsAlive(); + if(m_aTable.HasColHeader()) + return implGetHeaderBar( 1 ); + else + return implGetHeaderBar( 0 ); +} + +Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleColumnHeaders() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return implGetHeaderBar( 0 ); +} + +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleRows() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + Sequence< sal_Int32 > aSelSeq; + implGetSelectedRows( aSelSeq ); + return aSelSeq; +} + +//columns aren't selectable +Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns() +{ + return {}; +} + +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleRowSelected( sal_Int32 nRow ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidRow( nRow ); + Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); + return comphelper::findValue(selectedRows, nRow) != -1; +} + +//columns aren't selectable +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleColumnSelected( sal_Int32 ) +{ + return false; +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + sal_Int64 nChildIndex = static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(m_aTable.GetColumnCount()) + nColumn; + return getAccessibleChild(nChildIndex); +} + +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + //selection of single cells not possible, so if row is selected, the cell will be selected too + return isAccessibleRowSelected(nRow); +} +void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + sal_Int32 nColumns = m_aTable.GetColumnCount(); + sal_Int32 nRow = nChildIndex / nColumns; + m_aTable.SelectRow( nRow, true ); +} +sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + sal_Int32 nColumns = m_aTable.GetColumnCount(); + sal_Int32 nRow = nChildIndex / nColumns; + return isAccessibleRowSelected(nRow); +} +void SAL_CALL AccessibleGridControlTable::clearAccessibleSelection() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + m_aTable.SelectAllRows( false ); +} +void SAL_CALL AccessibleGridControlTable::selectAllAccessibleChildren() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); + auto selectedRowsRange = asNonConstRange(selectedRows); + for(tools::Long i=0; i<m_aTable.GetRowCount(); i++) + selectedRowsRange[i]=i; +} +sal_Int64 SAL_CALL AccessibleGridControlTable::getSelectedAccessibleChildCount() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows(); + sal_Int32 nColumns = m_aTable.GetColumnCount(); + return static_cast<sal_Int64>(selectedRows.getLength()) * static_cast<sal_Int64>(nColumns); +} +Reference< XAccessible > SAL_CALL +AccessibleGridControlTable::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + if (nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount()) + throw lang::IndexOutOfBoundsException("Invalid index into selection", *this); + + const sal_Int32 nColCount = getAccessibleColumnCount(); + assert(nColCount > 0 && "Column count non-positive, but child count > 0"); + const sal_Int32 nIndexInSelectedRowsSequence = nSelectedChildIndex / nColCount; + const Sequence<sal_Int32> aSelectedRows = getSelectedAccessibleRows(); + const sal_Int32 nRowIndex = aSelectedRows[nIndexInSelectedRowsSequence]; + const sal_Int32 nColIndex = nSelectedChildIndex % nColCount; + return getAccessibleCellAt(nRowIndex, nColIndex); +} +//not implemented yet, because only row selection possible +void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild( + sal_Int64 ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); +} +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType ) +{ + Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleGridControlTableSelectionImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleGridControlTable::acquire() noexcept +{ + AccessibleGridControlTableBase::acquire(); +} + +void SAL_CALL AccessibleGridControlTable::release() noexcept +{ + AccessibleGridControlTableBase::release(); +} +// XServiceInfo --------------------------------------------------------------- + +OUString SAL_CALL AccessibleGridControlTable::getImplementationName() +{ + return "com.sun.star.accessibility.AccessibleGridControlTable"; +} + +void AccessibleGridControlTable::dispose() +{ + for (rtl::Reference<AccessibleGridControlTableCell>& rxCell : m_aCellVector) + { + if (rxCell.is()) + { + rxCell->dispose(); + rxCell.clear(); + } + } + + AccessibleGridControlTableBase::dispose(); +} + +void AccessibleGridControlTable::commitEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue, + const css::uno::Any& rOldValue) +{ + if (nEventId == AccessibleEventId::TABLE_MODEL_CHANGED) + { + AccessibleTableModelChange aChange; + if (rNewValue >>= aChange) + { + assert(aChange.Type != AccessibleTableModelChangeType::COLUMNS_REMOVED); + + if (aChange.Type == AccessibleTableModelChangeType::ROWS_REMOVED) + { + int nColCount = m_aTable.GetColumnCount(); + // check valid index - entries are inserted lazily + size_t const nStart = nColCount * aChange.FirstRow; + size_t const nEnd = nColCount * aChange.LastRow; + if (nStart < m_aCellVector.size()) + { + m_aCellVector.erase( + m_aCellVector.begin() + nStart, + m_aCellVector.begin() + std::min(m_aCellVector.size(), nEnd)); + } + } + } + } + + AccessibleGridControlBase::commitEvent(nEventId, rNewValue, rOldValue); +} + +// internal virtual methods --------------------------------------------------- + +tools::Rectangle AccessibleGridControlTable::implGetBoundingBox() +{ + vcl::Window* pParent = m_aTable.GetAccessibleParentWindow(); + DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" ); + tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( *pParent )); + tools::Rectangle aTableRect( m_aTable.calcTableRect() ); + tools::Long nX = aGridRect.Left() + aTableRect.Left(); + tools::Long nY = aGridRect.Top() + aTableRect.Top(); + tools::Long nWidth = aGridRect.GetSize().Width()-aTableRect.Left(); + tools::Long nHeight = aGridRect.GetSize().Height()-aTableRect.Top(); + tools::Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight )); + return aTable; +} + +AbsoluteScreenPixelRectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen() +{ + tools::Rectangle aGridRect( m_aTable.GetWindowExtentsAbsolute()); + tools::Rectangle aTableRect( m_aTable.calcTableRect() ); + tools::Long nX = aGridRect.Left() + aTableRect.Left(); + tools::Long nY = aGridRect.Top() + aTableRect.Top(); + tools::Long nWidth = aGridRect.GetSize().Width()-aTableRect.Left(); + tools::Long nHeight = aGridRect.GetSize().Height()-aTableRect.Top(); + AbsoluteScreenPixelRectangle aTable( AbsoluteScreenPixelPoint( nX, nY ), AbsoluteScreenPixelSize( nWidth, nHeight )); + return aTable; +} +// internal helper methods ---------------------------------------------------- +Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar( + sal_Int32 nChildIndex ) +{ + Reference< XAccessible > xRet; + + if (!m_xParent.is()) + return nullptr; + + Reference<XAccessibleContext> xContext = m_xParent->getAccessibleContext(); + if( xContext.is() ) + { + try + { + xRet = xContext->getAccessibleChild( nChildIndex ); + } + catch (const lang::IndexOutOfBoundsException&) + { + OSL_FAIL( "implGetHeaderBar - wrong child index" ); + } + // RuntimeException goes to caller + } + return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY ); +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControlTableBase.cxx b/accessibility/source/extended/AccessibleGridControlTableBase.cxx new file mode 100644 index 0000000000..499a3cec23 --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlTableBase.cxx @@ -0,0 +1,246 @@ +/* -*- 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 <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <extended/AccessibleGridControlTableBase.hxx> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> +#include <comphelper/sequence.hxx> + +using css::uno::Reference; +using css::uno::Sequence; +using css::uno::Any; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::vcl; +using namespace ::vcl::table; + + +namespace accessibility { + + +AccessibleGridControlTableBase::AccessibleGridControlTableBase( + const Reference< XAccessible >& rxParent, + IAccessibleTable& rTable, + AccessibleTableControlObjType eObjType ) : + GridControlAccessibleElement( rxParent, rTable, eObjType ) +{ +} + +// XAccessibleContext --------------------------------------------------------- + +sal_Int64 SAL_CALL AccessibleGridControlTableBase::getAccessibleChildCount() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + sal_Int64 nChildren = 0; + if (m_eObjType == AccessibleTableControlObjType::ROWHEADERBAR) + nChildren = m_aTable.GetRowCount(); + else if (m_eObjType == AccessibleTableControlObjType::TABLE) + nChildren = static_cast<sal_Int64>(m_aTable.GetRowCount()) * static_cast<sal_Int64>(m_aTable.GetColumnCount()); + else if (m_eObjType == AccessibleTableControlObjType::COLUMNHEADERBAR) + nChildren = m_aTable.GetColumnCount(); + return nChildren; +} + +sal_Int16 SAL_CALL AccessibleGridControlTableBase::getAccessibleRole() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return AccessibleRole::TABLE; +} + +// XAccessibleTable ----------------------------------------------------------- + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleRowCount() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + if (m_eObjType == AccessibleTableControlObjType::COLUMNHEADERBAR) + return 1; + return m_aTable.GetRowCount(); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleColumnCount() +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + if (m_eObjType == AccessibleTableControlObjType::ROWHEADERBAR) + return 1; + return m_aTable.GetColumnCount(); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleRowExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleColumnExtentAt( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return 1; // merged cells not supported +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlTableBase::getAccessibleCaption() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return nullptr; // not supported +} + +Reference< XAccessible > SAL_CALL AccessibleGridControlTableBase::getAccessibleSummary() +{ + SolarMutexGuard g; + + ensureIsAlive(); + return nullptr; // not supported +} + +sal_Int64 SAL_CALL AccessibleGridControlTableBase::getAccessibleIndex( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidAddress( nRow, nColumn ); + return static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(m_aTable.GetColumnCount()) + nColumn; +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleRow( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetRow( nChildIndex ); +} + +sal_Int32 SAL_CALL AccessibleGridControlTableBase::getAccessibleColumn( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + ensureIsValidIndex( nChildIndex ); + return implGetColumn( nChildIndex ); +} + +// XInterface ----------------------------------------------------------------- + +Any SAL_CALL AccessibleGridControlTableBase::queryInterface( const uno::Type& rType ) +{ + Any aAny( GridControlAccessibleElement::queryInterface( rType ) ); + return aAny.hasValue() ? + aAny : AccessibleGridControlTableImplHelper::queryInterface( rType ); +} + +void SAL_CALL AccessibleGridControlTableBase::acquire() noexcept +{ + GridControlAccessibleElement::acquire(); +} + +void SAL_CALL AccessibleGridControlTableBase::release() noexcept +{ + GridControlAccessibleElement::release(); +} + +// XTypeProvider -------------------------------------------------------------- + +Sequence< uno::Type > SAL_CALL AccessibleGridControlTableBase::getTypes() +{ + return ::comphelper::concatSequences( + GridControlAccessibleElement::getTypes(), + AccessibleGridControlTableImplHelper::getTypes() ); +} + +Sequence< sal_Int8 > SAL_CALL AccessibleGridControlTableBase::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// internal helper methods ---------------------------------------------------- + +sal_Int32 AccessibleGridControlTableBase::implGetRow( sal_Int64 nChildIndex ) +{ + sal_Int32 nColumns = getAccessibleColumnCount(); + return nColumns ? (nChildIndex / nColumns) : 0; +} + +sal_Int32 AccessibleGridControlTableBase::implGetColumn( sal_Int64 nChildIndex ) +{ + sal_Int32 nColumns = getAccessibleColumnCount(); + return nColumns ? (nChildIndex % nColumns) : 0; +} + +void AccessibleGridControlTableBase::implGetSelectedRows( Sequence< sal_Int32 >& rSeq ) +{ + sal_Int32 const selectionCount( m_aTable.GetSelectedRowCount() ); + rSeq.realloc( selectionCount ); + auto pSeq = rSeq.getArray(); + for ( sal_Int32 i=0; i<selectionCount; ++i ) + pSeq[i] = m_aTable.GetSelectedRowIndex(i); +} + +void AccessibleGridControlTableBase::ensureIsValidRow( sal_Int32 nRow ) +{ + if (nRow >= getAccessibleRowCount()) + throw lang::IndexOutOfBoundsException( "row index is invalid", *this ); +} + +void AccessibleGridControlTableBase::ensureIsValidColumn( sal_Int32 nColumn ) +{ + if (nColumn >= getAccessibleColumnCount()) + throw lang::IndexOutOfBoundsException( "column index is invalid", *this ); +} + +void AccessibleGridControlTableBase::ensureIsValidAddress( + sal_Int32 nRow, sal_Int32 nColumn ) +{ + ensureIsValidRow( nRow ); + ensureIsValidColumn( nColumn ); +} + +void AccessibleGridControlTableBase::ensureIsValidIndex( sal_Int64 nChildIndex ) +{ + if (nChildIndex >= static_cast<sal_Int64>(m_aTable.GetRowCount()) * static_cast<sal_Int64>(m_aTable.GetColumnCount())) + throw lang::IndexOutOfBoundsException( "child index is invalid", *this ); +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleGridControlTableCell.cxx b/accessibility/source/extended/AccessibleGridControlTableCell.cxx new file mode 100644 index 0000000000..43e56aefae --- /dev/null +++ b/accessibility/source/extended/AccessibleGridControlTableCell.cxx @@ -0,0 +1,345 @@ +/* -*- 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 <extended/AccessibleGridControlTableCell.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/accessibletable.hxx> +#include <vcl/svapp.hxx> +#include <tools/gen.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +namespace accessibility +{ + namespace + { + // FIXME this is a copy'n'paste from + // source/extended/AccessibleBrowseBoxTableCell.cxx, get rid of that... + /// @throws css::lang::IndexOutOfBoundsException + void checkIndex_Impl( sal_Int32 _nIndex, std::u16string_view _sText ) + { + if ( _nIndex >= static_cast<sal_Int32>(_sText.size()) ) + throw css::lang::IndexOutOfBoundsException(); + } + } + using namespace ::com::sun::star::lang; + using namespace comphelper; + using namespace ::com::sun::star::uno; + using ::com::sun::star::accessibility::XAccessible; + using namespace ::com::sun::star::accessibility; + using namespace ::vcl; + using namespace ::vcl::table; + + + // = AccessibleGridControlCell + + + AccessibleGridControlCell::AccessibleGridControlCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, ::vcl::table::IAccessibleTable& _rTable, + sal_Int32 _nRowPos, sal_uInt16 _nColPos, ::vcl::table::AccessibleTableControlObjType _eType ) + :AccessibleGridControlBase( _rxParent, _rTable, _eType ) + ,m_nRowPos( _nRowPos ) + ,m_nColPos( _nColPos ) + { + assert(((m_eObjType == AccessibleTableControlObjType::TABLECELL) + || ((m_eObjType == AccessibleTableControlObjType::ROWHEADERCELL) && _nColPos == 0) + || ((m_eObjType == AccessibleTableControlObjType::COLUMNHEADERCELL) && _nRowPos == 0)) + && "Unhandled table cell type"); + } + + void SAL_CALL AccessibleGridControlCell::grabFocus() + { + SolarMutexGuard aSolarGuard; + + m_aTable.GoToCell( m_nColPos, m_nRowPos ); + } + + OUString SAL_CALL AccessibleGridControlCell::getAccessibleName() + { + SolarMutexGuard g; + + ensureIsAlive(); + return m_aTable.GetAccessibleObjectName(m_eObjType, m_nRowPos, m_nColPos); + } + + // implementation of a table cell + OUString AccessibleGridControlTableCell::implGetText() + { + ensureIsAlive(); + return m_aTable.GetAccessibleCellText( getRowPos(), getColumnPos() ); + } + + css::lang::Locale AccessibleGridControlTableCell::implGetLocale() + { + ensureIsAlive(); + return m_aTable.GetAccessible()->getAccessibleContext()->getLocale(); + } + + void AccessibleGridControlTableCell::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + + AccessibleGridControlTableCell::AccessibleGridControlTableCell(const css::uno::Reference<XAccessible >& _rxParent, + ::vcl::table::IAccessibleTable& _rTable, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos) + :AccessibleGridControlCell(_rxParent, _rTable, _nRowPos, _nColPos, AccessibleTableControlObjType::TABLECELL) + { + } + + // XInterface + + /** Queries for a new interface. */ + css::uno::Any SAL_CALL AccessibleGridControlTableCell::queryInterface( + const css::uno::Type& rType ) + { + Any aRet = AccessibleGridControlCell::queryInterface(rType); + if ( !aRet.hasValue() ) + aRet = AccessibleTextHelper_BASE::queryInterface(rType); + return aRet; + } + + /** Acquires the object (calls acquire() on base class). */ + void SAL_CALL AccessibleGridControlTableCell::acquire() noexcept + { + AccessibleGridControlCell::acquire(); + } + + /** Releases the object (calls release() on base class). */ + void SAL_CALL AccessibleGridControlTableCell::release() noexcept + { + AccessibleGridControlCell::release(); + } + + css::awt::Rectangle SAL_CALL AccessibleGridControlTableCell::getCharacterBounds( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return AWTRectangle( m_aTable.GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) ); + } + + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getIndexAtPoint( const css::awt::Point& _aPoint ) + { + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + return m_aTable.GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) ); + } + + /** @return + The name of this class. + */ + OUString SAL_CALL AccessibleGridControlTableCell::getImplementationName() + { + return "com.sun.star.accessibility.AccessibleGridControlTableCell"; + } + + /** @return The count of visible children. */ + sal_Int64 SAL_CALL AccessibleGridControlTableCell::getAccessibleChildCount() + { + return 0; + } + + /** @return The css::accessibility::XAccessible interface of the specified child. */ + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL AccessibleGridControlTableCell::getAccessibleChild( sal_Int64 ) + { + throw css::lang::IndexOutOfBoundsException(); + } + + /** Return a bitset of states of the current object. + */ + sal_Int64 AccessibleGridControlTableCell::implCreateStateSet() + { + sal_Int64 nStateSet = 0; + + if( isAlive() ) + { + // SHOWING done with mxParent + if( implIsShowing() ) + nStateSet |= AccessibleStateType::SHOWING; + + m_aTable.FillAccessibleStateSetForCell( nStateSet, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) ); + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; + } + + + // css::accessibility::XAccessible + + /** @return The css::accessibility::XAccessibleContext interface of this object. */ + css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL AccessibleGridControlTableCell::getAccessibleContext() + { + SolarMutexGuard g; + + ensureIsAlive(); + return this; + } + + // css::accessibility::XAccessibleContext + + sal_Int64 SAL_CALL AccessibleGridControlTableCell::getAccessibleIndexInParent() + { + SolarMutexGuard aSolarGuard; + + ensureIsAlive(); + + return (static_cast<sal_Int64>(getRowPos()) * static_cast<sal_Int64>(m_aTable.GetColumnCount())) + getColumnPos(); + } + + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCaretPosition( ) + { + return -1; + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::setCaretPosition ( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + sal_Unicode SAL_CALL AccessibleGridControlTableCell::getCharacter( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); + } + css::uno::Sequence< css::beans::PropertyValue > SAL_CALL AccessibleGridControlTableCell::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& ) + { + SolarMutexGuard aSolarGuard; + + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return css::uno::Sequence< css::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCharacterCount( ) + { + SolarMutexGuard aSolarGuard; + + return implGetText().getLength(); + } + + OUString SAL_CALL AccessibleGridControlTableCell::getSelectedText( ) + { + return OUString(); + } + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionStart( ) + { + return 0; + } + sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionEnd( ) + { + return 0; + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + OUString SAL_CALL AccessibleGridControlTableCell::getText( ) + { + SolarMutexGuard aSolarGuard; + + return implGetText( ); + } + OUString SAL_CALL AccessibleGridControlTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + + return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ); + } + css::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + + OUString sText = implGetText(); + checkIndex_Impl( nStartIndex, sText ); + checkIndex_Impl( nEndIndex, sText ); + + //!!! don't know how to put a string into the clipboard + return false; + } + sal_Bool SAL_CALL AccessibleGridControlTableCell::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) + { + return false; + } + + tools::Rectangle AccessibleGridControlTableCell::implGetBoundingBox() + { + vcl::Window* pParent = m_aTable.GetAccessibleParentWindow(); + DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" ); + tools::Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( *pParent ); + sal_Int64 nIndex = getAccessibleIndexInParent(); + tools::Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount()); + tools::Long nX = aGridRect.Left() + aCellRect.Left(); + tools::Long nY = aGridRect.Top() + aCellRect.Top(); + tools::Rectangle aCell( Point( nX, nY ), aCellRect.GetSize()); + return aCell; + } + + AbsoluteScreenPixelRectangle AccessibleGridControlTableCell::implGetBoundingBoxOnScreen() + { + AbsoluteScreenPixelRectangle aGridRect = m_aTable.GetWindowExtentsAbsolute(); + sal_Int64 nIndex = getAccessibleIndexInParent(); + tools::Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount()); + tools::Long nX = aGridRect.Left() + aCellRect.Left(); + tools::Long nY = aGridRect.Top() + aCellRect.Top(); + AbsoluteScreenPixelRectangle aCell( AbsoluteScreenPixelPoint( nX, nY ), aCellRect.GetSize()); + return aCell; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/AccessibleIconView.cxx b/accessibility/source/extended/AccessibleIconView.cxx new file mode 100644 index 0000000000..6bc5c99e92 --- /dev/null +++ b/accessibility/source/extended/AccessibleIconView.cxx @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include <sal/config.h> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> + +#include <toolkit/helper/convert.hxx> +#include <vcl/event.hxx> + +#include <extended/AccessibleIconView.hxx> + +namespace accessibility +{ +AccessibleIconView::AccessibleIconView( + SvTreeListBox const& _rListBox, + const css::uno::Reference<css::accessibility::XAccessible>& _xParent) + : AccessibleListBox(_rListBox, _xParent) +{ +} + +void AccessibleIconView::ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent) +{ + if (!isAlive()) + return; + + switch (rVclWindowEvent.GetId()) + { + case VclEventId::WindowMouseMove: + if (MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData())) + { + if (auto xChild = getAccessibleAtPoint(AWTPoint(pMouseEvt->GetPosPixel()))) + { + // Allow announcing the element on mouse hover + css::uno::Any aNew(xChild); + NotifyAccessibleEvent( + css::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, {}, aNew); + } + } + break; + default: + AccessibleListBox::ProcessWindowEvent(rVclWindowEvent); + } +} +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/accessibility/source/extended/accessiblebrowseboxcell.cxx b/accessibility/source/extended/accessiblebrowseboxcell.cxx new file mode 100644 index 0000000000..07c6200141 --- /dev/null +++ b/accessibility/source/extended/accessiblebrowseboxcell.cxx @@ -0,0 +1,69 @@ +/* -*- 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 <sal/types.h> +#include <vcl/accessibletableprovider.hxx> +#include <extended/accessiblebrowseboxcell.hxx> + +namespace accessibility +{ + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::accessibility; + + // AccessibleBrowseBoxCell + AccessibleBrowseBoxCell::AccessibleBrowseBoxCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, sal_uInt16 _nColPos, AccessibleBrowseBoxObjType _eType ) + :AccessibleBrowseBoxBase( _rxParent, _rBrowseBox, _xFocusWindow, _eType ) + ,m_nRowPos( _nRowPos ) + ,m_nColPos( _nColPos ) + { + // set accessible name here, because for that we need the position of the cell + // and so the base class isn't capable of doing this + sal_Int32 nPos = _nRowPos * _rBrowseBox.GetColumnCount() + _nColPos; + OUString aAccName = _rBrowseBox.GetAccessibleObjectName( AccessibleBrowseBoxObjType::TableCell, nPos ); + implSetName( aAccName ); + } + + AccessibleBrowseBoxCell::~AccessibleBrowseBoxCell() + { + } + + void SAL_CALL AccessibleBrowseBoxCell::grabFocus() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + mpBrowseBox->GoToCell( m_nRowPos, m_nColPos ); + } + + ::tools::Rectangle AccessibleBrowseBoxCell::implGetBoundingBox() + { + return mpBrowseBox->GetFieldRectPixel( m_nRowPos, m_nColPos, false, /*bOnScreen*/false ); + } + + AbsoluteScreenPixelRectangle AccessibleBrowseBoxCell::implGetBoundingBoxOnScreen() + { + return AbsoluteScreenPixelRectangle(mpBrowseBox->GetFieldRectPixel( m_nRowPos, m_nColPos, false, /*bOnScreen*/true )); + } +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibleeditbrowseboxcell.cxx b/accessibility/source/extended/accessibleeditbrowseboxcell.cxx new file mode 100644 index 0000000000..d447b906e3 --- /dev/null +++ b/accessibility/source/extended/accessibleeditbrowseboxcell.cxx @@ -0,0 +1,240 @@ +/* -*- 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 <helper/accresmgr.hxx> +#include <strings.hrc> + +#include <extended/accessibleeditbrowseboxcell.hxx> +#include <comphelper/processfactory.hxx> +#include <utility> +#include <comphelper/diagnose_ex.hxx> + +namespace accessibility +{ + using namespace com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::awt; + using namespace ::comphelper; + + EditBrowseBoxTableCell::EditBrowseBoxTableCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + const css::uno::Reference< css::accessibility::XAccessible >& _rxOwningAccessible, + const css::uno::Reference< css::accessibility::XAccessibleContext >& _xControlChild, + ::vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos) + :AccessibleBrowseBoxCell( _rxParent, _rBrowseBox, _xFocusWindow, _nRowPos, _nColPos ) + ,OAccessibleContextWrapperHelper( ::comphelper::getProcessComponentContext(), rBHelper, _xControlChild, _rxOwningAccessible, _rxParent ) + { + aggregateProxy( m_refCount, *this ); + } + + EditBrowseBoxTableCell::~EditBrowseBoxTableCell() + { + if ( !rBHelper.bDisposed ) + { + acquire(); // to prevent duplicate dtor calls + dispose(); + } + } + + OUString SAL_CALL EditBrowseBoxTableCell::getImplementationName() + { + return "com.sun.star.comp.svtools.TableCellProxy"; + } + + IMPLEMENT_FORWARD_XINTERFACE2( EditBrowseBoxTableCell, AccessibleBrowseBoxCell, OAccessibleContextWrapperHelper ) + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( EditBrowseBoxTableCell, AccessibleBrowseBoxCell, OAccessibleContextWrapperHelper ) + + void EditBrowseBoxTableCell::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) + { + commitEvent( _rEvent.EventId, _rEvent.NewValue, _rEvent.OldValue ); + } + + // css::accessibility::XAccessibleComponent + sal_Int32 SAL_CALL EditBrowseBoxTableCell::getForeground( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + css::uno::Reference< css::accessibility::XAccessibleComponent > xAccComp( m_xInnerContext, UNO_QUERY ); + if ( xAccComp.is() ) + return xAccComp->getForeground(); + return 0; + } + + sal_Int32 SAL_CALL EditBrowseBoxTableCell::getBackground( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + css::uno::Reference< css::accessibility::XAccessibleComponent > xAccComp( m_xInnerContext, UNO_QUERY ); + if ( xAccComp.is() ) + return xAccComp->getBackground(); + return 0; + } + + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL EditBrowseBoxTableCell::getAccessibleParent( ) + { + return m_xParentAccessible; + } + + OUString SAL_CALL EditBrowseBoxTableCell::getAccessibleDescription() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return m_xInnerContext->getAccessibleDescription(); + } + + OUString SAL_CALL EditBrowseBoxTableCell::getAccessibleName() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return AccResId(RID_STR_ACC_COLUMN_NUM).replaceAll("%COLUMNNUMBER", OUString::number(getColumnPos()-1)) + ", " + + AccResId(RID_STR_ACC_ROW_NUM).replaceAll("%ROWNUMBER", OUString::number(getRowPos())); + } + + css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL EditBrowseBoxTableCell::getAccessibleRelationSet() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return baseGetAccessibleRelationSet( ); + } + + sal_Int64 SAL_CALL EditBrowseBoxTableCell::getAccessibleStateSet() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return m_xInnerContext->getAccessibleStateSet(); + // TODO: shouldn't we add an ACTIVE here? Isn't the EditBrowseBoxTableCell always ACTIVE? + } + + sal_Int64 SAL_CALL EditBrowseBoxTableCell::getAccessibleChildCount( ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return baseGetAccessibleChildCount(); + } + + css::uno::Reference< css::accessibility::XAccessible > SAL_CALL EditBrowseBoxTableCell::getAccessibleChild( sal_Int64 i ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return baseGetAccessibleChild( i ); + } + + sal_Int16 SAL_CALL EditBrowseBoxTableCell::getAccessibleRole() + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + return m_xInnerContext->getAccessibleRole( ); + } + + void SAL_CALL EditBrowseBoxTableCell::dispose() + { + // simply disambiguate. Note that the OComponentHelper base in AccessibleBrowseBoxCell + // will call our "disposing()", which will call "dispose()" on the OAccessibleContextWrapperHelper + // so there is no need to do this here. + AccessibleBrowseBoxCell::dispose(); + } + + void SAL_CALL EditBrowseBoxTableCell::disposing( const css::lang::EventObject& _rSource ) + { + AccessibleBrowseBoxCell::disposing( _rSource ); + OAccessibleContextWrapperHelper::disposing( _rSource ); + } + + void SAL_CALL EditBrowseBoxTableCell::disposing() + { + SolarMethodGuard aGuard(getMutex()); + + OAccessibleContextWrapperHelper::dispose(); + // TODO: do we need to dispose our inner object? The base class does this, but is it a good idea? + AccessibleBrowseBoxCell::disposing(); + } + + // EditBrowseBoxTableCell + EditBrowseBoxTableCellAccess::EditBrowseBoxTableCellAccess( + css::uno::Reference< css::accessibility::XAccessible > _xParent, css::uno::Reference< css::accessibility::XAccessible > _xControlAccessible, + css::uno::Reference< css::awt::XWindow > _xFocusWindow, + ::vcl::IAccessibleTableProvider& _rBrowseBox, sal_Int32 _nRowPos, sal_uInt16 _nColPos ) + :m_xParent(std::move( _xParent )) + ,m_xControlAccessible(std::move( _xControlAccessible )) + ,m_xFocusWindow(std::move( _xFocusWindow )) + ,m_pBrowseBox( &_rBrowseBox ) + ,m_nRowPos( _nRowPos ) + ,m_nColPos( _nColPos ) + { + } + + EditBrowseBoxTableCellAccess::~EditBrowseBoxTableCellAccess( ) + { + } + + css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL EditBrowseBoxTableCellAccess::getAccessibleContext( ) + { + if ( !m_pBrowseBox || !m_xControlAccessible.is() ) + throw DisposedException(); + css::uno::Reference< css::accessibility::XAccessibleContext > xMyContext( m_aContext ); + if ( !xMyContext.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > xInnerContext = m_xControlAccessible->getAccessibleContext(); + css::uno::Reference< css::accessibility::XAccessible > xMe( this ); + + xMyContext = new EditBrowseBoxTableCell( xMe, m_xParent, xInnerContext, *m_pBrowseBox, m_xFocusWindow, m_nRowPos, m_nColPos ); + m_aContext = xMyContext; + } + return xMyContext; + } + + void EditBrowseBoxTableCellAccess::disposing(std::unique_lock<std::mutex>&) + { + // dispose our context, if it still alive + css::uno::Reference< XComponent > xMyContext( m_aContext.get(), UNO_QUERY ); + if ( xMyContext.is() ) + { + try + { + xMyContext->dispose(); + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "accessibility", "EditBrowseBoxTableCellAccess::disposing: caught an exception while disposing the context!" ); + } + } + + m_pBrowseBox = nullptr; + m_xControlAccessible.clear(); + m_aContext.clear(); + // NO dispose of the inner object there: it is the css::accessibility::XAccessible of a window, and disposing + // it would delete the respective VCL window + } +} // namespace accessibility + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibleiconchoicectrl.cxx b/accessibility/source/extended/accessibleiconchoicectrl.cxx new file mode 100644 index 0000000000..032c9dae95 --- /dev/null +++ b/accessibility/source/extended/accessibleiconchoicectrl.cxx @@ -0,0 +1,345 @@ +/* -*- 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 <extended/accessibleiconchoicectrl.hxx> +#include <extended/accessibleiconchoicectrlentry.hxx> +#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 <comphelper/accessiblecontexthelper.hxx> +#include <vcl/toolkit/ivctrl.hxx> +#include <cppuhelper/supportsservice.hxx> + + +namespace accessibility +{ + + + // class AccessibleIconChoiceCtrl ---------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + + // Ctor() and Dtor() + + AccessibleIconChoiceCtrl::AccessibleIconChoiceCtrl( SvtIconChoiceCtrl const & _rIconCtrl, const Reference< XAccessible >& _xParent ) : + ImplInheritanceHelper( _rIconCtrl.GetWindowPeer() ), + m_xParent ( _xParent ) + { + } + + void AccessibleIconChoiceCtrl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + if ( !isAlive() ) + return; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ListboxSelect : + { + // First send an event that tells the listeners of a + // modified selection. The active descendant event is + // send after that so that the receiving AT has time to + // read the text or name of the active child. +// NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + + if ( getCtrl() && getCtrl()->HasFocus() ) + { + SvxIconChoiceCtrlEntry* pEntry = static_cast< SvxIconChoiceCtrlEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nPos = getCtrl()->GetEntryListPos( pEntry ); + Reference< XAccessible > xChild = new AccessibleIconChoiceCtrlEntry( *getCtrl(), nPos, this ); + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOldValue, aNewValue ); + + } + } + break; + } + case VclEventId::WindowGetFocus : + { + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + if ( pCtrl && pCtrl->HasFocus() ) + { + SvxIconChoiceCtrlEntry* pEntry = static_cast< SvxIconChoiceCtrlEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry == nullptr ) + { + pEntry = getCtrl()->GetSelectedEntry(); + } + if ( pEntry ) + { + sal_Int32 nPos = pCtrl->GetEntryListPos( pEntry ); + Reference< XAccessible > xChild = new AccessibleIconChoiceCtrlEntry( *pCtrl, nPos, this ); + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOldValue, aNewValue ); + } + } + break; + } + default: + VCLXAccessibleComponent::ProcessWindowChildEvent (rVclWindowEvent); + } + } + + // XComponent + + void SAL_CALL AccessibleIconChoiceCtrl::disposing() + { + ::osl::MutexGuard aGuard( m_aMutex ); + + m_xParent = nullptr; + } + + // XServiceInfo + + OUString SAL_CALL AccessibleIconChoiceCtrl::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleIconChoiceControl"; + } + + Sequence< OUString > SAL_CALL AccessibleIconChoiceCtrl::getSupportedServiceNames() + { + return {"com.sun.star.accessibility.AccessibleContext", + "com.sun.star.accessibility.AccessibleComponent", + "com.sun.star.awt.AccessibleIconChoiceControl"}; + } + + sal_Bool SAL_CALL AccessibleIconChoiceCtrl::supportsService( const OUString& _rServiceName ) + { + return cppu::supportsService(this, _rServiceName); + } + + // XAccessible + + Reference< XAccessibleContext > SAL_CALL AccessibleIconChoiceCtrl::getAccessibleContext( ) + { + ensureAlive(); + return this; + } + + // XAccessibleContext + + sal_Int64 SAL_CALL AccessibleIconChoiceCtrl::getAccessibleChildCount( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + return getCtrl()->GetEntryCount(); + } + + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrl::getAccessibleChild( sal_Int64 i ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if (i < 0 || i >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry(i); + if ( !pEntry ) + throw RuntimeException("getAccessibleChild: Entry " + + OUString::number(i) + " not found", + getXWeak()); + + return new AccessibleIconChoiceCtrlEntry( *pCtrl, i, this ); + } + + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrl::getAccessibleParent( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + ensureAlive(); + return m_xParent; + } + + sal_Int16 SAL_CALL AccessibleIconChoiceCtrl::getAccessibleRole( ) + { + //return AccessibleRole::TREE; + return AccessibleRole::LIST; + } + + OUString SAL_CALL AccessibleIconChoiceCtrl::getAccessibleDescription( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + return getCtrl()->GetAccessibleDescription(); + } + + OUString SAL_CALL AccessibleIconChoiceCtrl::getAccessibleName( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + OUString sName = getCtrl()->GetAccessibleName(); + if ( sName.isEmpty() ) + sName = "IconChoiceControl"; + return sName; + } + + // XAccessibleSelection + + void SAL_CALL AccessibleIconChoiceCtrl::selectAccessibleChild( sal_Int64 nChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + pCtrl->SetCursor( pEntry ); + } + + sal_Bool SAL_CALL AccessibleIconChoiceCtrl::isAccessibleChildSelected( sal_Int64 nChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return ( pCtrl->GetCursor() == pEntry ); + } + + void SAL_CALL AccessibleIconChoiceCtrl::clearAccessibleSelection( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + getCtrl()->SetNoSelection(); + } + + void SAL_CALL AccessibleIconChoiceCtrl::selectAllAccessibleChildren( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + sal_Int32 nCount = pCtrl->GetEntryCount(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pCtrl->GetCursor() != pEntry ) + pCtrl->SetCursor( pEntry ); + } + } + + sal_Int64 SAL_CALL AccessibleIconChoiceCtrl::getSelectedAccessibleChildCount( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + sal_Int64 nSelCount = 0; + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + sal_Int32 nCount = pCtrl->GetEntryCount(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pCtrl->GetCursor() == pEntry ) + ++nSelCount; + } + + return nSelCount; + } + + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrl::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int32 nSelCount = 0; + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + sal_Int32 nCount = pCtrl->GetEntryCount(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pCtrl->GetCursor() == pEntry ) + ++nSelCount; + + if ( nSelCount == ( nSelectedChildIndex + 1 ) ) + { + xChild = new AccessibleIconChoiceCtrlEntry( *pCtrl, i, this ); + break; + } + } + + return xChild; + } + + void SAL_CALL AccessibleIconChoiceCtrl::deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + sal_Int32 nSelCount = 0; + VclPtr<SvtIconChoiceCtrl> pCtrl = getCtrl(); + sal_Int32 nCount = pCtrl->GetEntryCount(); + bool bFound = false; + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvxIconChoiceCtrlEntry* pEntry = pCtrl->GetEntry( i ); + if ( pEntry->IsSelected() ) + { + ++nSelCount; + if ( i == nSelectedChildIndex ) + bFound = true; + } + } + + // if only one entry is selected and its index is chosen to deselect -> no selection anymore + if ( nSelCount == 1 && bFound ) + pCtrl->SetNoSelection(); + } + + void AccessibleIconChoiceCtrl::FillAccessibleStateSet( sal_Int64& rStateSet ) + { + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + if ( isAlive() ) + { + rStateSet |= AccessibleStateType::FOCUSABLE; + rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS; + rStateSet |= AccessibleStateType::SELECTABLE; + } + } + + VclPtr< SvtIconChoiceCtrl > AccessibleIconChoiceCtrl::getCtrl() const + { + return GetAs<SvtIconChoiceCtrl >(); + } + +}// namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibleiconchoicectrlentry.cxx b/accessibility/source/extended/accessibleiconchoicectrlentry.cxx new file mode 100644 index 0000000000..9e7b75cf14 --- /dev/null +++ b/accessibility/source/extended/accessibleiconchoicectrlentry.cxx @@ -0,0 +1,669 @@ +/* -*- 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 <extended/accessibleiconchoicectrlentry.hxx> +#include <vcl/toolkit/ivctrl.hxx> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <toolkit/helper/convert.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <svtools/stringtransfer.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <i18nlangtag/languagetag.hxx> + +#define ACCESSIBLE_ACTION_COUNT 1 + +namespace +{ + /// @throws css::lang::IndexOutOfBoundsException + void checkActionIndex_Impl( sal_Int32 _nIndex ) + { + if ( _nIndex < 0 || _nIndex >= ACCESSIBLE_ACTION_COUNT ) + // only three actions + throw css::lang::IndexOutOfBoundsException(); + } +} + + +namespace accessibility +{ + + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + + // Ctor() and Dtor() + + AccessibleIconChoiceCtrlEntry::AccessibleIconChoiceCtrlEntry( SvtIconChoiceCtrl& _rIconCtrl, + sal_Int32 _nPos, + const Reference< XAccessible >& _xParent ) : + + AccessibleIconChoiceCtrlEntry_BASE ( m_aMutex ), + + m_pIconCtrl ( &_rIconCtrl ), + m_nIndex ( _nPos ), + m_nClientId ( 0 ), + m_xParent ( _xParent ) + + { + osl_atomic_increment( &m_refCount ); + { + Reference< XComponent > xComp( m_xParent, UNO_QUERY ); + if ( xComp.is() ) + xComp->addEventListener( this ); + } + osl_atomic_decrement( &m_refCount ); + } + + void AccessibleIconChoiceCtrlEntry::disposing( const css::lang::EventObject& _rSource ) + { + if ( _rSource.Source == m_xParent ) + { + dispose(); + OSL_ENSURE( !m_xParent.is() && ( m_pIconCtrl == nullptr ), "" ); + } + } + + AccessibleIconChoiceCtrlEntry::~AccessibleIconChoiceCtrlEntry() + { + if ( IsAlive_Impl() ) + { + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } + } + + tools::Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBox_Impl() const + { + tools::Rectangle aRect; + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry ) + aRect = m_pIconCtrl->GetBoundingBox( pEntry ); + + return aRect; + } + + AbsoluteScreenPixelRectangle AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen_Impl() const + { + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( !pEntry ) + return AbsoluteScreenPixelRectangle(); + tools::Rectangle aRect = m_pIconCtrl->GetBoundingBox( pEntry ); + AbsoluteScreenPixelPoint aTopLeft = m_pIconCtrl->GetWindowExtentsAbsolute().TopLeft(); + aTopLeft += AbsoluteScreenPixelPoint(aRect.TopLeft()); + return AbsoluteScreenPixelRectangle( aTopLeft, aRect.GetSize() ); + } + + bool AccessibleIconChoiceCtrlEntry::IsAlive_Impl() const + { + return ( !rBHelper.bDisposed && !rBHelper.bInDispose && m_pIconCtrl ); + } + + bool AccessibleIconChoiceCtrlEntry::IsShowing_Impl() const + { + bool bShowing = false; + Reference< XAccessibleContext > xParentContext = + m_xParent.is() ? m_xParent->getAccessibleContext() : Reference< XAccessibleContext >(); + if( xParentContext.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParentContext, uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = GetBoundingBox_Impl().Overlaps( VCLRectangle( xParentComp->getBounds() ) ); + } + + return bShowing; + } + + tools::Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBox() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBox_Impl(); + } + + AbsoluteScreenPixelRectangle AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBoxOnScreen_Impl(); + } + + void AccessibleIconChoiceCtrlEntry::EnsureIsAlive() const + { + if ( !IsAlive_Impl() ) + throw lang::DisposedException(); + } + + OUString AccessibleIconChoiceCtrlEntry::implGetText() + { + OUString sRet; + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry ) + sRet = pEntry->GetDisplayText(); + return sRet; + } + + Locale AccessibleIconChoiceCtrlEntry::implGetLocale() + { + return Application::GetSettings().GetUILanguageTag().getLocale(); + } + void AccessibleIconChoiceCtrlEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + + // XTypeProvider + + + Sequence< sal_Int8 > AccessibleIconChoiceCtrlEntry::getImplementationId() + { + return css::uno::Sequence<sal_Int8>(); + } + + // XComponent + + void SAL_CALL AccessibleIconChoiceCtrlEntry::disposing() + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // Send a disposing to all listeners. + if ( m_nClientId ) + { + sal_uInt32 nId = m_nClientId; + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + Reference< XComponent > xComp( m_xParent, UNO_QUERY ); + if ( xComp.is() ) + xComp->removeEventListener( this ); + + m_pIconCtrl = nullptr; + m_xParent = nullptr; + } + + // XServiceInfo + + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleIconChoiceControlEntry"; + } + + Sequence< OUString > SAL_CALL AccessibleIconChoiceCtrlEntry::getSupportedServiceNames() + { + return {"com.sun.star.accessibility.AccessibleContext", + "com.sun.star.accessibility.AccessibleComponent", + "com.sun.star.awt.AccessibleIconChoiceControlEntry"}; + } + + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::supportsService( const OUString& _rServiceName ) + { + return cppu::supportsService(this, _rServiceName); + } + + // XAccessible + + Reference< XAccessibleContext > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleContext( ) + { + EnsureIsAlive(); + return this; + } + + // XAccessibleContext + + sal_Int64 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChildCount( ) + { + return 0; // no children + } + + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChild( sal_Int64 ) + { + throw IndexOutOfBoundsException(); + } + + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleParent( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return m_xParent; + } + + sal_Int64 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleIndexInParent( ) + { + return m_nIndex; + } + + sal_Int16 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRole( ) + { + //return AccessibleRole::LABEL; + return AccessibleRole::LIST_ITEM; + } + + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleDescription( ) + { + // no description for every item + return OUString(); + } + + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleName( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return implGetText(); + } + + Reference< XAccessibleRelationSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRelationSet( ) + { + return new utl::AccessibleRelationSetHelper; + } + + sal_Int64 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleStateSet( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int64 nStateSet = 0; + + if ( IsAlive_Impl() ) + { + nStateSet |= AccessibleStateType::TRANSIENT; + nStateSet |= AccessibleStateType::SELECTABLE; + nStateSet |= AccessibleStateType::ENABLED; + nStateSet |= AccessibleStateType::SENSITIVE; + if ( IsShowing_Impl() ) + { + nStateSet |= AccessibleStateType::SHOWING; + nStateSet |= AccessibleStateType::VISIBLE; + } + + if ( m_pIconCtrl && m_pIconCtrl->GetCursor() == m_pIconCtrl->GetEntry( m_nIndex ) ) + nStateSet |= AccessibleStateType::SELECTED; + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; + } + + Locale SAL_CALL AccessibleIconChoiceCtrlEntry::getLocale( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return implGetLocale(); + } + + // XAccessibleComponent + + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::containsPoint( const awt::Point& rPoint ) + { + return tools::Rectangle( Point(), GetBoundingBox().GetSize() ).Contains( VCLPoint( rPoint ) ); + } + + Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleAtPoint( const awt::Point& ) + { + return Reference< XAccessible >(); + } + + awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getBounds( ) + { + return AWTRectangle( GetBoundingBox() ); + } + + awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocation( ) + { + return AWTPoint( GetBoundingBox().TopLeft() ); + } + + awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocationOnScreen( ) + { + return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); + } + + awt::Size SAL_CALL AccessibleIconChoiceCtrlEntry::getSize( ) + { + return AWTSize( GetBoundingBox().GetSize() ); + } + + void SAL_CALL AccessibleIconChoiceCtrlEntry::grabFocus( ) + { + // do nothing, because no focus for each item + } + + sal_Int32 AccessibleIconChoiceCtrlEntry::getForeground( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + + sal_Int32 AccessibleIconChoiceCtrlEntry::getBackground( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + + // XAccessibleText + + + awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterBounds( sal_Int32 _nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( ( 0 > _nIndex ) || ( implGetText().getLength() <= _nIndex ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( m_pIconCtrl ) + { + tools::Rectangle aItemRect = GetBoundingBox_Impl(); + tools::Rectangle aCharRect = m_pIconCtrl->GetEntryCharacterBounds( m_nIndex, _nIndex ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; + } + + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getIndexAtPoint( const awt::Point& aPoint ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nIndex = -1; + if ( m_pIconCtrl ) + { + vcl::ControlLayoutData aLayoutData; + tools::Rectangle aItemRect = GetBoundingBox_Impl(); + m_pIconCtrl->RecordLayoutData( &aLayoutData, aItemRect ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + nIndex = aLayoutData.GetIndexForPoint( aPnt ); + + tools::Long nLen = aLayoutData.m_aUnicodeBoundRects.size(); + for ( tools::Long i = 0; i < nLen; ++i ) + { + tools::Rectangle aRect = aLayoutData.GetCharacterBounds(i); + bool bInside = aRect.Contains( aPnt ); + + if ( bInside ) + break; + } + } + + return nIndex; + } + + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + OUString sText = implGetText(); + if ( ( 0 > nStartIndex ) || ( sText.getLength() <= nStartIndex ) + || ( 0 > nEndIndex ) || ( sText.getLength() <= nEndIndex ) ) + throw IndexOutOfBoundsException(); + + sal_Int32 nLen = nEndIndex - nStartIndex + 1; + ::svt::OStringTransfer::CopyString( sText.copy( nStartIndex, nLen ), m_pIconCtrl ); + + return true; + } + + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) + { + return false; + } + + // XAccessibleEventBroadcaster + + void SAL_CALL AccessibleIconChoiceCtrlEntry::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener ) + { + if (xListener.is()) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); + } + } + + void SAL_CALL AccessibleIconChoiceCtrlEntry::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener ) + { + if (!xListener.is()) + return; + + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + sal_Int32 nId = m_nClientId; + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClient( nId ); + } + } + + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCaretPosition( ) + { + return -1; + } + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setCaretPosition ( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + sal_Unicode SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacter( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); + } + css::uno::Sequence< css::beans::PropertyValue > SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return css::uno::Sequence< css::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterCount( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return implGetText().getLength(); + } + + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectedText( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OUString(); + } + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionStart( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return 0; + } + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionEnd( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return 0; + } + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getText( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return implGetText( ); + } + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ); + } + css::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + + + // XAccessibleAction + + sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionCount( ) + { + // three actions supported + return ACCESSIBLE_ACTION_COUNT; + } + + sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::doAccessibleAction( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + bool bRet = false; + checkActionIndex_Impl( nIndex ); + EnsureIsAlive(); + + SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex ); + if ( pEntry && !pEntry->IsSelected() ) + { + m_pIconCtrl->SetNoSelection(); + m_pIconCtrl->SetCursor( pEntry ); + bRet = true; + } + + return bRet; + } + + OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionDescription( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + checkActionIndex_Impl( nIndex ); + EnsureIsAlive(); + + return "Select"; + } + + Reference< XAccessibleKeyBinding > AccessibleIconChoiceCtrlEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) + { + Reference< XAccessibleKeyBinding > xRet; + checkActionIndex_Impl( nIndex ); + // ... which key? + return xRet; + } + +}// namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessiblelistbox.cxx b/accessibility/source/extended/accessiblelistbox.cxx new file mode 100644 index 0000000000..31330c8454 --- /dev/null +++ b/accessibility/source/extended/accessiblelistbox.cxx @@ -0,0 +1,508 @@ +/* -*- 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 <extended/accessiblelistbox.hxx> +#include <extended/accessiblelistboxentry.hxx> +#include <vcl/toolkit/treelistbox.hxx> +#include <vcl/toolkit/treelistentry.hxx> +#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 <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> + + +namespace accessibility +{ + + + // class AccessibleListBox ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + + // Ctor() and Dtor() + + AccessibleListBox::AccessibleListBox( SvTreeListBox const & _rListBox, const Reference< XAccessible >& _xParent ) : + + ImplInheritanceHelper( _rListBox.GetWindowPeer() ), + m_xParent( _xParent ) + { + } + + AccessibleListBox::~AccessibleListBox() + { + if ( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } + } + + void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + if ( !isAlive() ) + return; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::CheckboxToggle : + { + if ( !getListBox() || !getListBox()->HasFocus() ) + { + return; + } + AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent); + if(!pCurOpEntry) + { + return ; + } + uno::Any aValue; + aValue <<= AccessibleStateType::CHECKED; + + if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SvButtonState::Checked ) + { + pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue ); + } + else + { + pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() ); + } + break; + } + + case VclEventId::ListboxSelect : + { + OSL_FAIL("Debug: Treelist shouldn't use VclEventId::ListboxSelect"); + break; + } + + case VclEventId::ListboxTreeSelect: + { + if ( getListBox() && getListBox()->HasFocus() ) + { + if (m_xFocusedEntry.is()) + { + m_xFocusedEntry->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED, Any(), Any()); + } + } + } + break; + case VclEventId::ListboxTreeFocus: + { + VclPtr<SvTreeListBox> pBox = getListBox(); + if( pBox && pBox->HasFocus() ) + { + uno::Any aNewValue; + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + if (m_xFocusedEntry.is() && m_xFocusedEntry->GetSvLBoxEntry() == pEntry) + { + aNewValue <<= uno::Reference<XAccessible>(m_xFocusedEntry);; + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, uno::Any(), aNewValue ); + return ; + } + uno::Any aOldValue; + aOldValue <<= uno::Reference<XAccessible>(m_xFocusedEntry);; + + m_xFocusedEntry = implGetAccessible(*pEntry); + + aNewValue <<= uno::Reference<XAccessible>(m_xFocusedEntry); + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); + } + else + { + aNewValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aNewValue ); + } + } + } + break; + case VclEventId::ListboxItemRemoved: + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + RemoveChildEntries(pEntry); + } + else + { + // NULL means Clear() + for (auto const& entry : m_mapEntry) + { + uno::Any aNewValue; + uno::Any aOldValue; + aOldValue <<= uno::Reference<XAccessible>(entry.second); + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + for (auto const& entry : m_mapEntry) + { // release references ... + entry.second->dispose(); + } + m_mapEntry.clear(); + } + } + break; + + // #i92103# + case VclEventId::ItemExpanded : + case VclEventId::ItemCollapsed : + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + Reference<XAccessible> const xChild(implGetAccessible(*pEntry)); + const short nAccEvent = + ( rVclWindowEvent.GetId() == VclEventId::ItemExpanded ) + ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED + : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED; + uno::Any aListBoxEntry; + aListBoxEntry <<= xChild; + NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry ); + if ( getListBox() && getListBox()->HasFocus() ) + { + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry ); + } + } + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + } + } + + AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ) + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( !pEntry ) + pEntry = getListBox()->GetCurEntry(); + + if (m_xFocusedEntry.is() && pEntry && pEntry != m_xFocusedEntry->GetSvLBoxEntry()) + { + AccessibleListBoxEntry *const pAccCurOptionEntry = implGetAccessible(*pEntry).get(); + uno::Any aNewValue; + aNewValue <<= uno::Reference<XAccessible>(pAccCurOptionEntry); + NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add + + return pAccCurOptionEntry; + } + else + { + return m_xFocusedEntry.get(); + } + } + + void AccessibleListBox::RemoveChildEntries(SvTreeListEntry* pEntry) + { + MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); + if ( mi != m_mapEntry.end() ) + { + uno::Any aNewValue; + uno::Any aOldValue; + aOldValue <<= uno::Reference<XAccessible>(mi->second); + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + m_mapEntry.erase(mi); + } + + VclPtr<SvTreeListBox> pBox = getListBox(); + SvTreeListEntry* pEntryChild = pBox->FirstChild(pEntry); + while (pEntryChild) + { + RemoveChildEntries(pEntryChild); + pEntryChild = pEntryChild->NextSibling(); + } + } + + // XComponent + + void SAL_CALL AccessibleListBox::disposing() + { + ::osl::MutexGuard aGuard( m_aMutex ); + + m_mapEntry.clear(); + VCLXAccessibleComponent::disposing(); + m_xParent = nullptr; + } + + // XServiceInfo + + OUString SAL_CALL AccessibleListBox::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleTreeListBox"; + } + + Sequence< OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() + { + return {"com.sun.star.accessibility.AccessibleContext", + "com.sun.star.accessibility.AccessibleComponent", + "com.sun.star.awt.AccessibleTreeListBox"}; + } + + sal_Bool SAL_CALL AccessibleListBox::supportsService( const OUString& _rServiceName ) + { + return cppu::supportsService(this, _rServiceName); + } + + // XAccessible + + Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext( ) + { + ensureAlive(); + return this; + } + + // XAccessibleContext + + sal_Int64 SAL_CALL AccessibleListBox::getAccessibleChildCount( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + sal_Int32 nCount = 0; + VclPtr<SvTreeListBox> pSvTreeListBox = getListBox(); + if ( pSvTreeListBox ) + nCount = pSvTreeListBox->GetLevelChildCount( nullptr ); + + return nCount; + } + + Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int64 i ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + SvTreeListEntry* pEntry = getListBox()->GetEntry(i); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + // Solution: Set the parameter of the parent to null to let entry determine the parent by itself + //return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + //return new AccessibleListBoxEntry( *getListBox(), pEntry, nullptr ); + return implGetAccessible(*pEntry); + } + + Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + ensureAlive(); + return m_xParent; + } + + sal_Int32 AccessibleListBox::GetRoleType() const + { + sal_Int32 nCase = 0; + SvTreeListEntry* pEntry = getListBox()->GetEntry(0); + if ( pEntry ) + { + if( pEntry->HasChildrenOnDemand() || getListBox()->GetChildCount(pEntry) > 0 ) + { + nCase = 1; + return nCase; + } + } + + bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + if( !(getListBox()->GetTreeFlags() & SvTreeFlags::CHKBTN) ) + { + if( bHasButtons ) + nCase = 1; + } + else + { + if( bHasButtons ) + nCase = 2; + else + nCase = 3; + } + return nCase; + } + + sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole() + { + ::comphelper::OExternalLockGuard aGuard( this ); + + //o is: return AccessibleRole::TREE; + bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; + if(!bHasButtons && (getListBox()->GetTreeFlags() & SvTreeFlags::CHKBTN)) + return AccessibleRole::LIST; + else + if (GetRoleType() == 0) + return AccessibleRole::LIST; + else + return AccessibleRole::TREE; + } + + OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + return getListBox()->GetAccessibleDescription(); + } + + OUString SAL_CALL AccessibleListBox::getAccessibleName( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + return getListBox()->GetAccessibleName(); + } + + // XAccessibleSelection + + void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int64 nChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + SvTreeListEntry* pEntry = getListBox()->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + getListBox()->Select( pEntry ); + } + + sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int64 nChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + SvTreeListEntry* pEntry = getListBox()->GetEntry( nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return getListBox()->IsSelected( pEntry ); + } + + void SAL_CALL AccessibleListBox::clearAccessibleSelection( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + sal_Int32 nCount = getListBox()->GetLevelChildCount( nullptr ); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = getListBox()->GetEntry( i ); + if ( getListBox()->IsSelected( pEntry ) ) + getListBox()->Select( pEntry, false ); + } + } + + void SAL_CALL AccessibleListBox::selectAllAccessibleChildren( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + sal_Int32 nCount = getListBox()->GetLevelChildCount( nullptr ); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = getListBox()->GetEntry( i ); + if ( !getListBox()->IsSelected( pEntry ) ) + getListBox()->Select( pEntry ); + } + } + + sal_Int64 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount( ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + return getListBox()->GetSelectionCount(); + } + + Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int64 nSelCount= 0; + sal_Int32 nCount = getListBox()->GetLevelChildCount( nullptr ); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = getListBox()->GetEntry( i ); + if ( getListBox()->IsSelected( pEntry ) ) + ++nSelCount; + + if ( nSelCount == ( nSelectedChildIndex + 1 ) ) + { + // Solution: Set the parameter of the parent to null to let entry determine the parent by itself + //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); + //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, nullptr ); + xChild = implGetAccessible(*pEntry).get(); + break; + } + } + + return xChild; + } + + void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + ::comphelper::OExternalLockGuard aGuard( this ); + + SvTreeListEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + getListBox()->Select( pEntry, false ); + } + + void AccessibleListBox::FillAccessibleStateSet( sal_Int64& rStateSet ) + { + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + if ( getListBox() && isAlive() ) + { + rStateSet |= AccessibleStateType::FOCUSABLE; + rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS; + if ( getListBox()->GetSelectionMode() == SelectionMode::Multiple ) + rStateSet |= AccessibleStateType::MULTI_SELECTABLE; + } + } + + rtl::Reference<AccessibleListBoxEntry> AccessibleListBox::implGetAccessible(SvTreeListEntry & rEntry) + { + rtl::Reference<AccessibleListBoxEntry> pAccessible; + auto const it = m_mapEntry.find(&rEntry); + if (it != m_mapEntry.end()) + { + pAccessible = it->second; + } + else + { + pAccessible = new AccessibleListBoxEntry(*getListBox(), rEntry, *this); + m_mapEntry.emplace(&rEntry, pAccessible); + } + assert(pAccessible.is()); + return pAccessible; + } + + VclPtr< SvTreeListBox > AccessibleListBox::getListBox() const + { + return GetAs< SvTreeListBox >(); + } + +}// namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessiblelistboxentry.cxx b/accessibility/source/extended/accessiblelistboxentry.cxx new file mode 100644 index 0000000000..10433d8827 --- /dev/null +++ b/accessibility/source/extended/accessiblelistboxentry.cxx @@ -0,0 +1,1203 @@ +/* -*- 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 <extended/accessiblelistboxentry.hxx> +#include <extended/accessiblelistbox.hxx> +#include <vcl/toolkit/treelistbox.hxx> +#include <svtools/stringtransfer.hxx> +#include <vcl/toolkit/svlbitm.hxx> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <i18nlangtag/languagetag.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <toolkit/helper/convert.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <helper/accresmgr.hxx> +#include <strings.hrc> + +namespace accessibility +{ + // class AccessibleListBoxEntry ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + using namespace ::comphelper; + + + // Ctor() and Dtor() + + AccessibleListBoxEntry::AccessibleListBoxEntry( SvTreeListBox& _rListBox, + SvTreeListEntry& rEntry, + AccessibleListBox & rListBox) + : AccessibleListBoxEntry_BASE( m_aMutex ) + + , m_pTreeListBox( &_rListBox ) + , m_pSvLBoxEntry(&rEntry) + , m_nClientId( 0 ) + , m_wListBox(&rListBox) + { + m_pTreeListBox->AddEventListener( LINK( this, AccessibleListBoxEntry, WindowEventListener ) ); + _rListBox.FillEntryPath( m_pSvLBoxEntry, m_aEntryPath ); + } + + AccessibleListBoxEntry::~AccessibleListBoxEntry() + { + if ( IsAlive_Impl() ) + { + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } + } + + IMPL_LINK( AccessibleListBoxEntry, WindowEventListener, VclWindowEvent&, rEvent, void ) + { + OSL_ENSURE( rEvent.GetWindow() , "AccessibleListBoxEntry::WindowEventListener: no event window!" ); + OSL_ENSURE( rEvent.GetWindow() == m_pTreeListBox, "AccessibleListBoxEntry::WindowEventListener: where did this come from?" ); + + if ( m_pTreeListBox == nullptr ) + return; + + switch ( rEvent.GetId() ) + { + case VclEventId::CheckboxToggle: + { + // assert this object is represented as a checkbox on a11y layer (LABEL role is used for + // SvButtonState::Tristate, s. AccessibleListBoxEntry::getAccessibleRole) + assert(getAccessibleRole() == AccessibleRole::CHECK_BOX + || getAccessibleRole() == AccessibleRole::LABEL); + Any aOldValue; + Any aNewValue; + if (getAccessibleStateSet() & AccessibleStateType::CHECKED) + aNewValue <<= AccessibleStateType::CHECKED; + else + aOldValue <<= AccessibleStateType::CHECKED; + + NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); + break; + } + case VclEventId::ObjectDying : + { + if ( m_pTreeListBox ) + m_pTreeListBox->RemoveEventListener( LINK( this, AccessibleListBoxEntry, WindowEventListener ) ); + m_pTreeListBox = nullptr; + dispose(); + break; + } + default: break; + } + } + + void AccessibleListBoxEntry::NotifyAccessibleEvent( sal_Int16 _nEventId, + const css::uno::Any& _aOldValue, + const css::uno::Any& _aNewValue ) + { + Reference< uno::XInterface > xSource( *this ); + AccessibleEventObject aEventObj( xSource, _nEventId, _aNewValue, _aOldValue, -1 ); + + if (m_nClientId) + comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEventObj ); + } + + + tools::Rectangle AccessibleListBoxEntry::GetBoundingBox_Impl() const + { + tools::Rectangle aRect; + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + aRect = m_pTreeListBox->GetBoundingRect( pEntry ); + SvTreeListEntry* pParent = m_pTreeListBox->GetParent( pEntry ); + if ( pParent ) + { + // position relative to parent entry + Point aTopLeft = aRect.TopLeft(); + aTopLeft -= m_pTreeListBox->GetBoundingRect( pParent ).TopLeft(); + aRect = tools::Rectangle( aTopLeft, aRect.GetSize() ); + } + } + + return aRect; + } + + tools::Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen_Impl() const + { + tools::Rectangle aRect; + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + aRect = m_pTreeListBox->GetBoundingRect( pEntry ); + Point aTopLeft = aRect.TopLeft(); + aTopLeft += Point(m_pTreeListBox->GetWindowExtentsAbsolute().TopLeft()); + aRect = tools::Rectangle( aTopLeft, aRect.GetSize() ); + } + + return aRect; + } + + bool AccessibleListBoxEntry::IsAlive_Impl() const + { + return !rBHelper.bDisposed && !rBHelper.bInDispose && (m_pTreeListBox != nullptr); + } + + bool AccessibleListBoxEntry::IsShowing_Impl() const + { + Reference< XAccessible > xParent = implGetParentAccessible( ); + + bool bShowing = false; + Reference< XAccessibleContext > xParentContext = + xParent.is() ? xParent->getAccessibleContext() : Reference< XAccessibleContext >(); + if( xParentContext.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParentContext, uno::UNO_QUERY ); + if( xParentComp.is() ) + bShowing = GetBoundingBox_Impl().Overlaps( VCLRectangle( xParentComp->getBounds() ) ); + } + + return bShowing; + } + + tools::Rectangle AccessibleListBoxEntry::GetBoundingBox() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBox_Impl(); + } + + tools::Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + return GetBoundingBoxOnScreen_Impl(); + } + + void AccessibleListBoxEntry::CheckActionIndex(sal_Int32 nIndex) + { + if (nIndex < 0 || nIndex >= getAccessibleActionCount()) + throw css::lang::IndexOutOfBoundsException(); + } + + void AccessibleListBoxEntry::EnsureIsAlive() const + { + if ( !IsAlive_Impl() ) + throw lang::DisposedException(); + } + + OUString AccessibleListBoxEntry::implGetText() + { + OUString sRet; + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + sRet = SvTreeListBox::SearchEntryTextWithHeadTitle( pEntry ); + return sRet; + } + + Locale AccessibleListBoxEntry::implGetLocale() + { + return Application::GetSettings().GetUILanguageTag().getLocale(); + } + void AccessibleListBoxEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) + { + nStartIndex = 0; + nEndIndex = 0; + } + + // XTypeProvider + + + Sequence< sal_Int8 > AccessibleListBoxEntry::getImplementationId() + { + return css::uno::Sequence<sal_Int8>(); + } + + + // XComponent + + void SAL_CALL AccessibleListBoxEntry::disposing() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + Reference< XAccessible > xKeepAlive( this ); + + // Send a disposing to all listeners. + if ( m_nClientId ) + { + ::comphelper::AccessibleEventNotifier::TClientId nId = m_nClientId; + m_nClientId = 0; + ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); + } + + // clean up + m_wListBox.clear(); + + if ( m_pTreeListBox ) + m_pTreeListBox->RemoveEventListener( LINK( this, AccessibleListBoxEntry, WindowEventListener ) ); + m_pTreeListBox = nullptr; + } + + // XServiceInfo + + OUString SAL_CALL AccessibleListBoxEntry::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleTreeListBoxEntry"; + } + + Sequence< OUString > SAL_CALL AccessibleListBoxEntry::getSupportedServiceNames() + { + return {"com.sun.star.accessibility.AccessibleContext", + "com.sun.star.accessibility.AccessibleComponent", + "com.sun.star.awt.AccessibleTreeListBoxEntry"}; + } + + sal_Bool SAL_CALL AccessibleListBoxEntry::supportsService( const OUString& _rServiceName ) + { + return cppu::supportsService(this, _rServiceName); + } + + // XAccessible + + Reference< XAccessibleContext > SAL_CALL AccessibleListBoxEntry::getAccessibleContext( ) + { + EnsureIsAlive(); + return this; + } + + // XAccessibleContext + + sal_Int64 SAL_CALL AccessibleListBoxEntry::getAccessibleChildCount( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + sal_Int32 nCount = 0; + if ( pEntry ) + nCount = m_pTreeListBox->GetLevelChildCount( pEntry ); + + return nCount; + } + + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleChild( sal_Int64 i ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + SvTreeListEntry* pEntry = GetRealChild(i); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + rtl::Reference<AccessibleListBox> xListBox(m_wListBox); + assert(xListBox.is()); + + return xListBox->implGetAccessible(*pEntry); + } + + Reference< XAccessible > AccessibleListBoxEntry::implGetParentAccessible( ) const + { + Reference< XAccessible > xParent; + assert( m_aEntryPath.size() ); // invalid path + if ( m_aEntryPath.size() == 1 ) + { // we're a top level entry + // -> our parent is the tree listbox itself + if ( m_pTreeListBox ) + xParent = m_pTreeListBox->GetAccessible( ); + } + else + { // we have an entry as parent -> get its accessible + + // shorten our access path by one + std::deque< sal_Int32 > aParentPath( m_aEntryPath ); + aParentPath.pop_back(); + + // get the entry for this shortened access path + SvTreeListEntry* pParentEntry = m_pTreeListBox->GetEntryFromPath( aParentPath ); + assert(pParentEntry && "AccessibleListBoxEntry::implGetParentAccessible: could not obtain a parent entry!"); + if ( pParentEntry ) + { + rtl::Reference<AccessibleListBox> xListBox(m_wListBox); + assert(xListBox.is()); + return xListBox->implGetAccessible(*pParentEntry); + // the AccessibleListBoxEntry class will create its parent + // when needed + } + } + + return xParent; + } + + + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleParent( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + return implGetParentAccessible( ); + } + + sal_Int64 SAL_CALL AccessibleListBoxEntry::getAccessibleIndexInParent( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + OSL_ENSURE( !m_aEntryPath.empty(), "empty path" ); + return m_aEntryPath.empty() ? -1 : m_aEntryPath.back(); + } + + sal_Int32 AccessibleListBoxEntry::GetRoleType() const + { + sal_Int32 nCase = 0; + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(0); + if ( pEntry ) + { + if( pEntry->HasChildrenOnDemand() || m_pTreeListBox->GetChildCount(pEntry) > 0 ) + { + nCase = 1; + return nCase; + } + } + + bool bHasButtons = (m_pTreeListBox->GetStyle() & WB_HASBUTTONS)!=0; + if( !(m_pTreeListBox->GetTreeFlags() & SvTreeFlags::CHKBTN) ) + { + if( bHasButtons ) + nCase = 1; + } + else + { + if( bHasButtons ) + nCase = 2; + else + nCase = 3; + } + return nCase; + } + + sal_Int16 SAL_CALL AccessibleListBoxEntry::getAccessibleRole( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + SvTreeListBox* pBox = m_pTreeListBox; + if(!pBox) + return AccessibleRole::UNKNOWN; + + SvTreeFlags treeFlag = pBox->GetTreeFlags(); + if(treeFlag & SvTreeFlags::CHKBTN ) + { + SvTreeListEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath ); + SvButtonState eState = pBox->GetCheckButtonState( pEntry ); + switch( eState ) + { + case SvButtonState::Checked: + case SvButtonState::Unchecked: + return AccessibleRole::CHECK_BOX; + case SvButtonState::Tristate: + default: + return AccessibleRole::LABEL; + } + } + if (GetRoleType() == 0) + return AccessibleRole::LIST_ITEM; + else + //o is: return AccessibleRole::LABEL; + return AccessibleRole::TREE_ITEM; + } + + OUString SAL_CALL AccessibleListBoxEntry::getAccessibleDescription( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if( getAccessibleRole() == AccessibleRole::TREE_ITEM ) + { + return OUString(); + } + return m_pTreeListBox->GetEntryAccessibleDescription( + m_pTreeListBox->GetEntryFromPath(m_aEntryPath)); + } + + OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + return implGetText(); + } + + Reference< XAccessibleRelationSet > SAL_CALL AccessibleListBoxEntry::getAccessibleRelationSet( ) + { + Reference< XAccessibleRelationSet > xRelSet; + Reference< XAccessible > xParent; + if ( m_aEntryPath.size() > 1 ) // not a root entry + xParent = implGetParentAccessible(); + if ( xParent.is() ) + { + rtl::Reference<utl::AccessibleRelationSetHelper> pRelationSetHelper = new utl::AccessibleRelationSetHelper; + Sequence< Reference< XInterface > > aSequence { xParent }; + pRelationSetHelper->AddRelation( + AccessibleRelation( AccessibleRelationType::NODE_CHILD_OF, aSequence ) ); + xRelSet = pRelationSetHelper; + } + return xRelSet; + } + + sal_Int64 SAL_CALL AccessibleListBoxEntry::getAccessibleStateSet( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int64 nStateSet = 0; + + if ( IsAlive_Impl() ) + { + switch(getAccessibleRole()) + { + case AccessibleRole::LABEL: + nStateSet |= AccessibleStateType::TRANSIENT; + nStateSet |= AccessibleStateType::SELECTABLE; + nStateSet |= AccessibleStateType::ENABLED; + if (m_pTreeListBox->IsInplaceEditingEnabled()) + nStateSet |= AccessibleStateType::EDITABLE; + if (IsShowing_Impl()) + nStateSet |= AccessibleStateType::SHOWING; + break; + case AccessibleRole::CHECK_BOX: + nStateSet |= AccessibleStateType::TRANSIENT; + nStateSet |= AccessibleStateType::SELECTABLE; + nStateSet |= AccessibleStateType::ENABLED; + if (IsShowing_Impl()) + nStateSet |= AccessibleStateType::SHOWING; + break; + } + SvTreeListEntry *pEntry = m_pTreeListBox->GetEntryFromPath(m_aEntryPath); + if (pEntry) + m_pTreeListBox->FillAccessibleEntryStateSet(pEntry, nStateSet); + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; + } + + Locale SAL_CALL AccessibleListBoxEntry::getLocale( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return implGetLocale(); + } + + // XAccessibleComponent + + sal_Bool SAL_CALL AccessibleListBoxEntry::containsPoint( const awt::Point& rPoint ) + { + return tools::Rectangle( Point(), GetBoundingBox().GetSize() ).Contains( VCLPoint( rPoint ) ); + } + + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleAtPoint( const awt::Point& _aPoint ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( VCLPoint( _aPoint ) ); + if ( !pEntry ) + throw RuntimeException("AccessibleListBoxEntry::getAccessibleAtPoint - pEntry cannot be empty!"); + + Reference< XAccessible > xAcc; + rtl::Reference<AccessibleListBox> xListBox(m_wListBox); + assert(xListBox.is()); + auto pAccEntry = xListBox->implGetAccessible(*pEntry); + tools::Rectangle aRect = pAccEntry->GetBoundingBox_Impl(); + if ( aRect.Contains( VCLPoint( _aPoint ) ) ) + xAcc = pAccEntry.get(); + return xAcc; + } + + awt::Rectangle SAL_CALL AccessibleListBoxEntry::getBounds( ) + { + return AWTRectangle( GetBoundingBox() ); + } + + awt::Point SAL_CALL AccessibleListBoxEntry::getLocation( ) + { + return AWTPoint( GetBoundingBox().TopLeft() ); + } + + awt::Point SAL_CALL AccessibleListBoxEntry::getLocationOnScreen( ) + { + return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); + } + + awt::Size SAL_CALL AccessibleListBoxEntry::getSize( ) + { + return AWTSize( GetBoundingBox().GetSize() ); + } + + void SAL_CALL AccessibleListBoxEntry::grabFocus( ) + { + // do nothing, because no focus for each item + } + + sal_Int32 AccessibleListBoxEntry::getForeground( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + + sal_Int32 AccessibleListBoxEntry::getBackground( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + + // XAccessibleText + + + awt::Rectangle SAL_CALL AccessibleListBoxEntry::getCharacterBounds( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + vcl::ControlLayoutData aLayoutData; + tools::Rectangle aItemRect = GetBoundingBox(); + m_pTreeListBox->RecordLayoutData( &aLayoutData, aItemRect ); + tools::Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; + } + + sal_Int32 SAL_CALL AccessibleListBoxEntry::getIndexAtPoint( const awt::Point& aPoint ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + if(aPoint.X==0 && aPoint.Y==0) return 0; + + sal_Int32 nIndex = -1; + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + vcl::ControlLayoutData aLayoutData; + tools::Rectangle aItemRect = GetBoundingBox(); + m_pTreeListBox->RecordLayoutData( &aLayoutData, aItemRect ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + nIndex = aLayoutData.GetIndexForPoint( aPnt ); + } + + return nIndex; + } + + sal_Bool SAL_CALL AccessibleListBoxEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + OUString sText = implGetText(); + if ( ( 0 > nStartIndex ) || ( sText.getLength() <= nStartIndex ) + || ( 0 > nEndIndex ) || ( sText.getLength() <= nEndIndex ) ) + throw IndexOutOfBoundsException(); + + sal_Int32 nLen = nEndIndex - nStartIndex + 1; + ::svt::OStringTransfer::CopyString( sText.copy( nStartIndex, nLen ), m_pTreeListBox ); + + return true; + } + + sal_Bool SAL_CALL AccessibleListBoxEntry::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) + { + return false; + } + + // XAccessibleEventBroadcaster + + void SAL_CALL AccessibleListBoxEntry::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener ) + { + if (xListener.is()) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); + } + } + + void SAL_CALL AccessibleListBoxEntry::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener ) + { + if (!xListener.is()) + return; + + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + sal_Int32 nId = m_nClientId; + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClient( nId ); + + } + } + + // XAccessibleAction + + sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleActionCount( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // three actions supported + SvTreeFlags treeFlag = m_pTreeListBox->GetTreeFlags(); + bool bHasButtons = (m_pTreeListBox->GetStyle() & WB_HASBUTTONS)!=0; + if( (treeFlag & SvTreeFlags::CHKBTN) && !bHasButtons) + { + sal_Int16 role = getAccessibleRole(); + if ( role == AccessibleRole::CHECK_BOX ) + return 2; + else if ( role == AccessibleRole::LABEL ) + return 0; + } + else + return 1; + return 0; + } + + sal_Bool SAL_CALL AccessibleListBoxEntry::doAccessibleAction( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + bool bRet = false; + CheckActionIndex(nIndex); + EnsureIsAlive(); + + SvTreeFlags treeFlag = m_pTreeListBox->GetTreeFlags(); + if( nIndex == 0 && (treeFlag & SvTreeFlags::CHKBTN) ) + { + if(getAccessibleRole() == AccessibleRole::CHECK_BOX) + { + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + SvButtonState state = m_pTreeListBox->GetCheckButtonState( pEntry ); + if ( state == SvButtonState::Checked ) + m_pTreeListBox->SetCheckButtonState(pEntry, SvButtonState::Unchecked); + else if (state == SvButtonState::Unchecked) + m_pTreeListBox->SetCheckButtonState(pEntry, SvButtonState::Checked); + } + } + else if( (nIndex == 1 && (treeFlag & SvTreeFlags::CHKBTN) ) || (nIndex == 0) ) + { + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + if ( m_pTreeListBox->IsExpanded( pEntry ) ) + m_pTreeListBox->Collapse( pEntry ); + else + m_pTreeListBox->Expand( pEntry ); + bRet = true; + } + } + + return bRet; + } + + OUString SAL_CALL AccessibleListBoxEntry::getAccessibleActionDescription( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + CheckActionIndex(nIndex); + EnsureIsAlive(); + + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + SvButtonState state = m_pTreeListBox->GetCheckButtonState( pEntry ); + SvTreeFlags treeFlag = m_pTreeListBox->GetTreeFlags(); + if(nIndex == 0 && (treeFlag & SvTreeFlags::CHKBTN)) + { + if(getAccessibleRole() == AccessibleRole::CHECK_BOX) + { + if ( state == SvButtonState::Checked ) + return "UnCheck"; + else if (state == SvButtonState::Unchecked) + return "Check"; + } + else + { + //Sometimes, a List or Tree may have both checkbox and label at the same time + return OUString(); + } + } + else if( (nIndex == 1 && (treeFlag & SvTreeFlags::CHKBTN)) || nIndex == 0 ) + { + if( pEntry && (pEntry->HasChildren() || pEntry->HasChildrenOnDemand()) ) + return m_pTreeListBox->IsExpanded( pEntry ) ? + AccResId(STR_SVT_ACC_ACTION_COLLAPSE) : + AccResId(STR_SVT_ACC_ACTION_EXPAND); + return OUString(); + + } + throw IndexOutOfBoundsException(); + } + + Reference< XAccessibleKeyBinding > AccessibleListBoxEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) + { + Reference< XAccessibleKeyBinding > xRet; + CheckActionIndex(nIndex); + // ... which key? + return xRet; + } + + // XAccessibleSelection + + void SAL_CALL AccessibleListBoxEntry::selectAccessibleChild( sal_Int64 nChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + SvTreeListEntry* pEntry = GetRealChild(nChildIndex); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + m_pTreeListBox->Select( pEntry ); + } + + sal_Bool SAL_CALL AccessibleListBoxEntry::isAccessibleChildSelected( sal_Int64 nChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, nChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + return m_pTreeListBox->IsSelected( pEntry ); + } + + void SAL_CALL AccessibleListBoxEntry::clearAccessibleSelection( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException("AccessibleListBoxEntry::clearAccessibleSelection - pParent cannot be empty!"); + sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent ); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i ); + if ( m_pTreeListBox->IsSelected( pEntry ) ) + m_pTreeListBox->Select( pEntry, false ); + } + } + + void SAL_CALL AccessibleListBoxEntry::selectAllAccessibleChildren( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException("AccessibleListBoxEntry::selectAllAccessibleChildren - pParent cannot be empty!"); + sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent ); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i ); + if ( !m_pTreeListBox->IsSelected( pEntry ) ) + m_pTreeListBox->Select( pEntry ); + } + } + + sal_Int64 SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChildCount( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + sal_Int64 nSelCount = 0; + + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException("AccessibleListBoxEntry::getSelectedAccessibleChildCount - pParent cannot be empty!"); + sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent ); + for (sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i ); + if ( m_pTreeListBox->IsSelected( pEntry ) ) + ++nSelCount; + } + + return nSelCount; + } + + Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + sal_Int64 nSelCount = 0; + + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if ( !pParent ) + throw RuntimeException("AccessibleListBoxEntry::getSelectedAccessibleChild - pParent cannot be empty!"); + sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent ); + for (sal_Int32 i = 0; i < nCount; ++i ) + { + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i ); + if ( m_pTreeListBox->IsSelected( pEntry ) ) + ++nSelCount; + + if ( nSelCount == ( nSelectedChildIndex + 1 ) ) + { + rtl::Reference<AccessibleListBox> xListBox(m_wListBox); + assert(xListBox.is()); + xChild = xListBox->implGetAccessible(*pEntry).get(); + break; + } + } + + return xChild; + } + + void SAL_CALL AccessibleListBoxEntry::deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + EnsureIsAlive(); + + if (nSelectedChildIndex < 0 || nSelectedChildIndex >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, nSelectedChildIndex ); + if ( !pEntry ) + throw IndexOutOfBoundsException(); + + m_pTreeListBox->Select( pEntry, false ); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getCaretPosition( ) + { + return -1; + } + sal_Bool SAL_CALL AccessibleListBoxEntry::setCaretPosition ( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + sal_Unicode SAL_CALL AccessibleListBoxEntry::getCharacter( sal_Int32 nIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); + } + css::uno::Sequence< css::beans::PropertyValue > SAL_CALL AccessibleListBoxEntry::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return css::uno::Sequence< css::beans::PropertyValue >(); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getCharacterCount( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return implGetText().getLength(); + } + + OUString SAL_CALL AccessibleListBoxEntry::getSelectedText( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OUString(); + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionStart( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return 0; + } + sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionEnd( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return 0; + } + sal_Bool SAL_CALL AccessibleListBoxEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; + } + OUString SAL_CALL AccessibleListBoxEntry::getText( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return implGetText( ); + } + OUString SAL_CALL AccessibleListBoxEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ); + } + css::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); + } + css::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + EnsureIsAlive(); + + return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); + } + + // XAccessibleValue + + + Any AccessibleListBoxEntry::getCurrentValue( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + Any aValue; + sal_Int32 level = static_cast<sal_Int32>(m_aEntryPath.size()) - 1; + level = level < 0 ? 0: level; + aValue <<= level; + return aValue; + } + + + sal_Bool AccessibleListBoxEntry::setCurrentValue( const Any& aNumber ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + + bool bReturn = false; + SvTreeListBox* pBox = m_pTreeListBox; + if(getAccessibleRole() == AccessibleRole::CHECK_BOX) + { + SvTreeListEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath ); + if ( pEntry ) + { + sal_Int32 nValue(0), nValueMin(0), nValueMax(0); + aNumber >>= nValue; + getMinimumValue() >>= nValueMin; + getMaximumValue() >>= nValueMax; + + if ( nValue < nValueMin ) + nValue = nValueMin; + else if ( nValue > nValueMax ) + nValue = nValueMax; + + pBox->SetCheckButtonState(pEntry, static_cast<SvButtonState>(nValue) ); + bReturn = true; + } + } + + return bReturn; + } + + + Any AccessibleListBoxEntry::getMaximumValue( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Any aValue; + // SvTreeListBox* pBox = m_pTreeListBox; + switch(getAccessibleRole()) + { + case AccessibleRole::CHECK_BOX: + aValue <<= sal_Int32(1); + break; + case AccessibleRole::LABEL: + default: + break; + } + + return aValue; + } + + + Any AccessibleListBoxEntry::getMinimumValue( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Any aValue; + // SvTreeListBox* pBox = m_pTreeListBox; + switch(getAccessibleRole()) + { + case AccessibleRole::CHECK_BOX: + aValue <<= sal_Int32(0); + break; + case AccessibleRole::LABEL: + default: + break; + } + + return aValue; + } + + Any AccessibleListBoxEntry::getMinimumIncrement( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Any aValue; + switch(getAccessibleRole()) + { + case AccessibleRole::CHECK_BOX: + aValue <<= sal_Int32(1); + break; + case AccessibleRole::LABEL: + default: + break; + } + + return aValue; + } + + SvTreeListEntry* AccessibleListBoxEntry::GetRealChild(sal_Int32 nIndex) + { + SvTreeListEntry* pEntry = nullptr; + SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath ); + if (pParent) + { + pEntry = m_pTreeListBox->GetEntry( pParent, nIndex ); + if ( !pEntry && getAccessibleChildCount() > 0 ) + { + m_pTreeListBox->RequestingChildren(pParent); + pEntry = m_pTreeListBox->GetEntry( pParent, nIndex ); + } + } + return pEntry; + } + +}// namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibletabbar.cxx b/accessibility/source/extended/accessibletabbar.cxx new file mode 100644 index 0000000000..518d068d65 --- /dev/null +++ b/accessibility/source/extended/accessibletabbar.cxx @@ -0,0 +1,495 @@ +/* -*- 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 <extended/accessibletabbar.hxx> +#include <svtools/tabbar.hxx> +#include <extended/accessibletabbarpagelist.hxx> +#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/awt/XDevice.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <o3tl/safeint.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <toolkit/awt/vclxfont.hxx> +#include <toolkit/helper/convert.hxx> + + +namespace accessibility +{ + + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::accessibility; + using namespace ::comphelper; + + + + + AccessibleTabBar::AccessibleTabBar( TabBar* pTabBar ) + :ImplInheritanceHelper( pTabBar ) + { + if ( m_pTabBar ) + m_aAccessibleChildren.assign( m_pTabBar->GetAccessibleChildWindowCount() + 1, Reference< XAccessible >() ); + } + + + void AccessibleTabBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + Any aOldValue, aNewValue; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowEnabled: + { + aNewValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + aNewValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowDisabled: + { + aOldValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + aOldValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowGetFocus: + { + aNewValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowLoseFocus: + { + aOldValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowShow: + { + aNewValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + case VclEventId::WindowHide: + { + aOldValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + default: + { + AccessibleTabBarBase::ProcessWindowEvent( rVclWindowEvent ); + } + break; + } + } + + + void AccessibleTabBar::FillAccessibleStateSet( sal_Int64& rStateSet ) + { + if ( !m_pTabBar ) + return; + + if ( m_pTabBar->IsEnabled() ) + { + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + } + + rStateSet |= AccessibleStateType::FOCUSABLE; + + if ( m_pTabBar->HasFocus() ) + rStateSet |= AccessibleStateType::FOCUSED; + + rStateSet |= AccessibleStateType::VISIBLE; + + if ( m_pTabBar->IsVisible() ) + rStateSet |= AccessibleStateType::SHOWING; + + if ( m_pTabBar->GetStyle() & WB_SIZEABLE ) + rStateSet |= AccessibleStateType::RESIZABLE; + } + + + // OCommonAccessibleComponent + + + awt::Rectangle AccessibleTabBar::implGetBounds() + { + awt::Rectangle aBounds; + if ( m_pTabBar ) + aBounds = AWTRectangle( tools::Rectangle( m_pTabBar->GetPosPixel(), m_pTabBar->GetSizePixel() ) ); + + return aBounds; + } + + + // XComponent + + + void AccessibleTabBar::disposing() + { + AccessibleTabBarBase::disposing(); + + // dispose all children + for (const Reference<XAccessible>& i : m_aAccessibleChildren) + { + Reference< XComponent > xComponent( i, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren.clear(); + } + + + // XServiceInfo + + + OUString AccessibleTabBar::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleTabBar"; + } + + + sal_Bool AccessibleTabBar::supportsService( const OUString& rServiceName ) + { + return cppu::supportsService(this, rServiceName); + } + + + Sequence< OUString > AccessibleTabBar::getSupportedServiceNames() + { + return { "com.sun.star.awt.AccessibleTabBar" }; + } + + + // XAccessible + + + Reference< XAccessibleContext > AccessibleTabBar::getAccessibleContext( ) + { + OExternalLockGuard aGuard( this ); + + return this; + } + + + // XAccessibleContext + + + sal_Int64 AccessibleTabBar::getAccessibleChildCount() + { + OExternalLockGuard aGuard( this ); + + return m_aAccessibleChildren.size(); + } + + + Reference< XAccessible > AccessibleTabBar::getAccessibleChild( sal_Int64 i ) + { + OExternalLockGuard aGuard( this ); + + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + { + if ( m_pTabBar ) + { + sal_Int32 nCount = m_pTabBar->GetAccessibleChildWindowCount(); + + if ( i < nCount ) + { + vcl::Window* pChild = m_pTabBar->GetAccessibleChildWindow( static_cast<sal_uInt16>(i) ); + if ( pChild ) + xChild = pChild->GetAccessible(); + } + else if ( i == nCount ) + { + xChild = new AccessibleTabBarPageList( m_pTabBar, i ); + } + + // insert into child list + m_aAccessibleChildren[i] = xChild; + } + } + + return xChild; + } + + + Reference< XAccessible > AccessibleTabBar::getAccessibleParent( ) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pTabBar ) + { + vcl::Window* pParent = m_pTabBar->GetAccessibleParentWindow(); + if ( pParent ) + xParent = pParent->GetAccessible(); + } + + return xParent; + } + + + sal_Int64 AccessibleTabBar::getAccessibleIndexInParent( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int64 nIndexInParent = -1; + if ( m_pTabBar ) + { + vcl::Window* pParent = m_pTabBar->GetAccessibleParentWindow(); + if ( pParent ) + { + for ( sal_uInt16 i = 0, nCount = pParent->GetAccessibleChildWindowCount(); i < nCount; ++i ) + { + vcl::Window* pChild = pParent->GetAccessibleChildWindow( i ); + if ( pChild == static_cast< vcl::Window* >( m_pTabBar ) ) + { + nIndexInParent = i; + break; + } + } + } + } + + return nIndexInParent; + } + + + sal_Int16 AccessibleTabBar::getAccessibleRole( ) + { + OExternalLockGuard aGuard( this ); + + return AccessibleRole::PANEL; + } + + + OUString AccessibleTabBar::getAccessibleDescription( ) + { + OExternalLockGuard aGuard( this ); + + OUString sDescription; + if ( m_pTabBar ) + sDescription = m_pTabBar->GetAccessibleDescription(); + + return sDescription; + } + + + OUString AccessibleTabBar::getAccessibleName( ) + { + OExternalLockGuard aGuard( this ); + + OUString sName; + if ( m_pTabBar ) + sName = m_pTabBar->GetAccessibleName(); + + return sName; + } + + + Reference< XAccessibleRelationSet > AccessibleTabBar::getAccessibleRelationSet( ) + { + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; + } + + + sal_Int64 AccessibleTabBar::getAccessibleStateSet( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; + } + + + Locale AccessibleTabBar::getLocale( ) + { + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); + } + + + // XAccessibleComponent + + + Reference< XAccessible > AccessibleTabBar::getAccessibleAtPoint( const awt::Point& rPoint ) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xChild; + for ( size_t i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + Reference< XAccessible > xAcc = getAccessibleChild( i ); + if ( xAcc.is() ) + { + Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY ); + if ( xComp.is() ) + { + tools::Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.Contains( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; + } + + + void AccessibleTabBar::grabFocus( ) + { + OExternalLockGuard aGuard( this ); + + if ( m_pTabBar ) + m_pTabBar->GrabFocus(); + } + + + sal_Int32 AccessibleTabBar::getForeground( ) + { + OExternalLockGuard aGuard( this ); + + Color nColor; + if ( m_pTabBar ) + { + if ( m_pTabBar->IsControlForeground() ) + nColor = m_pTabBar->GetControlForeground(); + else + { + vcl::Font aFont; + if ( m_pTabBar->IsControlFont() ) + aFont = m_pTabBar->GetControlFont(); + else + aFont = m_pTabBar->GetFont(); + nColor = aFont.GetColor(); + } + } + + return sal_Int32(nColor); + } + + + sal_Int32 AccessibleTabBar::getBackground( ) + { + OExternalLockGuard aGuard( this ); + + Color nColor; + if ( m_pTabBar ) + { + if ( m_pTabBar->IsControlBackground() ) + nColor = m_pTabBar->GetControlBackground(); + else + nColor = m_pTabBar->GetBackground().GetColor(); + } + + return sal_Int32(nColor); + } + + + // XAccessibleExtendedComponent + + + Reference< awt::XFont > AccessibleTabBar::getFont( ) + { + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + if ( m_pTabBar ) + { + Reference< awt::XDevice > xDev( m_pTabBar->GetComponentInterface(), UNO_QUERY ); + if ( xDev.is() ) + { + vcl::Font aFont; + if ( m_pTabBar->IsControlFont() ) + aFont = m_pTabBar->GetControlFont(); + else + aFont = m_pTabBar->GetFont(); + rtl::Reference<VCLXFont> pVCLXFont = new VCLXFont; + pVCLXFont->Init( *xDev, aFont ); + xFont = pVCLXFont; + } + } + + return xFont; + } + + + OUString AccessibleTabBar::getTitledBorderText( ) + { + OExternalLockGuard aGuard( this ); + + OUString sText; + if ( m_pTabBar ) + sText = m_pTabBar->GetText(); + + return sText; + } + + + OUString AccessibleTabBar::getToolTipText( ) + { + OExternalLockGuard aGuard( this ); + + OUString sText; + if ( m_pTabBar ) + sText = m_pTabBar->GetQuickHelpText(); + + return sText; + } + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibletabbarbase.cxx b/accessibility/source/extended/accessibletabbarbase.cxx new file mode 100644 index 0000000000..1e213f0711 --- /dev/null +++ b/accessibility/source/extended/accessibletabbarbase.cxx @@ -0,0 +1,96 @@ +/* -*- 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 <extended/accessibletabbarbase.hxx> +#ifndef ACCESSIBILITY_EXT_ACCESSIBLETABBARPAGELIST +#include <extended/accessibletabbarpagelist.hxx> +#endif +#include <svtools/tabbar.hxx> +#include <vcl/vclevent.hxx> + + +namespace accessibility +{ + + +AccessibleTabBarBase::AccessibleTabBarBase( TabBar* pTabBar ) : + m_pTabBar( nullptr ) +{ + SetTabBarPointer( pTabBar ); +} + +AccessibleTabBarBase::~AccessibleTabBarBase() +{ + ClearTabBarPointer(); +} + +IMPL_LINK( AccessibleTabBarBase, WindowEventListener, VclWindowEvent&, rEvent, void ) +{ + vcl::Window* pEventWindow = rEvent.GetWindow(); + OSL_ENSURE( pEventWindow, "AccessibleTabBarBase::WindowEventListener: no window!" ); + + if( ( rEvent.GetId() == VclEventId::TabbarPageRemoved ) && + ( static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rEvent.GetData())) == TabBar::PAGE_NOT_FOUND ) && + (dynamic_cast<AccessibleTabBarPageList *>(this) == nullptr)) + { + return; + } + + if ( !pEventWindow->IsAccessibilityEventsSuppressed() || (rEvent.GetId() == VclEventId::ObjectDying) ) + ProcessWindowEvent( rEvent ); +} + +void AccessibleTabBarBase::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + if( rVclWindowEvent.GetId() == VclEventId::ObjectDying ) + ClearTabBarPointer(); +} + +// XComponent + +void AccessibleTabBarBase::disposing() +{ + OAccessibleExtendedComponentHelper::disposing(); + ClearTabBarPointer(); +} + +// private + +void AccessibleTabBarBase::SetTabBarPointer( TabBar* pTabBar ) +{ + OSL_ENSURE( !m_pTabBar, "AccessibleTabBarBase::SetTabBarPointer - multiple call" ); + m_pTabBar = pTabBar; + if( m_pTabBar ) + m_pTabBar->AddEventListener( LINK( this, AccessibleTabBarBase, WindowEventListener ) ); +} + +void AccessibleTabBarBase::ClearTabBarPointer() +{ + if( m_pTabBar ) + { + m_pTabBar->RemoveEventListener( LINK( this, AccessibleTabBarBase, WindowEventListener ) ); + m_pTabBar = nullptr; + } +} + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibletabbarpage.cxx b/accessibility/source/extended/accessibletabbarpage.cxx new file mode 100644 index 0000000000..eab2cf269c --- /dev/null +++ b/accessibility/source/extended/accessibletabbarpage.cxx @@ -0,0 +1,415 @@ +/* -*- 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 <extended/accessibletabbarpage.hxx> +#include <svtools/tabbar.hxx> +#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 <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <toolkit/helper/convert.hxx> +#include <i18nlangtag/languagetag.hxx> + + +namespace accessibility +{ + + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + using namespace ::comphelper; + + + + + AccessibleTabBarPage::AccessibleTabBarPage( TabBar* pTabBar, sal_uInt16 nPageId, const Reference< XAccessible >& rxParent ) + :ImplInheritanceHelper( pTabBar ) + ,m_nPageId( nPageId ) + ,m_xParent( rxParent ) + { + m_bShowing = IsShowing(); + m_bSelected = IsSelected(); + + if ( m_pTabBar ) + m_sPageText = m_pTabBar->GetPageText( m_nPageId ); + } + + + bool AccessibleTabBarPage::IsEnabled() + { + OExternalLockGuard aGuard( this ); + + bool bEnabled = false; + if ( m_pTabBar ) + bEnabled = m_pTabBar->IsPageEnabled( m_nPageId ); + + return bEnabled; + } + + + bool AccessibleTabBarPage::IsShowing() const + { + bool bShowing = false; + + if ( m_pTabBar && m_pTabBar->IsVisible() ) + bShowing = true; + + return bShowing; + } + + + bool AccessibleTabBarPage::IsSelected() const + { + bool bSelected = false; + + if ( m_pTabBar && m_pTabBar->GetCurPageId() == m_nPageId ) + bSelected = true; + + return bSelected; + } + + + void AccessibleTabBarPage::SetShowing( bool bShowing ) + { + if ( m_bShowing != bShowing ) + { + Any aOldValue, aNewValue; + if ( m_bShowing ) + aOldValue <<= AccessibleStateType::SHOWING; + else + aNewValue <<= AccessibleStateType::SHOWING; + m_bShowing = bShowing; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + } + + + void AccessibleTabBarPage::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 ); + } + } + + + void AccessibleTabBarPage::SetPageText( const OUString& sPageText ) + { + if ( m_sPageText != sPageText ) + { + Any aOldValue, aNewValue; + aOldValue <<= m_sPageText; + aNewValue <<= sPageText; + m_sPageText = sPageText; + NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } + } + + + void AccessibleTabBarPage::FillAccessibleStateSet( sal_Int64& rStateSet ) + { + if ( IsEnabled() ) + { + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + } + + rStateSet |= AccessibleStateType::VISIBLE; + + if ( IsShowing() ) + rStateSet |= AccessibleStateType::SHOWING; + + rStateSet |= AccessibleStateType::SELECTABLE; + + if ( IsSelected() ) + rStateSet |= AccessibleStateType::SELECTED; + } + + + // OCommonAccessibleComponent + + + awt::Rectangle AccessibleTabBarPage::implGetBounds() + { + awt::Rectangle aBounds; + if ( m_pTabBar ) + { + // get bounding rectangle relative to the AccessibleTabBar + aBounds = AWTRectangle( m_pTabBar->GetPageRect( m_nPageId ) ); + + // get position of the AccessibleTabBarPageList relative to the AccessibleTabBar + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComponent.is() ) + { + awt::Point aParentLoc = xParentComponent->getLocation(); + + // calculate bounding rectangle relative to the AccessibleTabBarPageList + aBounds.X -= aParentLoc.X; + aBounds.Y -= aParentLoc.Y; + } + } + } + + return aBounds; + } + + + // XComponent + + + void AccessibleTabBarPage::disposing() + { + AccessibleTabBarBase::disposing(); + m_sPageText.clear(); + } + + + // XServiceInfo + + + OUString AccessibleTabBarPage::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleTabBarPage"; + } + + + sal_Bool AccessibleTabBarPage::supportsService( const OUString& rServiceName ) + { + return cppu::supportsService(this, rServiceName); + } + + + Sequence< OUString > AccessibleTabBarPage::getSupportedServiceNames() + { + return { "com.sun.star.awt.AccessibleTabBarPage" }; + } + + + // XAccessible + + + Reference< XAccessibleContext > AccessibleTabBarPage::getAccessibleContext( ) + { + OExternalLockGuard aGuard( this ); + + return this; + } + + + // XAccessibleContext + + + sal_Int64 AccessibleTabBarPage::getAccessibleChildCount() + { + return 0; + } + + + Reference< XAccessible > AccessibleTabBarPage::getAccessibleChild( sal_Int64 ) + { + OExternalLockGuard aGuard( this ); + + throw IndexOutOfBoundsException(); + } + + + Reference< XAccessible > AccessibleTabBarPage::getAccessibleParent( ) + { + OExternalLockGuard aGuard( this ); + + return m_xParent; + } + + + sal_Int64 AccessibleTabBarPage::getAccessibleIndexInParent( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int64 nIndexInParent = -1; + if ( m_pTabBar ) + nIndexInParent = m_pTabBar->GetPagePos( m_nPageId ); + + return nIndexInParent; + } + + + sal_Int16 AccessibleTabBarPage::getAccessibleRole( ) + { + return AccessibleRole::PAGE_TAB; + } + + + OUString AccessibleTabBarPage::getAccessibleDescription( ) + { + OExternalLockGuard aGuard( this ); + + OUString sDescription; + if ( m_pTabBar ) + sDescription = m_pTabBar->GetHelpText( m_nPageId ); + + return sDescription; + } + + + OUString AccessibleTabBarPage::getAccessibleName( ) + { + OExternalLockGuard aGuard( this ); + + return m_sPageText; + } + + + Reference< XAccessibleRelationSet > AccessibleTabBarPage::getAccessibleRelationSet( ) + { + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; + } + + + sal_Int64 AccessibleTabBarPage::getAccessibleStateSet( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; + } + + + Locale AccessibleTabBarPage::getLocale( ) + { + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); + } + + + // XAccessibleComponent + + + Reference< XAccessible > AccessibleTabBarPage::getAccessibleAtPoint( const awt::Point& ) + { + return Reference< XAccessible >(); + } + + + void AccessibleTabBarPage::grabFocus( ) + { + // no focus + } + + + sal_Int32 AccessibleTabBarPage::getForeground( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + + + sal_Int32 AccessibleTabBarPage::getBackground( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + + + // XAccessibleExtendedComponent + + + Reference< awt::XFont > AccessibleTabBarPage::getFont( ) + { + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; + } + + + OUString AccessibleTabBarPage::getTitledBorderText( ) + { + OExternalLockGuard aGuard( this ); + + return m_sPageText; + } + + + OUString AccessibleTabBarPage::getToolTipText( ) + { + return OUString(); + } + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibletabbarpagelist.cxx b/accessibility/source/extended/accessibletabbarpagelist.cxx new file mode 100644 index 0000000000..8ad6b168eb --- /dev/null +++ b/accessibility/source/extended/accessibletabbarpagelist.cxx @@ -0,0 +1,670 @@ +/* -*- 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 <extended/accessibletabbarpagelist.hxx> +#include <svtools/tabbar.hxx> +#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 <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <o3tl/safeint.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <toolkit/helper/convert.hxx> +#include <i18nlangtag/languagetag.hxx> + + +namespace accessibility +{ + + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + using namespace ::comphelper; + + + + + AccessibleTabBarPageList::AccessibleTabBarPageList( TabBar* pTabBar, sal_Int32 nIndexInParent ) + :ImplInheritanceHelper( pTabBar ) + ,m_nIndexInParent( nIndexInParent ) + { + if ( m_pTabBar ) + m_aAccessibleChildren.assign( m_pTabBar->GetPageCount(), rtl::Reference< AccessibleTabBarPage >() ); + } + + + void AccessibleTabBarPageList::UpdateShowing( bool bShowing ) + { + for (const rtl::Reference<AccessibleTabBarPage>& xChild : m_aAccessibleChildren) + { + if ( xChild.is() ) + xChild->SetShowing( bShowing ); + } + } + + + void AccessibleTabBarPageList::UpdateSelected( sal_Int32 i, bool bSelected ) + { + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() ) + { + rtl::Reference< AccessibleTabBarPage > xChild( m_aAccessibleChildren[i] ); + if ( xChild.is() ) + xChild->SetSelected( bSelected ); + } + } + + + void AccessibleTabBarPageList::UpdatePageText( sal_Int32 i ) + { + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + return; + + if ( m_pTabBar ) + { + rtl::Reference< AccessibleTabBarPage > pAccessibleTabBarPage( m_aAccessibleChildren[i] ); + if ( pAccessibleTabBarPage.is() ) + { + OUString sPageText = m_pTabBar->GetPageText( m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) ) ); + pAccessibleTabBarPage->SetPageText( sPageText ); + } + } + } + + + void AccessibleTabBarPageList::InsertChild( sal_Int32 i ) + { + if ( i < 0 || o3tl::make_unsigned(i) > m_aAccessibleChildren.size() ) + return; + + // insert entry in child list + m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, rtl::Reference< AccessibleTabBarPage >() ); + + // send accessible child event + Reference< XAccessible > xChild( getAccessibleChild( i ) ); + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } + } + + + void AccessibleTabBarPageList::RemoveChild( sal_Int32 i ) + { + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + return; + + // get the accessible of the removed page + rtl::Reference< AccessibleTabBarPage > xChild( m_aAccessibleChildren[i] ); + + // remove entry in child list + m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i ); + + // send accessible child event + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aOldValue <<= uno::Reference<XAccessible>(xChild); + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + xChild->dispose(); + } + } + + + void AccessibleTabBarPageList::MoveChild( sal_Int32 i, sal_Int32 j ) + { + if ( !(i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() && + j >= 0 && o3tl::make_unsigned(j) <= m_aAccessibleChildren.size()) ) + return; + + if ( i < j ) + --j; + + // get the accessible of the moved page + rtl::Reference< AccessibleTabBarPage > xChild( m_aAccessibleChildren[i] ); + + // remove entry in child list at old position + m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i ); + + // insert entry in child list at new position + m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + j, xChild ); + } + + + void AccessibleTabBarPageList::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowEnabled: + { + Any aNewValue; + aNewValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue ); + aNewValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue ); + } + break; + case VclEventId::WindowDisabled: + { + Any aOldValue; + aOldValue <<= AccessibleStateType::ENABLED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() ); + aOldValue <<= AccessibleStateType::SENSITIVE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() ); + } + break; + case VclEventId::WindowShow: + { + Any aOldValue, aNewValue; + aNewValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + UpdateShowing( true ); + } + break; + case VclEventId::WindowHide: + { + Any aOldValue, aNewValue; + aOldValue <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + UpdateShowing( false ); + } + break; + case VclEventId::TabbarPageSelected: + { + // do nothing + } + break; + case VclEventId::TabbarPageActivated: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdateSelected( nPagePos, true ); + } + } + break; + case VclEventId::TabbarPageDeactivated: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdateSelected( nPagePos, false ); + } + } + break; + case VclEventId::TabbarPageInserted: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + InsertChild( nPagePos ); + } + } + break; + case VclEventId::TabbarPageRemoved: + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + + OExternalLockGuard aGuard( this ); + + if ( nPageId == TabBar::PAGE_NOT_FOUND ) + { + for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i ) + RemoveChild( i ); + } + else + { + for ( sal_Int64 i = 0, nCount = m_aAccessibleChildren.size(); i < nCount; ++i ) + { + sal_uInt16 nChildPageId = m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) ); + if (nPageId == nChildPageId) + { + RemoveChild( i ); + break; + } + } + } + } + } + break; + case VclEventId::TabbarPageMoved: + { + Pair* pPair = static_cast<Pair*>(rVclWindowEvent.GetData()); + if ( pPair ) + MoveChild( pPair->A(), pPair->B() ); + } + break; + case VclEventId::TabbarPageTextChanged: + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId ); + UpdatePageText( nPagePos ); + } + break; + default: + { + AccessibleTabBarBase::ProcessWindowEvent( rVclWindowEvent ); + } + break; + } + } + + + void AccessibleTabBarPageList::FillAccessibleStateSet( sal_Int64& rStateSet ) + { + if ( !m_pTabBar ) + return; + + if ( m_pTabBar->IsEnabled() ) + { + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + } + + rStateSet |= AccessibleStateType::VISIBLE; + + if ( m_pTabBar->IsVisible() ) + rStateSet |= AccessibleStateType::SHOWING; + } + + + // OCommonAccessibleComponent + + + awt::Rectangle AccessibleTabBarPageList::implGetBounds() + { + awt::Rectangle aBounds; + if ( m_pTabBar ) + aBounds = AWTRectangle( m_pTabBar->GetPageArea() ); + + return aBounds; + } + + + // XComponent + + + void AccessibleTabBarPageList::disposing() + { + AccessibleTabBarBase::disposing(); + + // dispose all children + for (const rtl::Reference<AccessibleTabBarPage>& xComponent : m_aAccessibleChildren) + { + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren.clear(); + } + + + // XServiceInfo + + + OUString AccessibleTabBarPageList::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleTabBarPageList"; + } + + + sal_Bool AccessibleTabBarPageList::supportsService( const OUString& rServiceName ) + { + return cppu::supportsService(this, rServiceName); + } + + + Sequence< OUString > AccessibleTabBarPageList::getSupportedServiceNames() + { + return { "com.sun.star.awt.AccessibleTabBarPageList" }; + } + + + // XAccessible + + + Reference< XAccessibleContext > AccessibleTabBarPageList::getAccessibleContext( ) + { + OExternalLockGuard aGuard( this ); + + return this; + } + + + // XAccessibleContext + + + sal_Int64 AccessibleTabBarPageList::getAccessibleChildCount() + { + OExternalLockGuard aGuard( this ); + + return m_aAccessibleChildren.size(); + } + + + Reference< XAccessible > AccessibleTabBarPageList::getAccessibleChild( sal_Int64 i ) + { + OExternalLockGuard aGuard( this ); + + return getAccessibleChildImpl(i); + } + + rtl::Reference< AccessibleTabBarPage > AccessibleTabBarPageList::getAccessibleChildImpl( sal_Int64 i ) + { + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + rtl::Reference< AccessibleTabBarPage > xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + { + if ( m_pTabBar ) + { + sal_uInt16 nPageId = m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) ); + + xChild = new AccessibleTabBarPage( m_pTabBar, nPageId, this ); + + // insert into child list + m_aAccessibleChildren[i] = xChild; + } + } + + return xChild; + } + + + Reference< XAccessible > AccessibleTabBarPageList::getAccessibleParent( ) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pTabBar ) + xParent = m_pTabBar->GetAccessible(); + + return xParent; + } + + + sal_Int64 AccessibleTabBarPageList::getAccessibleIndexInParent( ) + { + OExternalLockGuard aGuard( this ); + + return m_nIndexInParent; + } + + + sal_Int16 AccessibleTabBarPageList::getAccessibleRole( ) + { + return AccessibleRole::PAGE_TAB_LIST; + } + + + OUString AccessibleTabBarPageList::getAccessibleDescription( ) + { + return OUString(); + } + + + OUString AccessibleTabBarPageList::getAccessibleName( ) + { + return OUString(); + } + + + Reference< XAccessibleRelationSet > AccessibleTabBarPageList::getAccessibleRelationSet( ) + { + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; + } + + + sal_Int64 AccessibleTabBarPageList::getAccessibleStateSet( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; + } + + + Locale AccessibleTabBarPageList::getLocale( ) + { + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); + } + + + // XAccessibleComponent + + + Reference< XAccessible > AccessibleTabBarPageList::getAccessibleAtPoint( const awt::Point& rPoint ) + { + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xChild; + for ( size_t i = 0; i < m_aAccessibleChildren.size(); ++i ) + { + rtl::Reference< AccessibleTabBarPage > xAcc = getAccessibleChildImpl( i ); + if ( xAcc.is() ) + { + Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY ); + if ( xComp.is() ) + { + tools::Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.Contains( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; + } + + + void AccessibleTabBarPageList::grabFocus( ) + { + // no focus + } + + + sal_Int32 AccessibleTabBarPageList::getForeground( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; + } + + + sal_Int32 AccessibleTabBarPageList::getBackground( ) + { + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; + } + + + // XAccessibleExtendedComponent + + + Reference< awt::XFont > AccessibleTabBarPageList::getFont( ) + { + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; + } + + + OUString AccessibleTabBarPageList::getTitledBorderText( ) + { + return OUString(); + } + + + OUString AccessibleTabBarPageList::getToolTipText( ) + { + return OUString(); + } + + + // XAccessibleSelection + + + void AccessibleTabBarPageList::selectAccessibleChild( sal_Int64 nChildIndex ) + { + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + if ( m_pTabBar ) + { + m_pTabBar->SetCurPageId( m_pTabBar->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) ); + m_pTabBar->PaintImmediately(); + m_pTabBar->ActivatePage(); + m_pTabBar->Select(); + } + } + + + sal_Bool AccessibleTabBarPageList::isAccessibleChildSelected( sal_Int64 nChildIndex ) + { + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + bool bSelected = false; + if ( m_pTabBar && m_pTabBar->GetCurPageId() == m_pTabBar->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) ) + bSelected = true; + + return bSelected; + } + + + void AccessibleTabBarPageList::clearAccessibleSelection( ) + { + // This method makes no sense in a TabBar, and so does nothing. + } + + + void AccessibleTabBarPageList::selectAllAccessibleChildren( ) + { + selectAccessibleChild( 0 ); + } + + + sal_Int64 AccessibleTabBarPageList::getSelectedAccessibleChildCount( ) + { + return 1; + } + + + Reference< XAccessible > AccessibleTabBarPageList::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + + for ( sal_Int64 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ ) + { + if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) ) + { + xChild = getAccessibleChild( i ); + break; + } + } + + return xChild; + } + + + void AccessibleTabBarPageList::deselectAccessibleChild( sal_Int64 nChildIndex ) + { + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + // This method makes no sense in a TabBar, and so does nothing. + } + + +} // namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibletablistbox.cxx b/accessibility/source/extended/accessibletablistbox.cxx new file mode 100644 index 0000000000..88bffdc1b4 --- /dev/null +++ b/accessibility/source/extended/accessibletablistbox.cxx @@ -0,0 +1,112 @@ +/* -*- 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 <extended/accessibletablistbox.hxx> +#include <extended/accessibletablistboxtable.hxx> +#include <vcl/toolkit/svtabbx.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +namespace accessibility +{ + + + // class AccessibleTabListBox ----------------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + + // Ctor() and Dtor() + + AccessibleTabListBox::AccessibleTabListBox( const Reference< XAccessible >& rxParent, SvHeaderTabListBox& rBox ) + :AccessibleBrowseBox( rxParent, nullptr, rBox ) + ,m_pTabListBox( &rBox ) + { + osl_atomic_increment( &m_refCount ); + { + setCreator( this ); + } + osl_atomic_decrement( &m_refCount ); + } + + + AccessibleTabListBox::~AccessibleTabListBox() + { + if ( isAlive() ) + { + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } + } + + rtl::Reference<AccessibleBrowseBoxTable> AccessibleTabListBox::createAccessibleTable() + { + return new AccessibleTabListBoxTable( this, *m_pTabListBox ); + } + + // XInterface ----------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( AccessibleTabListBox, AccessibleBrowseBox, AccessibleTabListBox_Base ) + + // XTypeProvider -------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleTabListBox, AccessibleBrowseBox, AccessibleTabListBox_Base ) + + // XAccessibleContext --------------------------------------------------------- + + sal_Int64 SAL_CALL AccessibleTabListBox::getAccessibleChildCount() + { + return 2; // header and table + } + + Reference< XAccessibleContext > SAL_CALL AccessibleTabListBox::getAccessibleContext() + { + return this; + } + + Reference< XAccessible > SAL_CALL + AccessibleTabListBox::getAccessibleChild( sal_Int64 nChildIndex ) + { + SolarMethodGuard aGuard(getMutex()); + ensureIsAlive(); + + if ( nChildIndex < 0 || nChildIndex > 1 ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xRet; + if (nChildIndex == 0) + { + //! so far the actual implementation object only supports column headers + xRet = implGetHeaderBar( AccessibleBrowseBoxObjType::ColumnHeaderBar ); + } + else if (nChildIndex == 1) + xRet = implGetTable(); + + if ( !xRet.is() ) + throw RuntimeException("getAccessibleChild called with NULL xRet",getXWeak()); + + return xRet; + } + + +}// namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/accessibletablistboxtable.cxx b/accessibility/source/extended/accessibletablistboxtable.cxx new file mode 100644 index 0000000000..fe2d51b0ee --- /dev/null +++ b/accessibility/source/extended/accessibletablistboxtable.cxx @@ -0,0 +1,348 @@ +/* -*- 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 <extended/accessibletablistboxtable.hxx> +#include <extended/AccessibleBrowseBoxTableCell.hxx> +#include <extended/AccessibleBrowseBoxCheckBoxCell.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <vcl/toolkit/svtabbx.hxx> + +namespace accessibility +{ + + + // class AccessibleTabListBoxTable --------------------------------------------- + + using namespace ::com::sun::star::accessibility; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star; + + + // Ctor() and Dtor() + + AccessibleTabListBoxTable::AccessibleTabListBoxTable( const Reference< XAccessible >& rxParent, SvHeaderTabListBox& rBox ) : + + AccessibleBrowseBoxTable( rxParent, rBox ), + + m_pTabListBox ( &rBox ) + + { + m_pTabListBox->AddEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) ); + } + + AccessibleTabListBoxTable::~AccessibleTabListBoxTable() + { + if ( isAlive() ) + { + m_pTabListBox = nullptr; + + // increment ref count to prevent double call of Dtor + osl_atomic_increment( &m_refCount ); + dispose(); + } + } + + void AccessibleTabListBoxTable::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) + { + if ( !isAlive() ) + return; + + switch ( VclEventId nEventId = rVclWindowEvent.GetId(); nEventId ) + { + case VclEventId::ObjectDying : + { + m_pTabListBox->RemoveEventListener( LINK( this, AccessibleTabListBoxTable, WindowEventListener ) ); + m_pTabListBox = nullptr; + break; + } + + case VclEventId::ControlGetFocus : + case VclEventId::ControlLoseFocus : + { + uno::Any aOldValue, aNewValue; + if ( nEventId == VclEventId::ControlGetFocus ) + aNewValue <<= AccessibleStateType::FOCUSED; + else + aOldValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + break; + } + + case VclEventId::ListboxSelect : + { + // First send an event that tells the listeners of a + // modified selection. The active descendant event is + // send after that so that the receiving AT has time to + // read the text or name of the active child. + commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + if ( m_pTabListBox && m_pTabListBox->HasFocus() ) + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + sal_uInt16 nCol = m_pTabListBox->GetCurrColumn(); + Reference< XAccessible > xChild = + m_pTabListBox->CreateAccessibleCell( nRow, nCol ); + uno::Any aOldValue, aNewValue; + aNewValue <<= xChild; + commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue, aOldValue ); + } + } + break; + } + case VclEventId::WindowGetFocus : + { + uno::Any aOldValue, aNewValue; + aNewValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + break; + + } + case VclEventId::WindowLoseFocus : + { + uno::Any aOldValue, aNewValue; + aOldValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue, aOldValue ); + break; + } + case VclEventId::ListboxTreeSelect: + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if (pEntry) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + Reference< XAccessible > xChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() ); + TriState eState = TRISTATE_INDET; + if ( m_pTabListBox->IsCellCheckBox( nRow, m_pTabListBox->GetCurrColumn(), eState ) ) + { + AccessibleCheckBoxCell* pCell = static_cast< AccessibleCheckBoxCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } + else + { + AccessibleBrowseBoxTableCell* pCell = static_cast< AccessibleBrowseBoxTableCell* >( xChild.get() ); + pCell->commitEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } + } + } + break; + case VclEventId::ListboxTreeFocus: + { + if ( m_pTabListBox && m_pTabListBox->HasFocus() ) + { + uno::Any aOldValue, aNewValue; + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + m_xCurChild = m_pTabListBox->CreateAccessibleCell( nRow, m_pTabListBox->GetCurrColumn() ); + aNewValue <<= m_xCurChild; + commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aNewValue ,aOldValue); + } + else + { + aNewValue <<= AccessibleStateType::FOCUSED; + commitEvent( AccessibleEventId::STATE_CHANGED, aNewValue ,aOldValue); + } + } + } + break; + + case VclEventId::CheckboxToggle : + { + if ( m_pTabListBox && m_pTabListBox->HasFocus() ) + { + SvTreeListEntry* pEntry = static_cast< SvTreeListEntry* >( rVclWindowEvent.GetData() ); + if ( pEntry ) + { + sal_Int32 nRow = m_pTabListBox->GetEntryPos( pEntry ); + sal_uInt16 nCol = m_pTabListBox->GetCurrColumn(); + TriState eState = TRISTATE_INDET; + if ( m_pTabListBox->IsCellCheckBox( nRow, nCol, eState ) ) + { + Reference< XAccessible > xChild = + m_pTabListBox->CreateAccessibleCell( nRow, nCol ); + AccessibleCheckBoxCell* pCell = + static_cast< AccessibleCheckBoxCell* >( xChild.get() ); + pCell->SetChecked( SvHeaderTabListBox::IsItemChecked( pEntry, nCol ) ); + } + } + } + break; + } + + default: break; + } + } + + IMPL_LINK( AccessibleTabListBoxTable, WindowEventListener, VclWindowEvent&, rEvent, void ) + { + OSL_ENSURE( rEvent.GetWindow() && m_pTabListBox, "no event window" ); + ProcessWindowEvent( rEvent ); + } + // helpers -------------------------------------------------------------------- + + void AccessibleTabListBoxTable::ensureValidIndex( sal_Int64 _nIndex ) const + { + if ( ( _nIndex < 0 ) || ( _nIndex >= static_cast<sal_Int64>((implGetRowCount()) * static_cast<sal_Int64>(implGetColumnCount())))) + throw IndexOutOfBoundsException(); + } + + void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow, bool _bSelect ) + { + if ( m_pTabListBox ) + m_pTabListBox->SelectRow(_nRow, _bSelect); + } + + sal_Int32 AccessibleTabListBoxTable::implGetRowCount() const + { + return m_pTabListBox ? m_pTabListBox->GetEntryCount() : 0; + } + + sal_Int32 AccessibleTabListBoxTable::implGetColumnCount() const + { + return m_pTabListBox ? m_pTabListBox->GetColumnCount() : 0; + } + + sal_Int32 AccessibleTabListBoxTable::implGetSelRowCount() const + { + return m_pTabListBox ? m_pTabListBox->GetSelectionCount() : 0; + } + + sal_Int32 AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow ) const + { + if ( m_pTabListBox ) + { + sal_Int32 nRow = 0; + SvTreeListEntry* pEntry = m_pTabListBox->FirstSelected(); + while ( pEntry ) + { + if ( nRow == nSelRow ) + return m_pTabListBox->GetEntryPos( pEntry ); + pEntry = m_pTabListBox->NextSelected( pEntry ); + ++nRow; + } + } + + return 0; + } + + // XInterface & XTypeProvider + + IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) + IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleTabListBoxTable, AccessibleBrowseBoxTable, AccessibleTabListBoxTableImplHelper) + + // XServiceInfo + + OUString AccessibleTabListBoxTable::getImplementationName() + { + return "com.sun.star.comp.svtools.AccessibleTabListBoxTable"; + } + + // XAccessibleSelection + + void SAL_CALL AccessibleTabListBoxTable::selectAccessibleChild( sal_Int64 nChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + ensureValidIndex( nChildIndex ); + + implSelectRow( implGetRow( nChildIndex ), true ); + } + + sal_Bool SAL_CALL AccessibleTabListBoxTable::isAccessibleChildSelected( sal_Int64 nChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + ensureValidIndex( nChildIndex ); + + return m_pTabListBox && m_pTabListBox->IsRowSelected(implGetRow(nChildIndex)); + } + + void SAL_CALL AccessibleTabListBoxTable::clearAccessibleSelection( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + + m_pTabListBox->SetNoSelection(); + } + + void SAL_CALL AccessibleTabListBoxTable::selectAllAccessibleChildren( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + + m_pTabListBox->SelectAll(); + } + + sal_Int64 SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChildCount( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + + return static_cast<sal_Int64>(implGetColumnCount()) * static_cast<sal_Int64>(implGetSelRowCount()); + } + + Reference< XAccessible > SAL_CALL AccessibleTabListBoxTable::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + + const sal_Int32 nColCount = implGetColumnCount(); + + if (nColCount == 0) + throw IndexOutOfBoundsException(); + + const sal_Int32 nRow = implGetSelRow(nSelectedChildIndex / nColCount); + const sal_Int32 nColumn = nSelectedChildIndex % nColCount; + return getAccessibleCellAt( nRow, nColumn ); + } + + void SAL_CALL AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + ensureIsAlive(); + ensureValidIndex( nSelectedChildIndex ); + + implSelectRow( implGetRow( nSelectedChildIndex ), false ); + } + + +}// namespace accessibility + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/extended/textwindowaccessibility.cxx b/accessibility/source/extended/textwindowaccessibility.cxx new file mode 100644 index 0000000000..19c8d139c6 --- /dev/null +++ b/accessibility/source/extended/textwindowaccessibility.cxx @@ -0,0 +1,2256 @@ +/* -*- 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 <sal/config.h> +#include <sal/log.hxx> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/i18n/Boundary.hpp> +#include <cppuhelper/exc_hlp.hxx> +#include <extended/textwindowaccessibility.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <utility> +#include <vcl/svapp.hxx> +#include <vcl/txtattr.hxx> +#include <vcl/window.hxx> +#include <comphelper/diagnose_ex.hxx> +#include <toolkit/helper/convert.hxx> +#include <comphelper/sequence.hxx> + +#include <algorithm> +#include <memory> +#include <numeric> +#include <vector> + +namespace accessibility +{ +void SfxListenerGuard::startListening(::SfxBroadcaster & rNotifier) +{ + assert(m_pNotifier == nullptr && "called more than once"); + m_pNotifier = &rNotifier; + m_rListener.StartListening(*m_pNotifier, DuplicateHandling::Prevent); +} + +void SfxListenerGuard::endListening() +{ + if (m_pNotifier != nullptr) + { + m_rListener.EndListening(*m_pNotifier); + m_pNotifier = nullptr; + } +} + +void WindowListenerGuard::startListening(vcl::Window & rNotifier) +{ + assert(m_pNotifier == nullptr && "called more than once"); + m_pNotifier = &rNotifier; + m_pNotifier->AddEventListener(m_aListener); +} + +void WindowListenerGuard::endListening() +{ + if (m_pNotifier) + { + m_pNotifier->RemoveEventListener(m_aListener); + m_pNotifier = nullptr; + } +} + +Paragraph::Paragraph(::rtl::Reference< Document > xDocument, + Paragraphs::size_type nNumber): + ParagraphBase(m_aMutex), + m_xDocument(std::move(xDocument)), + m_nNumber(nNumber), + m_nClientId(0) +{ + m_aParagraphText = m_xDocument->retrieveParagraphText(this); +} + +void +Paragraph::numberChanged(bool bIncremented) +{ + if (bIncremented) + ++m_nNumber; + else + --m_nNumber; +} + +void Paragraph::textChanged() +{ + OUString aParagraphText = implGetText(); + css::uno::Any aOldValue, aNewValue; + if ( implInitTextChangedEvent( m_aParagraphText, aParagraphText, aOldValue, aNewValue ) ) + { + m_aParagraphText = aParagraphText; + notifyEvent(css::accessibility::AccessibleEventId:: + TEXT_CHANGED, + aOldValue, aNewValue); + } +} + +void Paragraph::notifyEvent(::sal_Int16 nEventId, + css::uno::Any const & rOldValue, + css::uno::Any const & rNewValue) +{ + if (m_nClientId) + comphelper::AccessibleEventNotifier::addEvent( m_nClientId, css::accessibility::AccessibleEventObject( + getXWeak(), + nEventId, rNewValue, rOldValue, -1) ); +} + +// virtual +css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL +Paragraph::getAccessibleContext() +{ + checkDisposed(); + return this; +} + +// virtual +sal_Int64 SAL_CALL Paragraph::getAccessibleChildCount() +{ + checkDisposed(); + return 0; +} + +// virtual +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +Paragraph::getAccessibleChild(sal_Int64) +{ + checkDisposed(); + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Paragraph::getAccessibleChild", + getXWeak()); +} + +// virtual +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +Paragraph::getAccessibleParent() +{ + checkDisposed(); + return m_xDocument->getAccessible(); +} + +// virtual +sal_Int64 SAL_CALL Paragraph::getAccessibleIndexInParent() +{ + checkDisposed(); + return m_xDocument->retrieveParagraphIndex(this); +} + +// virtual +::sal_Int16 SAL_CALL Paragraph::getAccessibleRole() +{ + checkDisposed(); + return css::accessibility::AccessibleRole::PARAGRAPH; +} + +// virtual +OUString SAL_CALL Paragraph::getAccessibleDescription() +{ + checkDisposed(); + return OUString(); +} + +// virtual +OUString SAL_CALL Paragraph::getAccessibleName() +{ + checkDisposed(); + return OUString(); +} + +// virtual +css::uno::Reference< css::accessibility::XAccessibleRelationSet > +SAL_CALL Paragraph::getAccessibleRelationSet() +{ + checkDisposed(); + return m_xDocument->retrieveParagraphRelationSet( this ); +} + +// virtual +sal_Int64 SAL_CALL Paragraph::getAccessibleStateSet() +{ + checkDisposed(); + + // FIXME Notification of changes (STATE_CHANGED) missing when + // m_rView.IsReadOnly() changes: + return m_xDocument->retrieveParagraphState(this); +} + +// virtual +css::lang::Locale SAL_CALL Paragraph::getLocale() +{ + checkDisposed(); + return m_xDocument->retrieveLocale(); +} + +// virtual +sal_Bool SAL_CALL Paragraph::containsPoint(css::awt::Point const & rPoint) +{ + checkDisposed(); + css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + false)); + return rPoint.X >= 0 && rPoint.X < aRect.Width + && rPoint.Y >= 0 && rPoint.Y < aRect.Height; +} + +// virtual +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +Paragraph::getAccessibleAtPoint(css::awt::Point const &) +{ + checkDisposed(); + return nullptr; +} + +// virtual +css::awt::Rectangle SAL_CALL Paragraph::getBounds() +{ + checkDisposed(); + return m_xDocument->retrieveParagraphBounds(this, false); +} + +// virtual +css::awt::Point SAL_CALL Paragraph::getLocation() +{ + checkDisposed(); + css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + false)); + return css::awt::Point(aRect.X, aRect.Y); +} + +// virtual +css::awt::Point SAL_CALL Paragraph::getLocationOnScreen() +{ + checkDisposed(); + css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + true)); + return css::awt::Point(aRect.X, aRect.Y); +} + +// virtual +css::awt::Size SAL_CALL Paragraph::getSize() +{ + checkDisposed(); + css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, + false)); + return css::awt::Size(aRect.Width, aRect.Height); +} + +// virtual +void SAL_CALL Paragraph::grabFocus() +{ + checkDisposed(); + VclPtr<vcl::Window> pWindow = m_xDocument->GetWindow(); + if ( pWindow ) + { + pWindow->GrabFocus(); + } + try + { + m_xDocument->changeParagraphSelection(this, 0, 0); + } + catch (const css::lang::IndexOutOfBoundsException &) + { + TOOLS_INFO_EXCEPTION("accessibility", "Paragraph::grabFocus: caught unexpected"); + } +} + +// virtual +sal_Int32 SAL_CALL Paragraph::getForeground() +{ + return 0; // TODO +} + +// virtual +sal_Int32 SAL_CALL Paragraph::getBackground() +{ + return 0; // TODO +} + +// virtual +::sal_Int32 SAL_CALL Paragraph::getCaretPosition() +{ + checkDisposed(); + return m_xDocument->retrieveParagraphCaretPosition(this); +} + +// virtual +sal_Bool SAL_CALL Paragraph::setCaretPosition(::sal_Int32 nIndex) +{ + checkDisposed(); + m_xDocument->changeParagraphSelection(this, nIndex, nIndex); + return true; +} + +// virtual +::sal_Unicode SAL_CALL Paragraph::getCharacter(::sal_Int32 nIndex) +{ + checkDisposed(); + return OCommonAccessibleText::implGetCharacter(implGetText(), nIndex); +} + +// virtual +css::uno::Sequence< css::beans::PropertyValue > SAL_CALL +Paragraph::getCharacterAttributes(::sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes) +{ + checkDisposed(); + return m_xDocument->retrieveCharacterAttributes( this, nIndex, aRequestedAttributes ); +} + +// virtual +css::awt::Rectangle SAL_CALL +Paragraph::getCharacterBounds(::sal_Int32 nIndex) +{ + checkDisposed(); + css::awt::Rectangle aBounds(m_xDocument->retrieveCharacterBounds(this, nIndex)); + css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false)); + aBounds.X -= aParaBounds.X; + aBounds.Y -= aParaBounds.Y; + return aBounds; +} + +// virtual +::sal_Int32 SAL_CALL Paragraph::getCharacterCount() +{ + checkDisposed(); + return implGetText().getLength(); +} + +// virtual +::sal_Int32 SAL_CALL +Paragraph::getIndexAtPoint(css::awt::Point const & rPoint) +{ + checkDisposed(); + css::awt::Point aPoint(rPoint); + css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false)); + aPoint.X += aParaBounds.X; + aPoint.Y += aParaBounds.Y; + return m_xDocument->retrieveCharacterIndex(this, aPoint); +} + +// virtual +OUString SAL_CALL Paragraph::getSelectedText() +{ + checkDisposed(); + + return OCommonAccessibleText::getSelectedText(); +} + +// virtual +::sal_Int32 SAL_CALL Paragraph::getSelectionStart() +{ + checkDisposed(); + return OCommonAccessibleText::getSelectionStart(); +} + +// virtual +::sal_Int32 SAL_CALL Paragraph::getSelectionEnd() +{ + checkDisposed(); + return OCommonAccessibleText::getSelectionEnd(); +} + +// virtual +sal_Bool SAL_CALL Paragraph::setSelection(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) +{ + checkDisposed(); + m_xDocument->changeParagraphSelection(this, nStartIndex, nEndIndex); + return true; +} + +// virtual +OUString SAL_CALL Paragraph::getText() +{ + checkDisposed(); + return implGetText(); +} + +// virtual +OUString SAL_CALL Paragraph::getTextRange(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) +{ + checkDisposed(); + return OCommonAccessibleText::implGetTextRange(implGetText(), nStartIndex, nEndIndex); +} + +// virtual +css::accessibility::TextSegment SAL_CALL Paragraph::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + checkDisposed(); + return OCommonAccessibleText::getTextAtIndex(nIndex, aTextType); +} + +// virtual +css::accessibility::TextSegment SAL_CALL Paragraph::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + checkDisposed(); + return OCommonAccessibleText::getTextBeforeIndex(nIndex, aTextType); +} + +// virtual +css::accessibility::TextSegment SAL_CALL Paragraph::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + checkDisposed(); + return OCommonAccessibleText::getTextBehindIndex(nIndex, aTextType); +} + +// virtual +sal_Bool SAL_CALL Paragraph::copyText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) +{ + checkDisposed(); + m_xDocument->copyParagraphText(this, nStartIndex, nEndIndex); + return true; +} + +// virtual +sal_Bool SAL_CALL Paragraph::scrollSubstringTo( sal_Int32, sal_Int32, css::accessibility::AccessibleScrollType ) +{ + return false; +} + +// virtual +sal_Bool SAL_CALL Paragraph::cutText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, true, false, + OUString()); + return true; +} + +// virtual +sal_Bool SAL_CALL Paragraph::pasteText(::sal_Int32 nIndex) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nIndex, nIndex, false, true, + OUString()); + return true; +} + +// virtual +sal_Bool SAL_CALL Paragraph::deleteText(::sal_Int32 nStartIndex, + ::sal_Int32 nEndIndex) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false, + OUString()); + return true; +} + +// virtual +sal_Bool SAL_CALL Paragraph::insertText(OUString const & rText, + ::sal_Int32 nIndex) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nIndex, nIndex, false, false, rText); + return true; +} + +// virtual +sal_Bool SAL_CALL +Paragraph::replaceText(::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, + OUString const & rReplacement) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false, + rReplacement); + return true; +} + +// virtual +sal_Bool SAL_CALL Paragraph::setAttributes( + ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, + css::uno::Sequence< css::beans::PropertyValue > const & rAttributeSet) +{ + checkDisposed(); + m_xDocument->changeParagraphAttributes(this, nStartIndex, nEndIndex, + rAttributeSet); + return true; +} + +// virtual +sal_Bool SAL_CALL Paragraph::setText(OUString const & rText) +{ + checkDisposed(); + m_xDocument->changeParagraphText(this, rText); + return true; +} + +// virtual +css::uno::Sequence< css::beans::PropertyValue > SAL_CALL +Paragraph::getDefaultAttributes(const css::uno::Sequence< OUString >&) +{ + checkDisposed(); + return {}; // default attributes are not supported by text engine +} + +// virtual +css::uno::Sequence< css::beans::PropertyValue > SAL_CALL +Paragraph::getRunAttributes(::sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes) +{ + checkDisposed(); + return m_xDocument->retrieveRunAttributes( this, Index, RequestedAttributes ); +} + +// virtual +::sal_Int32 SAL_CALL Paragraph::getLineNumberAtIndex( ::sal_Int32 nIndex ) +{ + checkDisposed(); + + ::sal_Int32 nLineNo = -1; + m_xDocument->retrieveParagraphLineBoundary( this, nIndex, &nLineNo ); + + return nLineNo; +} + +// virtual +css::accessibility::TextSegment SAL_CALL Paragraph::getTextAtLineNumber( ::sal_Int32 nLineNo ) +{ + checkDisposed(); + + css::i18n::Boundary aBoundary = + m_xDocument->retrieveParagraphBoundaryOfLine( this, nLineNo ); + + return css::accessibility::TextSegment( getTextRange(aBoundary.startPos, aBoundary.endPos), + aBoundary.startPos, aBoundary.endPos); +} + +// virtual +css::accessibility::TextSegment SAL_CALL Paragraph::getTextAtLineWithCaret( ) +{ + checkDisposed(); + + sal_Int32 nLineNo = getNumberOfLineWithCaret(); + + try { + return ( nLineNo >= 0 ) ? + getTextAtLineNumber( nLineNo ) : + css::accessibility::TextSegment(); + } catch (const css::lang::IndexOutOfBoundsException&) { + css::uno::Any anyEx = cppu::getCaughtException(); + throw css::lang::WrappedTargetRuntimeException( + "textwindowaccessibility.cxx:" + " Paragraph::getTextAtLineWithCaret", + getXWeak(), anyEx ); + } +} + +// virtual +::sal_Int32 SAL_CALL Paragraph::getNumberOfLineWithCaret( ) +{ + checkDisposed(); + return m_xDocument->retrieveParagraphLineWithCursor(this); +} + + +// virtual +void SAL_CALL Paragraph::addAccessibleEventListener( + css::uno::Reference< + css::accessibility::XAccessibleEventListener > const & rListener) +{ + if (!rListener.is()) + return; + + ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + aGuard.clear(); + rListener->disposing(css::lang::EventObject( + getXWeak())); + } + else + { + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, rListener ); + } +} + +// virtual +void SAL_CALL Paragraph::removeAccessibleEventListener( + css::uno::Reference< + css::accessibility::XAccessibleEventListener > const & rListener) +{ + comphelper::AccessibleEventNotifier::TClientId nId = 0; + { + osl::MutexGuard aGuard(rBHelper.rMutex); + if (rListener.is() && m_nClientId != 0 + && comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, rListener ) == 0) + { + nId = m_nClientId; + m_nClientId = 0; + } + } + if (nId != 0) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + comphelper::AccessibleEventNotifier::revokeClient(nId); + } +} + +// virtual +void SAL_CALL Paragraph::disposing() +{ + comphelper::AccessibleEventNotifier::TClientId nId = 0; + { + osl::MutexGuard aGuard(rBHelper.rMutex); + nId = m_nClientId; + m_nClientId = 0; + } + if (nId != 0) + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(nId, *this); +} + +// virtual +OUString Paragraph::implGetText() +{ + return m_xDocument->retrieveParagraphText(this); +} + +// virtual +css::lang::Locale Paragraph::implGetLocale() +{ + return m_xDocument->retrieveLocale(); +} + +// virtual +void Paragraph::implGetSelection(::sal_Int32 & rStartIndex, + ::sal_Int32 & rEndIndex) +{ + m_xDocument->retrieveParagraphSelection(this, &rStartIndex, &rEndIndex); +} + +// virtual +void Paragraph::implGetParagraphBoundary( const OUString& rText, + css::i18n::Boundary& rBoundary, + ::sal_Int32 nIndex ) +{ + ::sal_Int32 nLength = rText.getLength(); + + if ( implIsValidIndex( nIndex, nLength ) ) + { + rBoundary.startPos = 0; + rBoundary.endPos = nLength; + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } +} + +// virtual +void Paragraph::implGetLineBoundary( const OUString& rText, + css::i18n::Boundary& rBoundary, + ::sal_Int32 nIndex ) +{ + ::sal_Int32 nLength = rText.getLength(); + + if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength ) + { + css::i18n::Boundary aBoundary = + m_xDocument->retrieveParagraphLineBoundary( this, nIndex, nullptr ); + rBoundary.startPos = aBoundary.startPos; + rBoundary.endPos = aBoundary.endPos; + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } +} + + +void Paragraph::checkDisposed() +{ + ::osl::MutexGuard aGuard(rBHelper.rMutex); + if (!(rBHelper.bDisposed || rBHelper.bInDispose)) + return; + throw css::lang::DisposedException( + OUString(), getXWeak()); +} + +Document::Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine, + ::TextView & rView): + VCLXAccessibleComponent(pVclXWindow), + m_xAccessible(pVclXWindow), + m_rEngine(rEngine), + m_rView(rView), + m_aEngineListener(*this), + m_aViewListener(LINK(this, Document, WindowEventHandler)), + m_nViewOffset(0), + m_nViewHeight(0), + m_nVisibleBeginOffset(0), + m_nSelectionFirstPara(-1), + m_nSelectionFirstPos(-1), + m_nSelectionLastPara(-1), + m_nSelectionLastPos(-1), + m_bSelectionChangedNotification(false) +{} + +css::lang::Locale Document::retrieveLocale() +{ + SolarMutexGuard aGuard; + return m_rEngine.GetLocale(); +} + +::sal_Int32 Document::retrieveParagraphIndex(Paragraph const * pParagraph) +{ + ::osl::MutexGuard aInternalGuard(GetMutex()); + + // If a client holds on to a Paragraph that is no longer visible, it can + // happen that this Paragraph lies outside the range from m_aVisibleBegin + // to m_aVisibleEnd. In that case, return -1 instead of a valid index: + Paragraphs::iterator aPara(m_xParagraphs->begin() + + pParagraph->getNumber()); + return aPara < m_aVisibleBegin || aPara >= m_aVisibleEnd + ? -1 : static_cast< ::sal_Int32 >(aPara - m_aVisibleBegin); + // XXX numeric overflow +} + +::sal_Int64 Document::retrieveParagraphState(Paragraph const * pParagraph) +{ + ::osl::MutexGuard aInternalGuard(GetMutex()); + + // If a client holds on to a Paragraph that is no longer visible, it can + // happen that this Paragraph lies outside the range from m_aVisibleBegin + // to m_aVisibleEnd. In that case, it is neither VISIBLE nor SHOWING: + ::sal_Int64 nState + = css::accessibility::AccessibleStateType::ENABLED + | css::accessibility::AccessibleStateType::SENSITIVE + | css::accessibility::AccessibleStateType::FOCUSABLE + | css::accessibility::AccessibleStateType::MULTI_LINE; + if (!m_rView.IsReadOnly()) + nState |= css::accessibility::AccessibleStateType::EDITABLE; + Paragraphs::iterator aPara(m_xParagraphs->begin() + + pParagraph->getNumber()); + if (aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd) + { + nState + |= css::accessibility::AccessibleStateType::VISIBLE + | css::accessibility::AccessibleStateType::SHOWING; + if (aPara == m_aFocused) + nState |= css::accessibility::AccessibleStateType::FOCUSED; + } + return nState; +}; + +css::awt::Rectangle +Document::retrieveParagraphBounds(Paragraph const * pParagraph, + bool bAbsolute) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + + // If a client holds on to a Paragraph that is no longer visible (as it + // scrolled out the top of the view), it can happen that this Paragraph + // lies before m_aVisibleBegin. In that case, calculate the vertical + // position of the Paragraph starting at paragraph 0, otherwise optimize + // and start at m_aVisibleBegin: + Paragraphs::iterator aPara(m_xParagraphs->begin() + + pParagraph->getNumber()); + auto lAddHeight = [](const sal_Int32& rSum, const ParagraphInfo& rParagraph) { + return rSum + rParagraph.getHeight(); }; + ::sal_Int32 nPos; + if (aPara < m_aVisibleBegin) + nPos = std::accumulate(m_xParagraphs->begin(), aPara, sal_Int32(0), lAddHeight); + else + nPos = std::accumulate(m_aVisibleBegin, aPara, m_nViewOffset - m_nVisibleBeginOffset, lAddHeight); + + Point aOrig(0, 0); + if (bAbsolute) + aOrig = Point(m_rView.GetWindow()->OutputToAbsoluteScreenPixel(aOrig)); + + return css::awt::Rectangle( + static_cast< ::sal_Int32 >(aOrig.X()), + static_cast< ::sal_Int32 >(aOrig.Y()) + nPos - m_nViewOffset, + m_rView.GetWindow()->GetOutputSizePixel().Width(), aPara->getHeight()); + // XXX numeric overflow (3x) +} + +OUString +Document::retrieveParagraphText(Paragraph const * pParagraph) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + return m_rEngine.GetText(static_cast< ::sal_uInt32 >(pParagraph->getNumber())); + // numeric overflow cannot happen here +} + +void Document::retrieveParagraphSelection(Paragraph const * pParagraph, + ::sal_Int32 * pBegin, + ::sal_Int32 * pEnd) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::TextSelection const & rSelection = m_rView.GetSelection(); + Paragraphs::size_type nNumber = pParagraph->getNumber(); + TextPaM aStartPaM( rSelection.GetStart() ); + TextPaM aEndPaM( rSelection.GetEnd() ); + TextPaM aMinPaM( std::min( aStartPaM, aEndPaM ) ); + TextPaM aMaxPaM( std::max( aStartPaM, aEndPaM ) ); + + if ( nNumber >= aMinPaM.GetPara() && nNumber <= aMaxPaM.GetPara() ) + { + *pBegin = nNumber > aMinPaM.GetPara() ? 0 : aMinPaM.GetIndex(); + // XXX numeric overflow + *pEnd = nNumber < aMaxPaM.GetPara() + ? m_rEngine.GetText(static_cast< ::sal_uInt32 >(nNumber)).getLength() + : aMaxPaM.GetIndex(); + // XXX numeric overflow (3x) + + if ( aStartPaM > aEndPaM ) + std::swap( *pBegin, *pEnd ); + } + else + { + *pBegin = 0; + *pEnd = 0; + } +} + +::sal_Int32 Document::retrieveParagraphCaretPosition(Paragraph const * pParagraph) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::TextSelection const & rSelection = m_rView.GetSelection(); + Paragraphs::size_type nNumber = pParagraph->getNumber(); + TextPaM aEndPaM( rSelection.GetEnd() ); + + return aEndPaM.GetPara() == nNumber ? aEndPaM.GetIndex() : -1; +} + +css::awt::Rectangle +Document::retrieveCharacterBounds(Paragraph const * pParagraph, + ::sal_Int32 nIndex) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + sal_Int32 nLength = m_rEngine.GetText(nNumber).getLength(); + // XXX numeric overflow + if (nIndex < 0 || nIndex > nLength) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::retrieveCharacterAttributes", + getXWeak()); + css::awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( nIndex == nLength ) + { + aBounds = AWTRectangle( + m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, nIndex))); + } + else + { + ::tools::Rectangle aLeft( + m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, nIndex))); + // XXX numeric overflow + ::tools::Rectangle aRight( + m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, nIndex + 1))); + // XXX numeric overflow (2x) + // FIXME If the vertical extends of the two cursors do not match, assume + // nIndex is the last character on the line; the bounding box will then + // extend to m_rEngine.GetMaxTextWidth(): + ::sal_Int32 nWidth = (aLeft.Top() == aRight.Top() + && aLeft.Bottom() == aRight.Bottom()) + ? static_cast< ::sal_Int32 >(aRight.Left() - aLeft.Left()) + : static_cast< ::sal_Int32 >(m_rEngine.GetMaxTextWidth() + - aLeft.Left()); + // XXX numeric overflow (4x) + aBounds = css::awt::Rectangle(static_cast< ::sal_Int32 >(aLeft.Left()), + static_cast< ::sal_Int32 >(aLeft.Top() - m_nViewOffset), + nWidth, + static_cast< ::sal_Int32 >(aLeft.Bottom() + - aLeft.Top())); + // XXX numeric overflow (4x) + } + return aBounds; +} + +::sal_Int32 Document::retrieveCharacterIndex(Paragraph const * pParagraph, + css::awt::Point const & rPoint) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + ::TextPaM aPaM(m_rEngine.GetPaM(::Point(static_cast< tools::Long >(rPoint.X), + static_cast< tools::Long >(rPoint.Y)))); + // XXX numeric overflow (2x) + return aPaM.GetPara() == nNumber ? aPaM.GetIndex() : -1; + // XXX numeric overflow +} + +css::uno::Sequence< css::beans::PropertyValue > +Document::retrieveCharacterAttributes( + Paragraph const * pParagraph, ::sal_Int32 nIndex, + const css::uno::Sequence< OUString >& aRequestedAttributes) +{ + SolarMutexGuard aGuard; + + vcl::Font aFont = m_rEngine.GetFont(); + const sal_Int32 AttributeCount = 9; + std::vector< css::beans::PropertyValue > aAttribs; + aAttribs.reserve(AttributeCount); + + css::beans::PropertyValue aAttrib; + aAttrib.Handle = -1; + aAttrib.State = css::beans::PropertyState_DIRECT_VALUE; + + //character background color + aAttrib.Name = "CharBackColor"; + aAttrib.Value = mapFontColor( aFont.GetFillColor() ); + aAttribs.push_back(aAttrib); + + //character color + aAttrib.Name = "CharColor"; + //aAttrib.Value = mapFontColor( aFont.GetColor() ); + aAttrib.Value = mapFontColor( m_rEngine.GetTextColor() ); + aAttribs.push_back(aAttrib); + + //character font name + aAttrib.Name = "CharFontName"; + aAttrib.Value <<= aFont.GetFamilyName(); + aAttribs.push_back(aAttrib); + + //character height + aAttrib.Name = "CharHeight"; + aAttrib.Value <<= static_cast<sal_Int16>(aFont.GetFontHeight()); + aAttribs.push_back(aAttrib); + + //character posture + aAttrib.Name = "CharPosture"; + aAttrib.Value <<= static_cast<sal_Int16>(aFont.GetItalic()); + aAttribs.push_back(aAttrib); + + //character relief + /* + aAttrib.Name = "CharRelief"; + aAttrib.Value = css::uno::Any( (sal_Int16)aFont.GetRelief() ); + aAttribs.push_back(aAttrib); + */ + + //character strikeout + aAttrib.Name = "CharStrikeout"; + aAttrib.Value <<= static_cast<sal_Int16>(aFont.GetStrikeout()); + aAttribs.push_back(aAttrib); + + //character underline + aAttrib.Name = "CharUnderline"; + aAttrib.Value <<= static_cast<sal_Int16>(aFont.GetUnderline()); + aAttribs.push_back(aAttrib); + + //character weight + aAttrib.Name = "CharWeight"; + aAttrib.Value <<= static_cast<float>(aFont.GetWeight()); + aAttribs.push_back(aAttrib); + + //character alignment + aAttrib.Name = "ParaAdjust"; + aAttrib.Value <<= static_cast<sal_Int16>(m_rEngine.GetTextAlign()); + aAttribs.push_back(aAttrib); + + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + // nIndex can be equal to getLength(); + if (nIndex < 0 || nIndex > m_rEngine.GetText(nNumber).getLength()) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::retrieveCharacterAttributes", + getXWeak()); + + + // retrieve run attributes + tPropValMap aCharAttrSeq; + retrieveRunAttributesImpl( pParagraph, nIndex, aRequestedAttributes, aCharAttrSeq ); + + for (const css::beans::PropertyValue& rAttrib : aAttribs) + { + aCharAttrSeq[ rAttrib.Name ] = rAttrib; + } + + const css::uno::Sequence< css::beans::PropertyValue > aRes = comphelper::mapValuesToSequence( aCharAttrSeq ); + + // sort the attributes + auto nLength = static_cast<size_t>(aRes.getLength()); + std::unique_ptr<sal_Int32[]> pIndices( new sal_Int32[nLength] ); + std::iota(&pIndices[0], &pIndices[nLength], 0); + std::sort(&pIndices[0], &pIndices[nLength], + [&aRes](sal_Int32 a, sal_Int32 b) { return aRes[a].Name < aRes[b].Name; }); + + // create sorted sequences according to index array + std::vector<css::beans::PropertyValue> aNewValues; + aNewValues.reserve(nLength); + std::transform(&pIndices[0], &pIndices[nLength], std::back_inserter(aNewValues), + [&aRes](const sal_Int32 nIdx) { return aRes[nIdx]; }); + + return comphelper::containerToSequence(aNewValues); +} + +void Document::retrieveRunAttributesImpl( + Paragraph const * pParagraph, ::sal_Int32 Index, + const css::uno::Sequence< OUString >& RequestedAttributes, + tPropValMap& rRunAttrSeq) +{ + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >( pParagraph->getNumber() ); + ::TextPaM aPaM( nNumber, Index ); + // XXX numeric overflow + ::TextAttribFontColor const * pColor + = static_cast< ::TextAttribFontColor const * >( + m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTCOLOR ) ); + ::TextAttribFontWeight const * pWeight + = static_cast< ::TextAttribFontWeight const * >( + m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTWEIGHT ) ); + tPropValMap aRunAttrSeq; + if ( pColor ) + { + css::beans::PropertyValue aPropVal; + aPropVal.Name = "CharColor"; + aPropVal.Handle = -1; + aPropVal.Value = mapFontColor( pColor->GetColor() ); + aPropVal.State = css::beans::PropertyState_DIRECT_VALUE; + aRunAttrSeq[ aPropVal.Name ] = aPropVal; + } + if ( pWeight ) + { + css::beans::PropertyValue aPropVal; + aPropVal.Name = "CharWeight"; + aPropVal.Handle = -1; + aPropVal.Value = mapFontWeight( pWeight->getFontWeight() ); + aPropVal.State = css::beans::PropertyState_DIRECT_VALUE; + aRunAttrSeq[ aPropVal.Name ] = aPropVal; + } + if ( !RequestedAttributes.hasElements() ) + { + rRunAttrSeq = aRunAttrSeq; + } + else + { + for ( const OUString& rReqAttr : RequestedAttributes ) + { + tPropValMap::iterator aIter = aRunAttrSeq.find( rReqAttr ); + if ( aIter != aRunAttrSeq.end() ) + { + rRunAttrSeq[ (*aIter).first ] = (*aIter).second; + } + } + } +} + +css::uno::Sequence< css::beans::PropertyValue > +Document::retrieveRunAttributes( + Paragraph const * pParagraph, ::sal_Int32 Index, + const css::uno::Sequence< OUString >& RequestedAttributes) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard( GetMutex() ); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >( pParagraph->getNumber() ); + // XXX numeric overflow + if ( Index < 0 || Index >= m_rEngine.GetText(nNumber).getLength() ) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::retrieveRunAttributes", + getXWeak() ); + + tPropValMap aRunAttrSeq; + retrieveRunAttributesImpl( pParagraph, Index, RequestedAttributes, aRunAttrSeq ); + return comphelper::mapValuesToSequence( aRunAttrSeq ); +} + +void Document::changeParagraphText(Paragraph const * pParagraph, + OUString const & rText) +{ + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + changeParagraphText(nNumber, 0, m_rEngine.GetTextLen(nNumber), false, + false, rText); + } +} + +void Document::changeParagraphText(Paragraph const * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd, + bool bCut, bool bPaste, + OUString const & rText) +{ + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).getLength()) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::changeParagraphText", + getXWeak()); + changeParagraphText(nNumber, static_cast< ::sal_uInt16 >(nBegin), + static_cast< ::sal_uInt16 >(nEnd), bCut, bPaste, rText); + // XXX numeric overflow (2x) + } +} + +void Document::copyParagraphText(Paragraph const * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd) +{ + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).getLength()) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::copyParagraphText", + getXWeak()); + m_rView.SetSelection( + ::TextSelection(::TextPaM(nNumber, nBegin), + ::TextPaM(nNumber, nEnd))); + // XXX numeric overflow (2x) + m_rView.Copy(); + } +} + +void Document::changeParagraphAttributes( + Paragraph const * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd, + css::uno::Sequence< css::beans::PropertyValue > const & rAttributeSet) +{ + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).getLength()) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::changeParagraphAttributes", + getXWeak()); + + // FIXME The new attributes are added to any attributes already set, + // they do not replace the old attributes as required by + // XAccessibleEditableText.setAttributes: + for (const auto& rAttr : rAttributeSet) + if ( rAttr.Name == "CharColor" ) + m_rEngine.SetAttrib(::TextAttribFontColor( + mapFontColor(rAttr.Value)), + nNumber, nBegin, nEnd); + // XXX numeric overflow (2x) + else if ( rAttr.Name == "CharWeight" ) + m_rEngine.SetAttrib(::TextAttribFontWeight( + mapFontWeight(rAttr.Value)), + nNumber, nBegin, nEnd); + // XXX numeric overflow (2x) + } +} + +void Document::changeParagraphSelection(Paragraph const * pParagraph, + ::sal_Int32 nBegin, ::sal_Int32 nEnd) +{ + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >(pParagraph->getNumber()); + // XXX numeric overflow + if (nBegin < 0 || nBegin > nEnd + || nEnd > m_rEngine.GetText(nNumber).getLength()) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::changeParagraphSelection", + getXWeak()); + m_rView.SetSelection( + ::TextSelection(::TextPaM(nNumber, nBegin), + ::TextPaM(nNumber, nEnd))); + // XXX numeric overflow (2x) + } +} + +css::i18n::Boundary +Document::retrieveParagraphLineBoundary( Paragraph const * pParagraph, + ::sal_Int32 nIndex, ::sal_Int32 *pLineNo ) +{ + css::i18n::Boundary aBoundary; + aBoundary.startPos = nIndex; + aBoundary.endPos = nIndex; + + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard( GetMutex() ); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >( pParagraph->getNumber() ); + if ( nIndex < 0 || nIndex > m_rEngine.GetText( nNumber ).getLength() ) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::retrieveParagraphLineBoundary", + getXWeak() ); + ::sal_Int32 nLineStart = 0; + ::sal_Int32 nLineEnd = 0; + ::sal_uInt16 nLineCount = m_rEngine.GetLineCount( nNumber ); + for ( ::sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine ) + { + nLineStart = nLineEnd; + nLineEnd += m_rEngine.GetLineLen( nNumber, nLine ); + if ( nIndex >= nLineStart && ( ( nLine == nLineCount - 1 ) ? nIndex <= nLineEnd : nIndex < nLineEnd ) ) + { + aBoundary.startPos = nLineStart; + aBoundary.endPos = nLineEnd; + if( pLineNo ) + pLineNo[0] = nLine; + break; + } + } + } + + return aBoundary; +} + +css::i18n::Boundary +Document::retrieveParagraphBoundaryOfLine( Paragraph const * pParagraph, + ::sal_Int32 nLineNo ) +{ + css::i18n::Boundary aBoundary; + aBoundary.startPos = 0; + aBoundary.endPos = 0; + + SolarMutexGuard aGuard; + { + ::osl::MutexGuard aInternalGuard( GetMutex() ); + ::sal_uInt32 nNumber = static_cast< ::sal_uInt32 >( pParagraph->getNumber() ); + if ( nLineNo >= m_rEngine.GetLineCount( nNumber ) ) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::retrieveParagraphBoundaryOfLine", + getXWeak() ); + ::sal_Int32 nLineStart = 0; + ::sal_Int32 nLineEnd = 0; + for ( ::sal_Int32 nLine = 0; nLine <= nLineNo; ++nLine ) + { + nLineStart = nLineEnd; + nLineEnd += m_rEngine.GetLineLen( nNumber, nLine ); + } + + aBoundary.startPos = nLineStart; + aBoundary.endPos = nLineEnd; + } + + return aBoundary; +} + +sal_Int32 Document::retrieveParagraphLineWithCursor( Paragraph const * pParagraph ) +{ + SolarMutexGuard aGuard; + ::osl::MutexGuard aInternalGuard(GetMutex()); + ::TextSelection const & rSelection = m_rView.GetSelection(); + Paragraphs::size_type nNumber = pParagraph->getNumber(); + TextPaM aEndPaM( rSelection.GetEnd() ); + + return aEndPaM.GetPara() == nNumber + ? m_rView.GetLineNumberOfCursorInSelection() : -1; +} + + +css::uno::Reference< css::accessibility::XAccessibleRelationSet > +Document::retrieveParagraphRelationSet( Paragraph const * pParagraph ) +{ + ::osl::MutexGuard aInternalGuard( GetMutex() ); + + rtl::Reference<::utl::AccessibleRelationSetHelper> pRelationSetHelper = new ::utl::AccessibleRelationSetHelper(); + + Paragraphs::iterator aPara( m_xParagraphs->begin() + pParagraph->getNumber() ); + + if ( aPara > m_aVisibleBegin && aPara < m_aVisibleEnd ) + { + css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence { getAccessibleChild( aPara - 1 ) }; + css::accessibility::AccessibleRelation aRelation( css::accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM, aSequence ); + pRelationSetHelper->AddRelation( aRelation ); + } + + if ( aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd -1 ) + { + css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence { getAccessibleChild( aPara + 1 ) }; + css::accessibility::AccessibleRelation aRelation( css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence ); + pRelationSetHelper->AddRelation( aRelation ); + } + + return pRelationSetHelper; +} + +// virtual +sal_Int64 SAL_CALL Document::getAccessibleChildCount() +{ + ::comphelper::OExternalLockGuard aGuard(this); + init(); + return m_aVisibleEnd - m_aVisibleBegin; +} + +// virtual +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +Document::getAccessibleChild(sal_Int64 i) +{ + ::comphelper::OExternalLockGuard aGuard(this); + init(); + if (i < 0 || i >= m_aVisibleEnd - m_aVisibleBegin) + throw css::lang::IndexOutOfBoundsException( + "textwindowaccessibility.cxx:" + " Document::getAccessibleChild", + getXWeak()); + return getAccessibleChild(m_aVisibleBegin + + static_cast< Paragraphs::size_type >(i)); +} + +// virtual +::sal_Int16 SAL_CALL Document::getAccessibleRole() +{ + return css::accessibility::AccessibleRole::TEXT_FRAME; +} + +// virtual +css::uno::Reference< css::accessibility::XAccessible > SAL_CALL +Document::getAccessibleAtPoint(css::awt::Point const & rPoint) +{ + ::comphelper::OExternalLockGuard aGuard(this); + init(); + if (rPoint.X >= 0 + && rPoint.X < m_rView.GetWindow()->GetOutputSizePixel().Width() + && rPoint.Y >= 0 && rPoint.Y < m_nViewHeight) + { + ::sal_Int32 nOffset = m_nViewOffset + rPoint.Y; // XXX numeric overflow + ::sal_Int32 nPos = m_nViewOffset - m_nVisibleBeginOffset; + for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd; + ++aIt) + { + nPos += aIt->getHeight(); // XXX numeric overflow + if (nOffset < nPos) + return getAccessibleChild(aIt); + } + } + return nullptr; +} +void Document::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + if (!m_rView.IsReadOnly()) + rStateSet |= css::accessibility::AccessibleStateType::EDITABLE; +} + +void Document::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) +{ + if( getAccessibleParent()->getAccessibleContext()->getAccessibleRole() == css::accessibility::AccessibleRole::SCROLL_PANE ) + { + css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence { getAccessibleParent() }; + rRelationSet.AddRelation( css::accessibility::AccessibleRelation( css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); + } + else + { + VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet); + } +} +// virtual +void SAL_CALL Document::disposing() +{ + m_aEngineListener.endListening(); + m_aViewListener.endListening(); + if (m_xParagraphs != nullptr) + disposeParagraphs(); + VCLXAccessibleComponent::disposing(); +} + +// virtual +void Document::Notify(::SfxBroadcaster &, ::SfxHint const & rHint) +{ + const TextHint* pTextHint = dynamic_cast<const TextHint*>(&rHint); + if (!pTextHint) + return; + + ::TextHint const & rTextHint = *pTextHint; + switch (rTextHint.GetId()) + { + case SfxHintId::TextParaInserted: + case SfxHintId::TextParaRemoved: + // SfxHintId::TextParaInserted and SfxHintId::TextParaRemoved are sent at + // "unsafe" times (when the text engine has not yet re-formatted its + // content), so that for example calling ::TextEngine::GetTextHeight + // from within the code that handles SfxHintId::TextParaInserted causes + // trouble within the text engine. Therefore, these hints are just + // buffered until a following ::TextEngine::FormatDoc causes a + // SfxHintId::TextFormatted to come in: + case SfxHintId::TextFormatPara: + // ::TextEngine::FormatDoc sends a sequence of + // SfxHintId::TextFormatParas, followed by an optional + // SfxHintId::TextHeightChanged, followed in all cases by one + // SfxHintId::TextFormatted. Only the SfxHintId::TextFormatParas contain + // the numbers of the affected paragraphs, but they are sent + // before the changes are applied. Therefore, SfxHintId::TextFormatParas + // are just buffered until another hint comes in: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + m_aParagraphNotifications.push(rTextHint); + break; + } + case SfxHintId::TextFormatted: + case SfxHintId::TextHeightChanged: + case SfxHintId::TextModified: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + handleParagraphNotifications(); + break; + } + case SfxHintId::TextViewScrolled: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + handleParagraphNotifications(); + + ::sal_Int32 nOffset = static_cast< ::sal_Int32 >( + m_rView.GetStartDocPos().Y()); + // XXX numeric overflow + if (nOffset != m_nViewOffset) + { + m_nViewOffset = nOffset; + + Paragraphs::iterator aOldVisibleBegin( + m_aVisibleBegin); + Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); + + determineVisibleRange(); + + notifyVisibleRangeChanges(aOldVisibleBegin, + aOldVisibleEnd, + m_xParagraphs->end()); + } + break; + } + case SfxHintId::TextViewSelectionChanged: + case SfxHintId::TextViewCaretChanged: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + if (m_aParagraphNotifications.empty()) + { + handleSelectionChangeNotification(); + } + else + { + // SfxHintId::TextViewSelectionChanged is sometimes sent at + // "unsafe" times (when the text engine has not yet re- + // formatted its content), so that for example calling + // ::TextEngine::GetTextHeight from within the code that + // handles a previous SfxHintId::TextParaInserted causes + // trouble within the text engine. Therefore, these + // hints are just buffered (along with + // SfxHintId::TextParaInserted/REMOVED/FORMATPARA) until a + // following ::TextEngine::FormatDoc causes a + // SfxHintId::TextFormatted to come in: + m_bSelectionChangedNotification = true; + } + break; + } + default: break; + } +} + +IMPL_LINK(Document, WindowEventHandler, ::VclWindowEvent&, rEvent, void) +{ + switch (rEvent.GetId()) + { + case VclEventId::WindowResize: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + + ::sal_Int32 nHeight = static_cast< ::sal_Int32 >( + m_rView.GetWindow()->GetOutputSizePixel().Height()); + // XXX numeric overflow + if (nHeight != m_nViewHeight) + { + m_nViewHeight = nHeight; + + Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin); + Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); + + determineVisibleRange(); + + notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd, + m_xParagraphs->end()); + } + break; + } + case VclEventId::WindowGetFocus: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + //to enable the PARAGRAPH to get focus for multiline edit + sal_Int64 count = getAccessibleChildCount(); + bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1; + if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty) + { + Paragraphs::iterator aTemp = bEmpty ? m_aVisibleBegin : m_aFocused; + ::rtl::Reference< Paragraph > xParagraph(getParagraph(aTemp)); + if (xParagraph.is()) + { + xParagraph->notifyEvent( + css::accessibility::AccessibleEventId:: + STATE_CHANGED, + css::uno::Any(), + css::uno::Any( + css::accessibility::AccessibleStateType:: + FOCUSED)); + } + } + break; + } + case VclEventId::WindowLoseFocus: + { + ::osl::MutexGuard aInternalGuard(GetMutex()); + if (!isAlive()) + break; + //to enable the PARAGRAPH to get focus for multiline edit + sal_Int64 count = getAccessibleChildCount(); + bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1; + if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty) + { + Paragraphs::iterator aTemp = bEmpty ? m_aVisibleBegin : m_aFocused; + ::rtl::Reference< Paragraph > xParagraph(getParagraph(aTemp)); + if (xParagraph.is()) + xParagraph->notifyEvent( + css::accessibility::AccessibleEventId:: + STATE_CHANGED, + css::uno::Any( + css::accessibility::AccessibleStateType:: + FOCUSED), + css::uno::Any()); + } + break; + } + default: break; + } +} + +void Document::init() +{ + if (m_xParagraphs != nullptr) + return; + + const ::sal_uInt32 nCount = m_rEngine.GetParagraphCount(); + m_xParagraphs.reset(new Paragraphs); + m_xParagraphs->reserve(static_cast< Paragraphs::size_type >(nCount)); + // numeric overflow is harmless here + for (::sal_uInt32 i = 0; i < nCount; ++i) + m_xParagraphs->push_back(ParagraphInfo(static_cast< ::sal_Int32 >( + m_rEngine.GetTextHeight(i)))); + // XXX numeric overflow + m_nViewOffset = static_cast< ::sal_Int32 >( + m_rView.GetStartDocPos().Y()); // XXX numeric overflow + m_nViewHeight = static_cast< ::sal_Int32 >( + m_rView.GetWindow()->GetOutputSizePixel().Height()); + // XXX numeric overflow + determineVisibleRange(); + m_nSelectionFirstPara = -1; + m_nSelectionFirstPos = -1; + m_nSelectionLastPara = -1; + m_nSelectionLastPos = -1; + m_aFocused = m_xParagraphs->end(); + m_bSelectionChangedNotification = false; + m_aEngineListener.startListening(m_rEngine); + m_aViewListener.startListening(*m_rView.GetWindow()); +} + +::rtl::Reference< Paragraph > +Document::getParagraph(Paragraphs::iterator const & rIt) +{ + return rIt->getParagraph().get(); +} + +css::uno::Reference< css::accessibility::XAccessible > +Document::getAccessibleChild(Paragraphs::iterator const & rIt) +{ + rtl::Reference< Paragraph > xParagraph(rIt->getParagraph()); + if (!xParagraph.is()) + { + xParagraph = new Paragraph(this, rIt - m_xParagraphs->begin()); + rIt->setParagraph(xParagraph); + } + return xParagraph; +} + +void Document::determineVisibleRange() +{ + Paragraphs::iterator const aEnd = m_xParagraphs->end(); + + m_aVisibleBegin = aEnd; + m_aVisibleEnd = aEnd; + m_nVisibleBeginOffset = 0; + + ::sal_Int32 nPos = 0; + for (Paragraphs::iterator aIt = m_xParagraphs->begin(); m_aVisibleEnd == aEnd && aIt != aEnd; ++aIt) + { + ::sal_Int32 const nOldPos = nPos; + nPos += aIt->getHeight(); // XXX numeric overflow + if (m_aVisibleBegin == aEnd) + { + if (nPos >= m_nViewOffset) + { + m_aVisibleBegin = aIt; + m_nVisibleBeginOffset = m_nViewOffset - nOldPos; + } + } + else + { + if (nPos >= m_nViewOffset + m_nViewHeight) // XXX numeric overflow + { + m_aVisibleEnd = aIt; + } + } + } + + SAL_WARN_IF( + !((m_aVisibleBegin == m_xParagraphs->end() && m_aVisibleEnd == m_xParagraphs->end() && m_nVisibleBeginOffset == 0) + || (m_aVisibleBegin < m_aVisibleEnd && m_nVisibleBeginOffset >= 0)), + "accessibility", + "invalid visible range"); +} + +void Document::notifyVisibleRangeChanges( + Paragraphs::iterator const & rOldVisibleBegin, + Paragraphs::iterator const & rOldVisibleEnd, + Paragraphs::iterator const & rInserted) +{ + // XXX Replace this code that determines which paragraphs have changed from + // invisible to visible or vice versa with a better algorithm. + for (Paragraphs::iterator aIt(rOldVisibleBegin); aIt != rOldVisibleEnd; + ++aIt) + { + if (aIt != rInserted + && (aIt < m_aVisibleBegin || aIt >= m_aVisibleEnd)) + NotifyAccessibleEvent( + css::accessibility::AccessibleEventId:: + CHILD, + css::uno::Any(getAccessibleChild(aIt)), + css::uno::Any()); + } + for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd; + ++aIt) + { + if (aIt == rInserted + || aIt < rOldVisibleBegin || aIt >= rOldVisibleEnd) + NotifyAccessibleEvent( + css::accessibility::AccessibleEventId:: + CHILD, + css::uno::Any(), + css::uno::Any(getAccessibleChild(aIt))); + } +} + +void +Document::changeParagraphText(::sal_uInt32 nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd, + bool bCut, bool bPaste, + OUString const & rText) +{ + m_rView.SetSelection(::TextSelection(::TextPaM(nNumber, nBegin), + ::TextPaM(nNumber, nEnd))); + if (bCut) + m_rView.Cut(); + else if (nBegin != nEnd) + m_rView.DeleteSelected(); + if (bPaste) + m_rView.Paste(); + else if (!rText.isEmpty()) + m_rView.InsertText(rText); +} + +void Document::handleParagraphNotifications() +{ + while (!m_aParagraphNotifications.empty()) + { + ::TextHint aHint(m_aParagraphNotifications.front()); + m_aParagraphNotifications.pop(); + switch (aHint.GetId()) + { + case SfxHintId::TextParaInserted: + { + ::sal_uInt32 n = static_cast< ::sal_uInt32 >( aHint.GetValue() ); + assert(n <= m_xParagraphs->size() && "bad SfxHintId::TextParaInserted event"); + + // Save the values of old iterators (the iterators themselves + // will get invalidated), and adjust the old values so that they + // reflect the insertion of the new paragraph: + Paragraphs::size_type nOldVisibleBegin + = m_aVisibleBegin - m_xParagraphs->begin(); + Paragraphs::size_type nOldVisibleEnd + = m_aVisibleEnd - m_xParagraphs->begin(); + Paragraphs::size_type nOldFocused + = m_aFocused - m_xParagraphs->begin(); + if (n <= nOldVisibleBegin) + ++nOldVisibleBegin; // XXX numeric overflow + if (n <= nOldVisibleEnd) + ++nOldVisibleEnd; // XXX numeric overflow + if (n <= nOldFocused) + ++nOldFocused; // XXX numeric overflow + if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionFirstPara) + ++m_nSelectionFirstPara; // XXX numeric overflow + if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionLastPara) + ++m_nSelectionLastPara; // XXX numeric overflow + + Paragraphs::iterator aIns( + m_xParagraphs->insert( + m_xParagraphs->begin() + n, + ParagraphInfo(static_cast< ::sal_Int32 >( + m_rEngine.GetTextHeight(n))))); + // XXX numeric overflow (2x) + + determineVisibleRange(); + m_aFocused = m_xParagraphs->begin() + nOldFocused; + + for (Paragraphs::iterator aIt(aIns);;) + { + ++aIt; + if (aIt == m_xParagraphs->end()) + break; + ::rtl::Reference< Paragraph > xParagraph( + getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->numberChanged(true); + } + + notifyVisibleRangeChanges( + m_xParagraphs->begin() + nOldVisibleBegin, + m_xParagraphs->begin() + nOldVisibleEnd, aIns); + break; + } + case SfxHintId::TextParaRemoved: + { + ::sal_uInt32 n = static_cast< ::sal_uInt32 >( aHint.GetValue() ); + if (n == TEXT_PARA_ALL) + { + for (Paragraphs::iterator aIt(m_aVisibleBegin); + aIt != m_aVisibleEnd; ++aIt) + { + NotifyAccessibleEvent( + css::accessibility::AccessibleEventId:: + CHILD, + css::uno::Any(getAccessibleChild(aIt)), + css::uno::Any()); + } + disposeParagraphs(); + m_xParagraphs->clear(); + determineVisibleRange(); + m_nSelectionFirstPara = -1; + m_nSelectionFirstPos = -1; + m_nSelectionLastPara = -1; + m_nSelectionLastPos = -1; + m_aFocused = m_xParagraphs->end(); + } + else + { + assert(n < m_xParagraphs->size() && "Bad SfxHintId::TextParaRemoved event"); + + Paragraphs::iterator aIt(m_xParagraphs->begin() + n); + // numeric overflow cannot occur + + // Save the values of old iterators (the iterators + // themselves will get invalidated), and adjust the old + // values so that they reflect the removal of the paragraph: + Paragraphs::size_type nOldVisibleBegin + = m_aVisibleBegin - m_xParagraphs->begin(); + Paragraphs::size_type nOldVisibleEnd + = m_aVisibleEnd - m_xParagraphs->begin(); + bool bWasVisible + = nOldVisibleBegin <= n && n < nOldVisibleEnd; + Paragraphs::size_type nOldFocused + = m_aFocused - m_xParagraphs->begin(); + bool bWasFocused = aIt == m_aFocused; + if (n < nOldVisibleBegin) + --nOldVisibleBegin; + if (n < nOldVisibleEnd) + --nOldVisibleEnd; + if (n < nOldFocused) + --nOldFocused; + if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionFirstPara) + --m_nSelectionFirstPara; + else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionFirstPara) + { + if (m_nSelectionFirstPara == m_nSelectionLastPara) + { + m_nSelectionFirstPara = -1; + m_nSelectionFirstPos = -1; + m_nSelectionLastPara = -1; + m_nSelectionLastPos = -1; + } + else + { + ++m_nSelectionFirstPara; + m_nSelectionFirstPos = 0; + } + } + if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionLastPara) + --m_nSelectionLastPara; + else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionLastPara) + { + assert(m_nSelectionFirstPara < m_nSelectionLastPara && "logic error"); + --m_nSelectionLastPara; + m_nSelectionLastPos = 0x7FFFFFFF; + } + + css::uno::Reference< css::accessibility::XAccessible > + xStrong; + if (bWasVisible) + xStrong = getAccessibleChild(aIt); + unotools::WeakReference<Paragraph> xWeak( + aIt->getParagraph()); + aIt = m_xParagraphs->erase(aIt); + + determineVisibleRange(); + m_aFocused = bWasFocused ? m_xParagraphs->end() + : m_xParagraphs->begin() + nOldFocused; + + for (; aIt != m_xParagraphs->end(); ++aIt) + { + ::rtl::Reference< Paragraph > xParagraph( + getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->numberChanged(false); + } + + if (bWasVisible) + NotifyAccessibleEvent( + css::accessibility::AccessibleEventId:: + CHILD, + css::uno::Any(xStrong), + css::uno::Any()); + + rtl::Reference< Paragraph > xComponent( xWeak.get() ); + if (xComponent.is()) + xComponent->dispose(); + + notifyVisibleRangeChanges( + m_xParagraphs->begin() + nOldVisibleBegin, + m_xParagraphs->begin() + nOldVisibleEnd, + m_xParagraphs->end()); + } + break; + } + case SfxHintId::TextFormatPara: + { + ::sal_uInt32 n = static_cast< ::sal_uInt32 >( aHint.GetValue() ); + assert(n < m_xParagraphs->size() && "Bad SfxHintId::TextFormatPara event"); + + (*m_xParagraphs)[static_cast< Paragraphs::size_type >(n)]. + changeHeight(static_cast< ::sal_Int32 >( + m_rEngine.GetTextHeight(n))); + // XXX numeric overflow + Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin); + Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); + determineVisibleRange(); + notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd, + m_xParagraphs->end()); + + if (n < m_xParagraphs->size()) + { + Paragraphs::iterator aIt(m_xParagraphs->begin() + n); + ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->textChanged(); + } + break; + } + default: + SAL_WARN("accessibility", "bad buffered hint"); + break; + } + } + if (m_bSelectionChangedNotification) + { + m_bSelectionChangedNotification = false; + handleSelectionChangeNotification(); + } +} + +namespace +{ + +enum class SelChangeType +{ + None, // no change, or invalid + CaretMove, // neither old nor new have selection, and they are different + NoSelToSel, // old has no selection but new has selection + SelToNoSel, // old has selection but new has no selection + // both old and new have selections + NoParaChange, // only end index changed inside end para + EndParaNoMoreBehind, // end para was behind start, but now is same or ahead + AddedFollowingPara, // selection extended to following paragraph(s) + ExcludedPreviousPara, // selection shrunk excluding previous paragraph(s) + ExcludedFollowingPara, // selection shrunk excluding following paragraph(s) + AddedPreviousPara, // selection extended to previous paragraph(s) + EndParaBecameBehind // end para was ahead of start, but now is behind +}; + +SelChangeType getSelChangeType(const TextPaM& Os, const TextPaM& Oe, + const TextPaM& Ns, const TextPaM& Ne) +{ + if (Os == Oe) // no old selection + { + if (Ns == Ne) // no new selection: only caret moves + return Os != Ns ? SelChangeType::CaretMove : SelChangeType::None; + else // old has no selection but new has selection + return SelChangeType::NoSelToSel; + } + else if (Ns == Ne) // old has selection; no new selection + { + return SelChangeType::SelToNoSel; + } + else if (Os == Ns) // both old and new have selections, and their starts are same + { + const sal_Int32 Osp = Os.GetPara(), Oep = Oe.GetPara(); + const sal_Int32 Nsp = Ns.GetPara(), Nep = Ne.GetPara(); + if (Oep == Nep) // end of selection stays in the same paragraph + { + //Send text_selection_change event on Nep + return Oe.GetIndex() != Ne.GetIndex() ? SelChangeType::NoParaChange + : SelChangeType::None; + } + else if (Oep < Nep) // end of selection moved to a following paragraph + { + //all the following examples like 1,2->1,3 means that old start select para is 1, old end select para is 2, + // then press shift up, the new start select para is 1, new end select para is 3; + //for example, 1, 2 -> 1, 3; 4,1 -> 4, 7; 4,1 -> 4, 2; 4,4->4,5 + if (Nep >= Nsp) // new end para not behind start + { + // 1, 2 -> 1, 3; 4, 1 -> 4, 7; 4,4->4,5; + if (Oep < Osp) // old end was behind start + { + // 4,1 -> 4,7; 4,1 -> 4,4 + return SelChangeType::EndParaNoMoreBehind; + } + else // old end para wasn't behind start + { + // 1, 2 -> 1, 3; 4,4->4,5; + return SelChangeType::AddedFollowingPara; + } + } + else // new end para is still behind start + { + // 4,1 -> 4,2, + return SelChangeType::ExcludedPreviousPara; + } + } + else // Oep > Nep => end of selection moved to a previous paragraph + { + // 3,2 -> 3,1; 4,7 -> 4,1; 4, 7 -> 4,6; 4,4 -> 4,3 + if (Nep >= Nsp) // new end para is still not behind of start + { + // 4,7 ->4,6 + return SelChangeType::ExcludedFollowingPara; + } + else // new end para is behind start + { + // 3,2 -> 3,1, 4,7 -> 4,1; 4,4->4,3 + if (Oep <= Osp) // it was not ahead already + { + // 3,2 -> 3,1; 4,4->4,3 + return SelChangeType::AddedPreviousPara; + } + else // it was ahead previously + { + // 4,7 -> 4,1 + return SelChangeType::EndParaBecameBehind; + } + } + } + } + return SelChangeType::None; +} + +} // namespace + +void Document::sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId) +{ + size_t nAvailDistance = std::distance(m_xParagraphs->begin(), m_aVisibleEnd); + + Paragraphs::iterator aEnd(m_xParagraphs->begin()); + size_t nEndDistance = std::min<size_t>(end + 1, nAvailDistance); + std::advance(aEnd, nEndDistance); + + Paragraphs::iterator aIt(m_xParagraphs->begin()); + size_t nStartDistance = std::min<size_t>(start, nAvailDistance); + std::advance(aIt, nStartDistance); + + while (aIt < aEnd) + { + ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt)); + if (xParagraph.is()) + xParagraph->notifyEvent( + nEventId, + css::uno::Any(), css::uno::Any()); + ++aIt; + } +} + +void Document::handleSelectionChangeNotification() +{ + ::TextSelection const & rSelection = m_rView.GetSelection(); + assert(rSelection.GetStart().GetPara() < m_xParagraphs->size() && + rSelection.GetEnd().GetPara() < m_xParagraphs->size() && + "bad SfxHintId::TextViewSelectionChanged event"); + ::sal_Int32 nNewFirstPara + = static_cast< ::sal_Int32 >(rSelection.GetStart().GetPara()); + ::sal_Int32 nNewFirstPos = rSelection.GetStart().GetIndex(); + // XXX numeric overflow + ::sal_Int32 nNewLastPara + = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetPara()); + ::sal_Int32 nNewLastPos = rSelection.GetEnd().GetIndex(); + // XXX numeric overflow + + // Lose focus: + Paragraphs::iterator aIt(m_xParagraphs->begin() + nNewLastPara); + if (m_aFocused != m_xParagraphs->end() && m_aFocused != aIt + && m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) + { + ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aFocused)); + if (xParagraph.is()) + xParagraph->notifyEvent( + css::accessibility::AccessibleEventId:: + STATE_CHANGED, + css::uno::Any( + css::accessibility::AccessibleStateType::FOCUSED), + css::uno::Any()); + } + + // Gain focus and update cursor position: + if (aIt >= m_aVisibleBegin && aIt < m_aVisibleEnd + && (aIt != m_aFocused + || nNewLastPara != m_nSelectionLastPara + || nNewLastPos != m_nSelectionLastPos)) + { + ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt)); + if (xParagraph.is()) + { + //disable the first event when user types in empty field. + sal_Int64 count = getAccessibleChildCount(); + bool bEmpty = count > 1; + //if (aIt != m_aFocused) + if (aIt != m_aFocused && bEmpty) + xParagraph->notifyEvent( + css::accessibility::AccessibleEventId:: + STATE_CHANGED, + css::uno::Any(), + css::uno::Any( + css::accessibility::AccessibleStateType::FOCUSED)); + if (nNewLastPara != m_nSelectionLastPara + || nNewLastPos != m_nSelectionLastPos) + xParagraph->notifyEvent( + css::accessibility::AccessibleEventId:: + CARET_CHANGED, + css::uno::Any( ::sal_Int32 ( + nNewLastPara == m_nSelectionLastPara + ? m_nSelectionLastPos : 0)), + css::uno::Any(nNewLastPos)); + } + } + m_aFocused = aIt; + + if (m_nSelectionFirstPara != -1) + { + sal_Int32 nMin; + sal_Int32 nMax; + SelChangeType ret = getSelChangeType(TextPaM(m_nSelectionFirstPara, m_nSelectionFirstPos), + TextPaM(m_nSelectionLastPara, m_nSelectionLastPos), + rSelection.GetStart(), rSelection.GetEnd()); + switch (ret) + { + case SelChangeType::None: + //no event + break; + case SelChangeType::CaretMove: + //only caret moved, already handled in above + break; + case SelChangeType::NoSelToSel: + //old has no selection but new has selection + nMin = std::min(nNewFirstPara, nNewLastPara); + nMax = std::max(nNewFirstPara, nNewLastPara); + sendEvent(nMin, nMax, css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nMin, nMax, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::SelToNoSel: + //old has selection but new has no selection. + nMin = std::min(m_nSelectionFirstPara, m_nSelectionLastPara); + nMax = std::max(m_nSelectionFirstPara, m_nSelectionLastPara); + sendEvent(nMin, nMax, css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nMin, nMax, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::NoParaChange: + //Send text_selection_change event on Nep + sendEvent(nNewLastPara, nNewLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::EndParaNoMoreBehind: + // 4, 1 -> 4, 7; 4,1 -> 4,4 + sendEvent(m_nSelectionLastPara, m_nSelectionFirstPara - 1, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nNewFirstPara + 1, nNewLastPara, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(m_nSelectionLastPara, nNewLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::AddedFollowingPara: + // 1, 2 -> 1, 4; 4,4->4,5; + sendEvent(m_nSelectionLastPara + 1, nNewLastPara, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(m_nSelectionLastPara, nNewLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::ExcludedPreviousPara: + // 4,1 -> 4,3, + sendEvent(m_nSelectionLastPara + 1, nNewLastPara, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(m_nSelectionLastPara, nNewLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::ExcludedFollowingPara: + // 4,7 ->4,5; + sendEvent(nNewLastPara + 1, m_nSelectionLastPara, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(nNewLastPara, m_nSelectionLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::AddedPreviousPara: + // 3,2 -> 3,1; 4,4->4,3 + sendEvent(nNewLastPara, m_nSelectionLastPara - 1, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(nNewLastPara, m_nSelectionLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + case SelChangeType::EndParaBecameBehind: + // 4,7 -> 4,1 + sendEvent(m_nSelectionFirstPara + 1, m_nSelectionLastPara, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + sendEvent(nNewLastPara, nNewFirstPara - 1, + css::accessibility::AccessibleEventId::SELECTION_CHANGED); + + sendEvent(nNewLastPara, m_nSelectionLastPara, + css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED); + break; + } + } + + m_nSelectionFirstPara = nNewFirstPara; + m_nSelectionFirstPos = nNewFirstPos; + m_nSelectionLastPara = nNewLastPara; + m_nSelectionLastPos = nNewLastPos; +} + +void Document::disposeParagraphs() +{ + for (auto const& paragraph : *m_xParagraphs) + { + rtl::Reference< Paragraph > xComponent( + paragraph.getParagraph().get() ); + if (xComponent.is()) + xComponent->dispose(); + } +} + +// static +css::uno::Any Document::mapFontColor(::Color const & rColor) +{ + return css::uno::Any(rColor.GetRGBColor()); + // FIXME keep transparency? +} + +// static +::Color Document::mapFontColor(css::uno::Any const & rColor) +{ + ::Color nColor; + rColor >>= nColor; + return nColor; +} + +// static +css::uno::Any Document::mapFontWeight(::FontWeight nWeight) +{ + // Map from ::FontWeight to css::awt::FontWeight, depends on order of + // elements in ::FontWeight (vcl/vclenum.hxx): + static float const aWeight[] + = { css::awt::FontWeight::DONTKNOW, // WEIGHT_DONTKNOW + css::awt::FontWeight::THIN, // WEIGHT_THIN + css::awt::FontWeight::ULTRALIGHT, // WEIGHT_ULTRALIGHT + css::awt::FontWeight::LIGHT, // WEIGHT_LIGHT + css::awt::FontWeight::SEMILIGHT, // WEIGHT_SEMILIGHT + css::awt::FontWeight::NORMAL, // WEIGHT_NORMAL + css::awt::FontWeight::NORMAL, // WEIGHT_MEDIUM + css::awt::FontWeight::SEMIBOLD, // WEIGHT_SEMIBOLD + css::awt::FontWeight::BOLD, // WEIGHT_BOLD + css::awt::FontWeight::ULTRABOLD, // WEIGHT_ULTRABOLD + css::awt::FontWeight::BLACK }; // WEIGHT_BLACK + return css::uno::Any(aWeight[nWeight]); +} + +// static +::FontWeight Document::mapFontWeight(css::uno::Any const & rWeight) +{ + float nWeight = css::awt::FontWeight::NORMAL; + rWeight >>= nWeight; + return nWeight <= css::awt::FontWeight::DONTKNOW ? WEIGHT_DONTKNOW + : nWeight <= css::awt::FontWeight::THIN ? WEIGHT_THIN + : nWeight <= css::awt::FontWeight::ULTRALIGHT ? WEIGHT_ULTRALIGHT + : nWeight <= css::awt::FontWeight::LIGHT ? WEIGHT_LIGHT + : nWeight <= css::awt::FontWeight::SEMILIGHT ? WEIGHT_SEMILIGHT + : nWeight <= css::awt::FontWeight::NORMAL ? WEIGHT_NORMAL + : nWeight <= css::awt::FontWeight::SEMIBOLD ? WEIGHT_SEMIBOLD + : nWeight <= css::awt::FontWeight::BOLD ? WEIGHT_BOLD + : nWeight <= css::awt::FontWeight::ULTRABOLD ? WEIGHT_ULTRABOLD + : WEIGHT_BLACK; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/helper/IComboListBoxHelper.cxx b/accessibility/source/helper/IComboListBoxHelper.cxx new file mode 100644 index 0000000000..f4830815fd --- /dev/null +++ b/accessibility/source/helper/IComboListBoxHelper.cxx @@ -0,0 +1,17 @@ +/* -*- 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/. + */ + +#include <helper/IComboListBoxHelper.hxx> + +namespace accessibility +{ +IComboListBoxHelper::~IComboListBoxHelper() {} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/helper/acc_factory.cxx b/accessibility/source/helper/acc_factory.cxx new file mode 100644 index 0000000000..4dcc63e4ab --- /dev/null +++ b/accessibility/source/helper/acc_factory.cxx @@ -0,0 +1,507 @@ +/* -*- 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 <config_features.h> +#include <config_feature_desktop.h> + +#include <toolkit/awt/vclxwindows.hxx> +#include <toolkit/helper/accessiblefactory.hxx> +#include <vcl/accessiblefactory.hxx> +#include <standard/svtaccessiblenumericfield.hxx> +#include <standard/vclxaccessiblebutton.hxx> +#include <standard/vclxaccessiblecheckbox.hxx> +#include <standard/vclxaccessibledropdowncombobox.hxx> +#include <standard/vclxaccessiblecombobox.hxx> +#include <standard/vclxaccessibledropdownlistbox.hxx> +#include <standard/vclxaccessibleedit.hxx> +#include <standard/vclxaccessiblefixedhyperlink.hxx> +#include <standard/vclxaccessiblefixedtext.hxx> +#include <standard/vclxaccessibleheaderbar.hxx> +#include <standard/vclxaccessiblelistbox.hxx> +#include <standard/vclxaccessibleradiobutton.hxx> +#include <standard/vclxaccessiblescrollbar.hxx> +#include <standard/vclxaccessibletoolbox.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <standard/vclxaccessiblestatusbar.hxx> +#include <standard/vclxaccessibletabcontrol.hxx> +#include <standard/vclxaccessibletabpagewindow.hxx> +#include <standard/vclxaccessiblemenubar.hxx> +#include <standard/vclxaccessiblepopupmenu.hxx> +#include <extended/accessibletablistbox.hxx> +#include <extended/AccessibleBrowseBox.hxx> +#include <extended/accessibleiconchoicectrl.hxx> +#include <extended/AccessibleIconView.hxx> +#include <extended/accessibletabbar.hxx> +#include <extended/accessiblelistbox.hxx> +#include <extended/AccessibleBrowseBoxHeaderBar.hxx> +#include <extended/textwindowaccessibility.hxx> +#include <extended/AccessibleBrowseBoxTableCell.hxx> +#include <extended/AccessibleBrowseBoxHeaderCell.hxx> +#include <extended/AccessibleBrowseBoxCheckBoxCell.hxx> +#include <extended/accessibleeditbrowseboxcell.hxx> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <vcl/toolkit/lstbox.hxx> +#include <vcl/toolkit/combobox.hxx> +#include <extended/AccessibleGridControl.hxx> +#include <vcl/accessibletable.hxx> + +#include <floatingwindowaccessible.hxx> + +using namespace ::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::accessibility; +using namespace ::vcl; +using namespace ::vcl::table; + +namespace { + +bool hasFloatingChild(vcl::Window *pWindow) +{ + vcl::Window * pChild = pWindow->GetAccessibleChildWindow(0); + return pChild && pChild->GetType() == WindowType::FLOATINGWINDOW; +} + +// IAccessibleFactory +class AccessibleFactory :public ::toolkit::IAccessibleFactory + ,public ::vcl::IAccessibleFactory +{ +public: + AccessibleFactory(); + + // ::toolkit::IAccessibleFactory + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXButton* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXCheckBox* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXRadioButton* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXListBox* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXFixedText* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXFixedHyperlink* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXScrollBar* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXEdit* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXMultiLineEdit* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXComboBox* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXToolBox* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXHeaderBar* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( SVTXNumericField* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleContext( VCLXWindow* _pXWindow ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessible( Menu* _pMenu, bool _bIsMenuBar ) override; + + // ::vcl::IAccessibleFactory + virtual vcl::IAccessibleTabListBox* + createAccessibleTabListBox( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + SvHeaderTabListBox& rBox + ) const override; + + virtual rtl::Reference<vcl::IAccessibleBrowseBox> + createAccessibleBrowseBox( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + vcl::IAccessibleTableProvider& _rBrowseBox + ) const override; + + virtual rtl::Reference<IAccessibleTableControl> + createAccessibleTableControl( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + IAccessibleTable& _rTable + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleIconChoiceCtrl( + SvtIconChoiceCtrl& _rIconCtrl, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleTabBar( + TabBar& _rTabBar + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessibleContext > + createAccessibleTextWindowContext( + VCLXWindow* pVclXWindow, TextEngine& rEngine, TextView& rView + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleTreeListBox( + SvTreeListBox& _rListBox, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleIconView( + SvTreeListBox& _rListBox, + const css::uno::Reference< css::accessibility::XAccessible >& _xParent + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleBrowseBoxHeaderBar( + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + vcl::IAccessibleTableProvider& _rOwningTable, + AccessibleBrowseBoxObjType _eObjType + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleBrowseBoxTableCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowId, + sal_uInt16 _nColId, + sal_Int32 _nOffset + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleBrowseBoxHeaderCell( + sal_Int32 _nColumnRowId, + const css::uno::Reference< css::accessibility::XAccessible >& rxParent, + vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + AccessibleBrowseBoxObjType _eObjType + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createAccessibleCheckBoxCell( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + vcl::IAccessibleTableProvider& _rBrowseBox, + const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos, + const TriState& _eState, + bool _bIsTriState + ) const override; + + virtual css::uno::Reference< css::accessibility::XAccessible > + createEditBrowseBoxTableCellAccess( + const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, + const css::uno::Reference< css::accessibility::XAccessible >& _rxControlAccessible, + const css::uno::Reference< css::awt::XWindow >& _rxFocusWindow, + vcl::IAccessibleTableProvider& _rBrowseBox, + sal_Int32 _nRowPos, + sal_uInt16 _nColPos + ) const override; + +protected: + virtual ~AccessibleFactory() override; +}; + +AccessibleFactory::AccessibleFactory() +{ +} + +AccessibleFactory::~AccessibleFactory() +{ +} + +Reference< XAccessible > AccessibleFactory::createAccessible( Menu* _pMenu, bool _bIsMenuBar ) +{ + rtl::Reference<OAccessibleMenuBaseComponent> pAccessible; + if ( _bIsMenuBar ) + pAccessible = new VCLXAccessibleMenuBar( _pMenu ); + else + pAccessible = new VCLXAccessiblePopupMenu( _pMenu ); + pAccessible->SetStates(); + return pAccessible; +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXButton* _pXWindow ) +{ + return new VCLXAccessibleButton( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXCheckBox* _pXWindow ) +{ + return new VCLXAccessibleCheckBox( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXRadioButton* _pXWindow ) +{ + return new VCLXAccessibleRadioButton( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXListBox* _pXWindow ) +{ + bool bIsDropDownBox = false; + VclPtr< ListBox > pBox = _pXWindow->GetAs< ListBox >(); + if ( pBox ) + bIsDropDownBox = ( ( pBox->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN ); + + if ( bIsDropDownBox ) + return new VCLXAccessibleDropDownListBox( _pXWindow ); + else + return new VCLXAccessibleListBox( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXFixedText* _pXWindow ) +{ + return new VCLXAccessibleFixedText( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXFixedHyperlink* _pXWindow ) +{ + return new VCLXAccessibleFixedHyperlink( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXScrollBar* _pXWindow ) +{ + return new VCLXAccessibleScrollBar( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXEdit* _pXWindow ) +{ + return new VCLXAccessibleEdit( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXMultiLineEdit* _pXWindow ) +{ + return new VCLXAccessibleEdit( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXComboBox* _pXWindow ) +{ + bool bIsDropDownBox = false; + VclPtr< ComboBox > pBox = _pXWindow->GetAs< ComboBox >(); + if ( pBox ) + bIsDropDownBox = ( ( pBox->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN ); + + if ( bIsDropDownBox ) + return new VCLXAccessibleDropDownComboBox( _pXWindow ); + else + return new VCLXAccessibleComboBox( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXWindow* _pXWindow ) +{ + Reference< XAccessibleContext > xContext; + + VclPtr<vcl::Window> pWindow = _pXWindow->GetWindow(); + if ( pWindow ) + { + WindowType nType = pWindow->GetType(); + + if ( nType == WindowType::MENUBARWINDOW || pWindow->IsMenuFloatingWindow() || pWindow->IsToolbarFloatingWindow() ) + { + Reference< XAccessible > xAcc( pWindow->GetAccessible() ); + if ( xAcc.is() ) + { + Reference< XAccessibleContext > xCont( xAcc->getAccessibleContext() ); + if ( pWindow->GetType() == WindowType::MENUBARWINDOW || + ( xCont.is() && xCont->getAccessibleRole() == AccessibleRole::POPUP_MENU ) ) + { + xContext = xCont; + } + } + } + + else if ( nType == WindowType::STATUSBAR ) + { + xContext = new VCLXAccessibleStatusBar(_pXWindow); + } + + else if ( nType == WindowType::TABCONTROL ) + { + xContext = new VCLXAccessibleTabControl(_pXWindow); + } + + else if ( nType == WindowType::TABPAGE && pWindow->GetAccessibleParentWindow() && pWindow->GetAccessibleParentWindow()->GetType() == WindowType::TABCONTROL ) + { + xContext = new VCLXAccessibleTabPageWindow( _pXWindow ); + } + + else if ( nType == WindowType::FLOATINGWINDOW ) + { + xContext = new FloatingWindowAccessible( _pXWindow ); + } + + else if ( nType == WindowType::BORDERWINDOW && hasFloatingChild( pWindow ) ) + { + xContext = new FloatingWindowAccessible( _pXWindow ); + } + + else if ( ( nType == WindowType::HELPTEXTWINDOW ) || ( nType == WindowType::FIXEDLINE ) ) + { + xContext = new VCLXAccessibleFixedText(_pXWindow); + } + else + { + xContext = new VCLXAccessibleComponent(_pXWindow); + } + } + return xContext; +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXToolBox* _pXWindow ) +{ + return new VCLXAccessibleToolBox( _pXWindow ); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( VCLXHeaderBar* _pXWindow ) +{ + return new VCLXAccessibleHeaderBar(_pXWindow); +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleContext( SVTXNumericField* _pXWindow ) +{ + return new SVTXAccessibleNumericField( _pXWindow ); +} + +vcl::IAccessibleTabListBox* AccessibleFactory::createAccessibleTabListBox( + const Reference< XAccessible >& rxParent, SvHeaderTabListBox& rBox ) const +{ + return new AccessibleTabListBox( rxParent, rBox ); +} + +rtl::Reference<vcl::IAccessibleBrowseBox> AccessibleFactory::createAccessibleBrowseBox( + const Reference< XAccessible >& _rxParent, vcl::IAccessibleTableProvider& _rBrowseBox ) const +{ + return new AccessibleBrowseBoxAccess( _rxParent, _rBrowseBox ); +} + +rtl::Reference<IAccessibleTableControl> AccessibleFactory::createAccessibleTableControl( + const Reference< XAccessible >& _rxParent, IAccessibleTable& _rTable ) const +{ + return new AccessibleGridControlAccess( _rxParent, _rTable ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleIconChoiceCtrl( + SvtIconChoiceCtrl& _rIconCtrl, const Reference< XAccessible >& _xParent ) const +{ + return new AccessibleIconChoiceCtrl( _rIconCtrl, _xParent ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleTabBar( TabBar& _rTabBar ) const +{ +#if HAVE_FEATURE_SCRIPTING + return new AccessibleTabBar( &_rTabBar ); +#else + (void)_rTabBar; + return nullptr; +#endif +} + +Reference< XAccessibleContext > AccessibleFactory::createAccessibleTextWindowContext( + VCLXWindow* pVclXWindow, TextEngine& rEngine, TextView& rView ) const +{ + return new Document( pVclXWindow, rEngine, rView ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleTreeListBox( + SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) const +{ + return new AccessibleListBox( _rListBox, _xParent ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleIconView( + SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) const +{ + return new AccessibleIconView( _rListBox, _xParent ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleBrowseBoxHeaderBar( + const Reference< XAccessible >& rxParent, vcl::IAccessibleTableProvider& _rOwningTable, + AccessibleBrowseBoxObjType _eObjType ) const +{ + return new AccessibleBrowseBoxHeaderBar( rxParent, _rOwningTable, _eObjType ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleBrowseBoxTableCell( + const Reference< XAccessible >& _rxParent, vcl::IAccessibleTableProvider& _rBrowseBox, + const Reference< XWindow >& _xFocusWindow, sal_Int32 _nRowId, sal_uInt16 _nColId, sal_Int32 _nOffset ) const +{ + return new AccessibleBrowseBoxTableCell( _rxParent, _rBrowseBox, _xFocusWindow, + _nRowId, _nColId, _nOffset ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleBrowseBoxHeaderCell( + sal_Int32 _nColumnRowId, const Reference< XAccessible >& rxParent, vcl::IAccessibleTableProvider& _rBrowseBox, + const Reference< XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType _eObjType ) const +{ + return new AccessibleBrowseBoxHeaderCell( _nColumnRowId, rxParent, _rBrowseBox, + _xFocusWindow, _eObjType ); +} + +Reference< XAccessible > AccessibleFactory::createAccessibleCheckBoxCell( + const Reference< XAccessible >& _rxParent, vcl::IAccessibleTableProvider& _rBrowseBox, + const Reference< XWindow >& _xFocusWindow, sal_Int32 _nRowPos, sal_uInt16 _nColPos, + const TriState& _eState, bool _bIsTriState ) const +{ + return new AccessibleCheckBoxCell( _rxParent, _rBrowseBox, _xFocusWindow, + _nRowPos, _nColPos, _eState, _bIsTriState ); +} + +Reference< XAccessible > AccessibleFactory::createEditBrowseBoxTableCellAccess( + const Reference< XAccessible >& _rxParent, const Reference< XAccessible >& _rxControlAccessible, + const Reference< XWindow >& _rxFocusWindow, vcl::IAccessibleTableProvider& _rBrowseBox, + sal_Int32 _nRowPos, sal_uInt16 _nColPos ) const +{ + return new EditBrowseBoxTableCellAccess( _rxParent, _rxControlAccessible, + _rxFocusWindow, _rBrowseBox, _nRowPos, _nColPos ); +} + +} // anonymous namespace + +#if HAVE_FEATURE_DESKTOP +/* this is the entry point to retrieve a factory for the toolkit-level Accessible/Contexts supplied + by this library + + This function implements the factory function needed in toolkit + (of type GetStandardAccComponentFactory). +*/ +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void* getStandardAccessibleFactory() + { + ::toolkit::IAccessibleFactory* pFactory = new AccessibleFactory; + pFactory->acquire(); + return pFactory; + } +} + +/** this is the entry point to retrieve a factory for the svtools-level Accessible/Contexts supplied + by this library + + This function implements the factory function needed in svtools + (of type GetSvtAccessibilityComponentFactory). +*/ +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void* getSvtAccessibilityComponentFactory() + { + ::vcl::IAccessibleFactory* pFactory = new AccessibleFactory; + pFactory->acquire(); + return pFactory; + } +} +#endif // HAVE_FEATURE_DESKTOP + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/helper/accresmgr.cxx b/accessibility/source/helper/accresmgr.cxx new file mode 100644 index 0000000000..f120dcb260 --- /dev/null +++ b/accessibility/source/helper/accresmgr.cxx @@ -0,0 +1,24 @@ +/* -*- 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 <helper/accresmgr.hxx> + +OUString AccResId(TranslateId aId) { return Translate::get(aId, Translate::Create("acc")); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/helper/characterattributeshelper.cxx b/accessibility/source/helper/characterattributeshelper.cxx new file mode 100644 index 0000000000..7e2a2334bf --- /dev/null +++ b/accessibility/source/helper/characterattributeshelper.cxx @@ -0,0 +1,79 @@ +/* -*- 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 <helper/characterattributeshelper.hxx> +#include <tools/gen.hxx> +#include <vcl/unohelp.hxx> +#include <comphelper/sequence.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; + + +CharacterAttributesHelper::CharacterAttributesHelper( const vcl::Font& rFont, sal_Int32 nBackColor, sal_Int32 nColor ) +{ + m_aAttributeMap.emplace( u"CharBackColor"_ustr, Any( nBackColor ) ); + m_aAttributeMap.emplace( u"CharColor"_ustr, Any( nColor ) ); + m_aAttributeMap.emplace( u"CharFontCharSet"_ustr, Any( static_cast<sal_Int16>(rFont.GetCharSet()) ) ); + m_aAttributeMap.emplace( u"CharFontFamily"_ustr, Any( static_cast<sal_Int16>(rFont.GetFamilyType()) ) ); + m_aAttributeMap.emplace( u"CharFontName"_ustr, Any( rFont.GetFamilyName() ) ); + m_aAttributeMap.emplace( u"CharFontPitch"_ustr, Any( static_cast<sal_Int16>(rFont.GetPitch()) ) ); + m_aAttributeMap.emplace( u"CharFontStyleName"_ustr, Any( rFont.GetStyleName() ) ); + m_aAttributeMap.emplace( u"CharHeight"_ustr, Any( static_cast<sal_Int16>(rFont.GetFontSize().Height()) ) ); + m_aAttributeMap.emplace( u"CharScaleWidth"_ustr, Any( static_cast<sal_Int16>(rFont.GetFontSize().Width()) ) ); + m_aAttributeMap.emplace( u"CharStrikeout"_ustr, Any( static_cast<sal_Int16>(rFont.GetStrikeout()) ) ); + m_aAttributeMap.emplace( u"CharUnderline"_ustr, Any( static_cast<sal_Int16>(rFont.GetUnderline()) ) ); + m_aAttributeMap.emplace( u"CharWeight"_ustr, Any( static_cast<float>(rFont.GetWeight()) ) ); + m_aAttributeMap.emplace( u"CharPosture"_ustr, Any( vcl::unohelper::ConvertFontSlant(rFont.GetItalic()) ) ); +} + + +std::vector< PropertyValue > CharacterAttributesHelper::GetCharacterAttributes() +{ + std::vector< PropertyValue > aValues; + aValues.reserve( m_aAttributeMap.size() ); + + for ( const auto& aIt : m_aAttributeMap) + { + aValues.emplace_back(aIt.first, sal_Int32(-1), aIt.second, PropertyState_DIRECT_VALUE); + } + + return aValues; +} + + +Sequence< PropertyValue > CharacterAttributesHelper::GetCharacterAttributes( const css::uno::Sequence< OUString >& aRequestedAttributes ) +{ + if ( !aRequestedAttributes.hasElements() ) + return comphelper::containerToSequence(GetCharacterAttributes()); + + std::vector< PropertyValue > aValues; + + for ( const auto& aRequestedAttribute: aRequestedAttributes) + { + AttributeMap::iterator aFound = m_aAttributeMap.find( aRequestedAttribute ); + if ( aFound != m_aAttributeMap.end() ) + aValues.emplace_back(aFound->first, sal_Int32(-1), aFound->second, PropertyState_DIRECT_VALUE); + } + + return comphelper::containerToSequence(aValues); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/inc/floatingwindowaccessible.hxx b/accessibility/source/inc/floatingwindowaccessible.hxx new file mode 100644 index 0000000000..c36e862360 --- /dev/null +++ b/accessibility/source/inc/floatingwindowaccessible.hxx @@ -0,0 +1,32 @@ +/* -*- 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 . + */ + +#pragma once + +#include <toolkit/awt/vclxaccessiblecomponent.hxx> + +class FloatingWindowAccessible final : public VCLXAccessibleComponent +{ +public: + using VCLXAccessibleComponent::VCLXAccessibleComponent; + + virtual void FillAccessibleRelationSet(utl::AccessibleRelationSetHelper& rRelationSet) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/accessiblemenubasecomponent.cxx b/accessibility/source/standard/accessiblemenubasecomponent.cxx new file mode 100644 index 0000000000..e5e390d595 --- /dev/null +++ b/accessibility/source/standard/accessiblemenubasecomponent.cxx @@ -0,0 +1,680 @@ +/* -*- 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 <standard/accessiblemenubasecomponent.hxx> +#include <standard/vclxaccessiblemenu.hxx> +#include <standard/vclxaccessiblemenuitem.hxx> +#include <standard/vclxaccessiblemenuseparator.hxx> +#include <toolkit/helper/convert.hxx> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <o3tl/safeint.hxx> +#include <vcl/menu.hxx> +#include <vcl/vclevent.hxx> + +#include <array> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + +// OAccessibleMenuBaseComponent + + +OAccessibleMenuBaseComponent::OAccessibleMenuBaseComponent( Menu* pMenu ) + :m_pMenu( pMenu ) + ,m_bEnabled( false ) + ,m_bFocused( false ) + ,m_bVisible( false ) + ,m_bSelected( false ) + ,m_bChecked( false ) +{ + if ( m_pMenu ) + { + m_aAccessibleChildren1.assign( m_pMenu->GetItemCount(), rtl::Reference< OAccessibleMenuItemComponent >() ); + m_pMenu->AddEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) ); + } +} + + +OAccessibleMenuBaseComponent::~OAccessibleMenuBaseComponent() +{ + if ( m_pMenu ) + m_pMenu->RemoveEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) ); +} + + +bool OAccessibleMenuBaseComponent::IsEnabled() +{ + return false; +} + + +bool OAccessibleMenuBaseComponent::IsFocused() +{ + return false; +} + + +bool OAccessibleMenuBaseComponent::IsVisible() +{ + return false; +} + + +bool OAccessibleMenuBaseComponent::IsSelected() +{ + return false; +} + + +bool OAccessibleMenuBaseComponent::IsChecked() +{ + return false; +} + + +void OAccessibleMenuBaseComponent::SetStates() +{ + m_bEnabled = IsEnabled(); + m_bFocused = IsFocused(); + m_bVisible = IsVisible(); + m_bSelected = IsSelected(); + m_bChecked = IsChecked(); +} + + +void OAccessibleMenuBaseComponent::SetEnabled( bool bEnabled ) +{ + if ( m_bEnabled == bEnabled ) + return; + + sal_Int64 nStateType=AccessibleStateType::ENABLED; + if (IsMenuHideDisabledEntries()) + { + nStateType = AccessibleStateType::VISIBLE; + } + std::array<Any, 2> aOldValue, aNewValue; + if ( m_bEnabled ) + { + aOldValue[0] <<= AccessibleStateType::SENSITIVE; + aOldValue[1] <<= nStateType; + } + else + { + aNewValue[0] <<= nStateType; + aNewValue[1] <<= AccessibleStateType::SENSITIVE; + } + m_bEnabled = bEnabled; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[0], aNewValue[0] ); + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[1], aNewValue[1] ); +} + + +void OAccessibleMenuBaseComponent::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 OAccessibleMenuBaseComponent::SetVisible( bool bVisible ) +{ + if ( m_bVisible != bVisible ) + { + Any aOldValue, aNewValue; + if ( m_bVisible ) + aOldValue <<= AccessibleStateType::VISIBLE; + else + aNewValue <<= AccessibleStateType::VISIBLE; + m_bVisible = bVisible; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + + +void OAccessibleMenuBaseComponent::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 ); + } +} + + +void OAccessibleMenuBaseComponent::SetChecked( bool bChecked ) +{ + if ( m_bChecked != bChecked ) + { + Any aOldValue, aNewValue; + if ( m_bChecked ) + aOldValue <<= AccessibleStateType::CHECKED; + else + aNewValue <<= AccessibleStateType::CHECKED; + m_bChecked = bChecked; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + + +void OAccessibleMenuBaseComponent::UpdateEnabled( sal_Int32 i, bool bEnabled ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren1.size() ) + { + rtl::Reference< OAccessibleMenuBaseComponent > xChild( m_aAccessibleChildren1[i] ); + if ( xChild.is() ) + xChild->SetEnabled( bEnabled ); + } +} + + +void OAccessibleMenuBaseComponent::UpdateFocused( sal_Int32 i, bool bFocused ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren1.size() ) + { + rtl::Reference< OAccessibleMenuBaseComponent > xChild( m_aAccessibleChildren1[i] ); + if ( xChild.is() ) + xChild->SetFocused( bFocused ); + } +} + + +void OAccessibleMenuBaseComponent::UpdateVisible() +{ + SetVisible( IsVisible() ); + for (const rtl::Reference<OAccessibleMenuItemComponent>& xChild : m_aAccessibleChildren1) + { + if ( xChild.is() ) + xChild->SetVisible( xChild->IsVisible() ); + } +} + + +void OAccessibleMenuBaseComponent::UpdateSelected( sal_Int32 i, bool bSelected ) +{ + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren1.size() ) + { + rtl::Reference< OAccessibleMenuBaseComponent > xChild( m_aAccessibleChildren1[i] ); + if ( xChild.is() ) + xChild->SetSelected( bSelected ); + } +} + + +void OAccessibleMenuBaseComponent::UpdateChecked( sal_Int32 i, bool bChecked ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren1.size() ) + { + rtl::Reference< OAccessibleMenuBaseComponent > xChild( m_aAccessibleChildren1[i] ); + if ( xChild.is() ) + xChild->SetChecked( bChecked ); + } +} + + +void OAccessibleMenuBaseComponent::UpdateAccessibleName( sal_Int32 i ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren1.size() ) + { + rtl::Reference< OAccessibleMenuBaseComponent > xChild( m_aAccessibleChildren1[i] ); + if ( xChild.is() ) + { + OAccessibleMenuItemComponent* pComp = static_cast< OAccessibleMenuItemComponent* >( xChild.get() ); + if ( pComp ) + pComp->SetAccessibleName( pComp->GetAccessibleName() ); + } + } +} + +void OAccessibleMenuBaseComponent::UpdateItemRole(sal_Int32 i) +{ + if (i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren1.size()) + return; + + rtl::Reference<OAccessibleMenuItemComponent> xChild(m_aAccessibleChildren1[i]); + if (!xChild.is()) + return; + + xChild->NotifyAccessibleEvent(AccessibleEventId::ROLE_CHANGED, Any(), Any()); +} + +void OAccessibleMenuBaseComponent::UpdateItemText( sal_Int32 i ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren1.size() ) + { + rtl::Reference< OAccessibleMenuItemComponent > xChild( m_aAccessibleChildren1[i] ); + if ( xChild.is() ) + xChild->SetItemText( xChild->GetItemText() ); + } +} + + +sal_Int64 OAccessibleMenuBaseComponent::GetChildCount() const +{ + return m_aAccessibleChildren1.size(); +} + + +Reference< XAccessible > OAccessibleMenuBaseComponent::GetChild( sal_Int64 i ) +{ + rtl::Reference< OAccessibleMenuItemComponent > xChild = m_aAccessibleChildren1[i]; + if ( !xChild.is() ) + { + if ( m_pMenu ) + { + // create a new child + rtl::Reference<OAccessibleMenuItemComponent> pChild; + + if ( m_pMenu->GetItemType( static_cast<sal_uInt16>(i) ) == MenuItemType::SEPARATOR ) + { + pChild = new VCLXAccessibleMenuSeparator( m_pMenu, static_cast<sal_uInt16>(i) ); + } + else + { + PopupMenu* pPopupMenu = m_pMenu->GetPopupMenu( m_pMenu->GetItemId( static_cast<sal_uInt16>(i) ) ); + if ( pPopupMenu ) + { + pChild = new VCLXAccessibleMenu( m_pMenu, static_cast<sal_uInt16>(i), pPopupMenu ); + pPopupMenu->SetAccessible( pChild ); + } + else + { + pChild = new VCLXAccessibleMenuItem( m_pMenu, static_cast<sal_uInt16>(i) ); + } + } + + // set states + pChild->SetStates(); + + xChild = pChild; + + // insert into menu item list + m_aAccessibleChildren1[i] = xChild; + } + } + + return xChild; +} + + +Reference< XAccessible > OAccessibleMenuBaseComponent::GetChildAt( const awt::Point& rPoint ) +{ + Reference< XAccessible > xChild; + for ( sal_Int64 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i ) + { + Reference< XAccessible > xAcc = getAccessibleChild( i ); + if ( xAcc.is() ) + { + Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY ); + if ( xComp.is() ) + { + tools::Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.Contains( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; +} + + +void OAccessibleMenuBaseComponent::InsertChild( sal_Int32 i ) +{ + if ( i < 0 ) + return; + + if ( o3tl::make_unsigned(i) > m_aAccessibleChildren1.size() ) + i = m_aAccessibleChildren1.size(); + + // insert entry in child list + m_aAccessibleChildren1.insert( m_aAccessibleChildren1.begin() + i, rtl::Reference< OAccessibleMenuItemComponent >() ); + + // update item position of accessible children + for ( sal_uInt32 j = i, nCount = m_aAccessibleChildren1.size(); j < nCount; ++j ) + { + rtl::Reference< OAccessibleMenuItemComponent > xAcc( m_aAccessibleChildren1[j] ); + if ( xAcc.is() ) + xAcc->SetItemPos( static_cast<sal_uInt16>(j) ); + } + + // send accessible child event + Reference< XAccessible > xChild( GetChild( i ) ); + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } +} + + +void OAccessibleMenuBaseComponent::RemoveChild( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren1.size() ) + return; + + // keep the accessible of the removed item + rtl::Reference< OAccessibleMenuItemComponent > xChild( m_aAccessibleChildren1[i] ); + + // remove entry in child list + m_aAccessibleChildren1.erase( m_aAccessibleChildren1.begin() + i ); + + // update item position of accessible children + for ( sal_uInt32 j = i, nCount = m_aAccessibleChildren1.size(); j < nCount; ++j ) + { + rtl::Reference< OAccessibleMenuItemComponent > xAcc( m_aAccessibleChildren1[j] ); + if ( xAcc.is() ) + xAcc->SetItemPos( static_cast<sal_uInt16>(j) ); + } + + // send accessible child event + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aOldValue <<= uno::Reference<XAccessible>(xChild); + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + xChild->dispose(); + } +} + + +bool OAccessibleMenuBaseComponent::IsHighlighted() +{ + return false; +} + + +bool OAccessibleMenuBaseComponent::IsChildHighlighted() +{ + bool bChildHighlighted = false; + + for (const rtl::Reference<OAccessibleMenuItemComponent>& xChild : m_aAccessibleChildren1) + { + if ( xChild.is() && xChild->IsHighlighted() ) + { + bChildHighlighted = true; + break; + } + } + + return bChildHighlighted; +} + + +void OAccessibleMenuBaseComponent::SelectChild( sal_Int32 i ) +{ + // open the menu + if ( getAccessibleRole() == AccessibleRole::MENU && !IsPopupMenuOpen() ) + Click(); + + // highlight the child + if ( m_pMenu ) + m_pMenu->HighlightItem( static_cast<sal_uInt16>(i) ); +} + + +void OAccessibleMenuBaseComponent::DeSelectAll() +{ + if ( m_pMenu ) + m_pMenu->DeHighlight(); +} + + +bool OAccessibleMenuBaseComponent::IsChildSelected( sal_Int32 i ) +{ + bool bSelected = false; + + if ( m_pMenu && m_pMenu->IsHighlighted( static_cast<sal_uInt16>(i) ) ) + bSelected = true; + + return bSelected; +} + + +void OAccessibleMenuBaseComponent::Click() +{ +} + + +bool OAccessibleMenuBaseComponent::IsPopupMenuOpen() +{ + return false; +} + + +IMPL_LINK( OAccessibleMenuBaseComponent, MenuEventListener, VclMenuEvent&, rEvent, void ) +{ + OSL_ENSURE( rEvent.GetMenu(), "OAccessibleMenuBaseComponent - Menu?" ); + ProcessMenuEvent( rEvent ); +} + + +void OAccessibleMenuBaseComponent::ProcessMenuEvent( const VclMenuEvent& rVclMenuEvent ) +{ + sal_uInt16 nItemPos = rVclMenuEvent.GetItemPos(); + + switch ( rVclMenuEvent.GetId() ) + { + case VclEventId::MenuShow: + case VclEventId::MenuHide: + { + UpdateVisible(); + } + break; + case VclEventId::MenuHighlight: + { + SetFocused( false ); + UpdateFocused( nItemPos, true ); + UpdateSelected( nItemPos, true ); + } + break; + case VclEventId::MenuDehighlight: + { + UpdateFocused( nItemPos, false ); + UpdateSelected( nItemPos, false ); + } + break; + case VclEventId::MenuSubmenuActivate: + { + } + break; + case VclEventId::MenuSubmenuDeactivate: + { + UpdateFocused( nItemPos, true ); + } + break; + case VclEventId::MenuEnable: + { + UpdateEnabled( nItemPos, true ); + } + break; + case VclEventId::MenuDisable: + { + UpdateEnabled( nItemPos, false ); + } + break; + case VclEventId::MenuSubmenuChanged: + { + RemoveChild( nItemPos ); + InsertChild( nItemPos ); + } + break; + case VclEventId::MenuInsertItem: + { + InsertChild( nItemPos ); + } + break; + case VclEventId::MenuRemoveItem: + { + RemoveChild( nItemPos ); + } + break; + case VclEventId::MenuAccessibleNameChanged: + { + UpdateAccessibleName( nItemPos ); + } + break; + case VclEventId::MenuItemRoleChanged: + { + UpdateItemRole(nItemPos); + } + break; + case VclEventId::MenuItemTextChanged: + { + UpdateAccessibleName( nItemPos ); + UpdateItemText( nItemPos ); + } + break; + case VclEventId::MenuItemChecked: + { + UpdateChecked( nItemPos, true ); + } + break; + case VclEventId::MenuItemUnchecked: + { + UpdateChecked( nItemPos, false ); + } + break; + case VclEventId::ObjectDying: + { + if ( m_pMenu ) + { + m_pMenu->RemoveEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) ); + + m_pMenu = nullptr; + + // dispose all menu items + for (const rtl::Reference<OAccessibleMenuItemComponent>& xComponent : m_aAccessibleChildren1) + { + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren1.clear(); + } + } + break; + default: + { + } + break; + } +} + + +// XComponent + + +void OAccessibleMenuBaseComponent::disposing() +{ + OAccessibleExtendedComponentHelper::disposing(); + + if ( !m_pMenu ) + return; + + m_pMenu->RemoveEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) ); + + m_pMenu = nullptr; + + // dispose all menu items + for (const rtl::Reference<OAccessibleMenuItemComponent>& xComponent : m_aAccessibleChildren1) + { + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren1.clear(); +} + + +// XServiceInfo + + +sal_Bool OAccessibleMenuBaseComponent::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + + +// XAccessible + + +Reference< XAccessibleContext > OAccessibleMenuBaseComponent::getAccessibleContext( ) +{ + OExternalLockGuard aGuard( this ); + + return this; +} + + +// XAccessibleContext + + +sal_Int64 OAccessibleMenuBaseComponent::getAccessibleStateSet( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; +} + + +bool OAccessibleMenuBaseComponent::IsMenuHideDisabledEntries() +{ + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/accessiblemenucomponent.cxx b/accessibility/source/standard/accessiblemenucomponent.cxx new file mode 100644 index 0000000000..9d86f0246a --- /dev/null +++ b/accessibility/source/standard/accessiblemenucomponent.cxx @@ -0,0 +1,411 @@ +/* -*- 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 <standard/accessiblemenucomponent.hxx> + +#include <toolkit/awt/vclxfont.hxx> +#include <toolkit/helper/convert.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/menu.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; +using namespace ::comphelper; + + + + +bool OAccessibleMenuComponent::IsEnabled() +{ + return true; +} + + +bool OAccessibleMenuComponent::IsVisible() +{ + bool bVisible = false; + + if ( m_pMenu ) + bVisible = m_pMenu->IsMenuVisible(); + + return bVisible; +} + + +void OAccessibleMenuComponent::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + if ( IsEnabled() ) + { + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + } + + rStateSet |= AccessibleStateType::FOCUSABLE; + + if ( IsFocused() ) + rStateSet |= AccessibleStateType::FOCUSED; + + if ( IsVisible() ) + { + rStateSet |= AccessibleStateType::VISIBLE; + rStateSet |= AccessibleStateType::SHOWING; + } + + rStateSet |= AccessibleStateType::OPAQUE; +} + + +// OCommonAccessibleComponent + + +awt::Rectangle OAccessibleMenuComponent::implGetBounds() +{ + awt::Rectangle aBounds( 0, 0, 0, 0 ); + + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + { + // get bounding rectangle of the window in screen coordinates + AbsoluteScreenPixelRectangle aRect = pWindow->GetWindowExtentsAbsolute(); + aBounds = AWTRectangle( aRect ); + + // get position of the accessible parent in screen coordinates + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComponent.is() ) + { + awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen(); + + // calculate position of the window relative to the accessible parent + aBounds.X -= aParentScreenLoc.X; + aBounds.Y -= aParentScreenLoc.Y; + } + } + } + } + + return aBounds; +} + + +// XAccessibleContext + + +sal_Int64 OAccessibleMenuComponent::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + return GetChildCount(); +} + + +Reference< XAccessible > OAccessibleMenuComponent::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + return GetChild( i ); +} + + +Reference< XAccessible > OAccessibleMenuComponent::getAccessibleParent( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + { + vcl::Window* pParent = pWindow->GetAccessibleParentWindow(); + if ( pParent ) + xParent = pParent->GetAccessible(); + } + } + + return xParent; +} + + +sal_Int16 OAccessibleMenuComponent::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::UNKNOWN; +} + + +OUString OAccessibleMenuComponent::getAccessibleDescription( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sDescription; + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + sDescription = pWindow->GetAccessibleDescription(); + } + + return sDescription; +} + + +OUString OAccessibleMenuComponent::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +Reference< XAccessibleRelationSet > OAccessibleMenuComponent::getAccessibleRelationSet( ) +{ + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; +} + + +Locale OAccessibleMenuComponent::getLocale( ) +{ + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +// XAccessibleComponent + + +Reference< XAccessible > OAccessibleMenuComponent::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + OExternalLockGuard aGuard( this ); + + return GetChildAt( rPoint ); +} + + +awt::Point OAccessibleMenuComponent::getLocationOnScreen( ) +{ + OExternalLockGuard aGuard( this ); + + awt::Point aPos; + + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + { + AbsoluteScreenPixelRectangle aRect = pWindow->GetWindowExtentsAbsolute(); + aPos = AWTPoint( aRect.TopLeft() ); + } + } + + return aPos; +} + + +void OAccessibleMenuComponent::grabFocus( ) +{ + OExternalLockGuard aGuard( this ); + + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + pWindow->GrabFocus(); + } +} + + +sal_Int32 OAccessibleMenuComponent::getForeground( ) +{ + OExternalLockGuard aGuard( this ); + + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + Color nColor = rStyleSettings.GetMenuTextColor(); + + return sal_Int32(nColor); +} + + +sal_Int32 OAccessibleMenuComponent::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +// XAccessibleExtendedComponent + + +Reference< awt::XFont > OAccessibleMenuComponent::getFont( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + { + Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), UNO_QUERY ); + if ( xDev.is() ) + { + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + rtl::Reference<VCLXFont> pVCLXFont = new VCLXFont; + pVCLXFont->Init( *xDev, rStyleSettings.GetMenuFont() ); + xFont = pVCLXFont; + } + } + } + + return xFont; +} + + +OUString OAccessibleMenuComponent::getTitledBorderText( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +OUString OAccessibleMenuComponent::getToolTipText( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +// XAccessibleSelection + + +void OAccessibleMenuComponent::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + SelectChild( nChildIndex ); +} + + +sal_Bool OAccessibleMenuComponent::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + return IsChildSelected( nChildIndex ); +} + + +void OAccessibleMenuComponent::clearAccessibleSelection( ) +{ + OExternalLockGuard aGuard( this ); + + DeSelectAll(); +} + + +void OAccessibleMenuComponent::selectAllAccessibleChildren( ) +{ + // This method makes no sense in a menu, and so does nothing. +} + + +sal_Int64 OAccessibleMenuComponent::getSelectedAccessibleChildCount( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nRet = 0; + + for ( sal_Int64 i = 0, nCount = GetChildCount(); i < nCount; i++ ) + { + if ( IsChildSelected( i ) ) + ++nRet; + } + + return nRet; +} + + +Reference< XAccessible > OAccessibleMenuComponent::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + + for ( sal_Int64 i = 0, j = 0, nCount = GetChildCount(); i < nCount; i++ ) + { + if ( IsChildSelected( i ) && ( j++ == nSelectedChildIndex ) ) + { + xChild = GetChild( i ); + break; + } + } + + return xChild; +} + + +void OAccessibleMenuComponent::deselectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + DeSelectAll(); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/accessiblemenuitemcomponent.cxx b/accessibility/source/standard/accessiblemenuitemcomponent.cxx new file mode 100644 index 0000000000..d3cc712bbc --- /dev/null +++ b/accessibility/source/standard/accessiblemenuitemcomponent.cxx @@ -0,0 +1,473 @@ +/* -*- 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 <standard/accessiblemenuitemcomponent.hxx> + + +#include <toolkit/helper/convert.hxx> + +#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 <unotools/accessiblerelationsethelper.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessibletexthelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/menu.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; +using namespace ::comphelper; + + + + +OAccessibleMenuItemComponent::OAccessibleMenuItemComponent( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu ) + :OAccessibleMenuBaseComponent( pMenu ) + ,m_pParent( pParent ) + ,m_nItemPos( nItemPos ) +{ + m_sAccessibleName = GetAccessibleName(); + m_sItemText = GetItemText(); +} + +OAccessibleMenuItemComponent::~OAccessibleMenuItemComponent() +{ +} + +bool OAccessibleMenuItemComponent::IsEnabled() +{ + OExternalLockGuard aGuard( this ); + + bool bEnabled = false; + if ( m_pParent ) + bEnabled = m_pParent->IsItemEnabled( m_pParent->GetItemId( m_nItemPos ) ); + + return bEnabled; +} + + +bool OAccessibleMenuItemComponent::IsVisible() +{ + bool bVisible = false; + + if ( m_pParent ) + bVisible = m_pParent->IsItemPosVisible( m_nItemPos ); + + return bVisible; +} + + +void OAccessibleMenuItemComponent::Select() +{ + // open the parent menu + Reference< XAccessible > xParent( getAccessibleParent() ); + if ( xParent.is() ) + { + OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xParent.get() ); + if ( pComp && pComp->getAccessibleRole() == AccessibleRole::MENU && !pComp->IsPopupMenuOpen() ) + pComp->Click(); + } + + // highlight the menu item + if ( m_pParent ) + m_pParent->HighlightItem( m_nItemPos ); +} + + +void OAccessibleMenuItemComponent::DeSelect() +{ + if ( m_pParent && IsSelected() ) + m_pParent->DeHighlight(); +} + + +void OAccessibleMenuItemComponent::Click() +{ + // open the parent menu + Reference< XAccessible > xParent( getAccessibleParent() ); + if ( xParent.is() ) + { + OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xParent.get() ); + if ( pComp && pComp->getAccessibleRole() == AccessibleRole::MENU && !pComp->IsPopupMenuOpen() ) + pComp->Click(); + } + + // click the menu item + if ( !m_pParent ) + return; + + vcl::Window* pWindow = m_pParent->GetWindow(); + if ( !pWindow ) + return; + + // #102438# Menu items are not selectable + // Popup menus are executed asynchronously, triggered by a timer. + // As Menu::SelectItem only works, if the corresponding menu window is + // already created, we have to set the menu delay to 0, so + // that the popup menus are executed synchronously. + AllSettings aSettings = pWindow->GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + sal_Int32 nDelay = aMouseSettings.GetMenuDelay(); + aMouseSettings.SetMenuDelay( 0 ); + aSettings.SetMouseSettings( aMouseSettings ); + pWindow->SetSettings( aSettings ); + + m_pParent->SelectItem( m_pParent->GetItemId( m_nItemPos ) ); + + // meanwhile the window pointer may be invalid + pWindow = m_pParent->GetWindow(); + if ( pWindow ) + { + // set the menu delay back to the old value + aSettings = pWindow->GetSettings(); + aMouseSettings = aSettings.GetMouseSettings(); + aMouseSettings.SetMenuDelay( nDelay ); + aSettings.SetMouseSettings( aMouseSettings ); + pWindow->SetSettings( aSettings ); + } +} + + +void OAccessibleMenuItemComponent::SetItemPos( sal_uInt16 nItemPos ) +{ + m_nItemPos = nItemPos; +} + + +void OAccessibleMenuItemComponent::SetAccessibleName( const OUString& sAccessibleName ) +{ + if ( m_sAccessibleName != sAccessibleName ) + { + Any aOldValue, aNewValue; + aOldValue <<= m_sAccessibleName; + aNewValue <<= sAccessibleName; + m_sAccessibleName = sAccessibleName; + NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } +} + + +OUString OAccessibleMenuItemComponent::GetAccessibleName() +{ + OUString sName; + if ( m_pParent ) + { + sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos ); + sName = m_pParent->GetAccessibleName( nItemId ); + if ( sName.isEmpty() ) + sName = m_pParent->GetItemText( nItemId ); + sName = removeMnemonicFromString( sName ); +#if defined(_WIN32) + if ( m_pParent->GetAccelKey( nItemId ).GetName().getLength() ) + sName += "\t" + m_pParent->GetAccelKey(nItemId).GetName(); +#endif + } + + return sName; +} + + +void OAccessibleMenuItemComponent::SetItemText( const OUString& sItemText ) +{ + Any aOldValue, aNewValue; + if ( OCommonAccessibleText::implInitTextChangedEvent( m_sItemText, sItemText, aOldValue, aNewValue ) ) + { + m_sItemText = sItemText; + NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue ); + } +} + + +OUString OAccessibleMenuItemComponent::GetItemText() +{ + OUString sText; + if ( m_pParent ) + sText = removeMnemonicFromString( m_pParent->GetItemText( m_pParent->GetItemId( m_nItemPos ) ) ); + + return sText; +} + + +void OAccessibleMenuItemComponent::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + bool bEnabled = IsEnabled(); + if ( bEnabled ) + { + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + } + + if ( IsVisible() ) + { + rStateSet |= AccessibleStateType::SHOWING; + if( !IsMenuHideDisabledEntries() || bEnabled ) + rStateSet |= AccessibleStateType::VISIBLE; + } + rStateSet |= AccessibleStateType::OPAQUE; +} + + +// OCommonAccessibleComponent + + +awt::Rectangle OAccessibleMenuItemComponent::implGetBounds() +{ + awt::Rectangle aBounds( 0, 0, 0, 0 ); + + if ( m_pParent ) + { + // get bounding rectangle of the item relative to the containing window + aBounds = AWTRectangle( m_pParent->GetBoundingRectangle( m_nItemPos ) ); + + // get position of containing window in screen coordinates + vcl::Window* pWindow = m_pParent->GetWindow(); + if ( pWindow ) + { + AbsoluteScreenPixelRectangle aRect = pWindow->GetWindowExtentsAbsolute(); + awt::Point aWindowScreenLoc = AWTPoint( aRect.TopLeft() ); + + // get position of accessible parent in screen coordinates + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComponent.is() ) + { + awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen(); + + // calculate bounding rectangle of the item relative to the accessible parent + aBounds.X += aWindowScreenLoc.X - aParentScreenLoc.X; + aBounds.Y += aWindowScreenLoc.Y - aParentScreenLoc.Y; + } + } + } + } + + return aBounds; +} + + +// XComponent + + +void SAL_CALL OAccessibleMenuItemComponent::disposing() +{ + OAccessibleMenuBaseComponent::disposing(); + + m_pParent = nullptr; + m_sAccessibleName.clear(); + m_sItemText.clear(); +} + + +// XAccessibleContext + + +sal_Int64 OAccessibleMenuItemComponent::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +Reference< XAccessible > OAccessibleMenuItemComponent::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + return Reference< XAccessible >(); +} + + +Reference< XAccessible > OAccessibleMenuItemComponent::getAccessibleParent( ) +{ + OExternalLockGuard aGuard( this ); + + return m_pParent->GetAccessible(); +} + + +sal_Int64 OAccessibleMenuItemComponent::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + return m_nItemPos; +} + + +sal_Int16 OAccessibleMenuItemComponent::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::UNKNOWN; +} + + +OUString OAccessibleMenuItemComponent::getAccessibleDescription( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sDescription; + if ( m_pParent ) + sDescription = m_pParent->GetAccessibleDescription( m_pParent->GetItemId( m_nItemPos ) ); + + return sDescription; +} + + +OUString OAccessibleMenuItemComponent::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + return m_sAccessibleName; +} + + +Reference< XAccessibleRelationSet > OAccessibleMenuItemComponent::getAccessibleRelationSet( ) +{ + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; +} + + +Locale OAccessibleMenuItemComponent::getLocale( ) +{ + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +// XAccessibleComponent + + +Reference< XAccessible > OAccessibleMenuItemComponent::getAccessibleAtPoint( const awt::Point& ) +{ + OExternalLockGuard aGuard( this ); + + return Reference< XAccessible >(); +} + + +void OAccessibleMenuItemComponent::grabFocus( ) +{ + // no focus for items +} + + +sal_Int32 OAccessibleMenuItemComponent::getForeground( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; +} + + +sal_Int32 OAccessibleMenuItemComponent::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; +} + + +// XAccessibleExtendedComponent + + +Reference< awt::XFont > OAccessibleMenuItemComponent::getFont( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; +} + + +OUString OAccessibleMenuItemComponent::getTitledBorderText( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +OUString OAccessibleMenuItemComponent::getToolTipText( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sRet; + if ( m_pParent ) + sRet = m_pParent->GetTipHelpText( m_pParent->GetItemId( m_nItemPos ) ); + + return sRet; +} + + +bool OAccessibleMenuItemComponent::IsMenuHideDisabledEntries() +{ + if (m_pParent ) + { + if( m_pParent->GetMenuFlags() & MenuFlags::HideDisabledEntries) + { + return true; + } + } + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/floatingwindowaccessible.cxx b/accessibility/source/standard/floatingwindowaccessible.cxx new file mode 100644 index 0000000000..aa5ef41f6c --- /dev/null +++ b/accessibility/source/standard/floatingwindowaccessible.cxx @@ -0,0 +1,45 @@ +/* -*- 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 <floatingwindowaccessible.hxx> + +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/window.hxx> + +namespace uno = ::com::sun::star::uno; + +using ::com::sun::star::accessibility::AccessibleRelation; +namespace AccessibleRelationType = ::com::sun::star::accessibility::AccessibleRelationType; + +void FloatingWindowAccessible::FillAccessibleRelationSet(utl::AccessibleRelationSetHelper& rRelationSet) +{ + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + vcl::Window* pParentWindow = pWindow->GetParent(); + if( pParentWindow ) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pParentWindow->GetAccessible() }; + rRelationSet.AddRelation( AccessibleRelation( AccessibleRelationType::SUB_WINDOW_OF, aSequence ) ); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/svtaccessiblenumericfield.cxx b/accessibility/source/standard/svtaccessiblenumericfield.cxx new file mode 100644 index 0000000000..f3192d4212 --- /dev/null +++ b/accessibility/source/standard/svtaccessiblenumericfield.cxx @@ -0,0 +1,110 @@ +/* -*- 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 <standard/svtaccessiblenumericfield.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <toolkit/awt/vclxwindows.hxx> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + +SVTXAccessibleNumericField::SVTXAccessibleNumericField(VCLXWindow* pVCLWindow) + : ImplInheritanceHelper(pVCLWindow) +{ +} + +void SVTXAccessibleNumericField::ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent) +{ + VCLXAccessibleEdit::ProcessWindowEvent(rVclWindowEvent); + + if (rVclWindowEvent.GetId() == VclEventId::EditModify) + { + css::uno::Any aNewValue = getCurrentValue(); + NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, css::uno::Any(), aNewValue); + } +} + +sal_Int16 SVTXAccessibleNumericField::getAccessibleRole() { return AccessibleRole::SPIN_BOX; } + +css::uno::Any SAL_CALL SVTXAccessibleNumericField::getCurrentValue() +{ + OExternalLockGuard aGuard(this); + + double dValue = 0; + SVTXNumericField* pField = static_cast<SVTXNumericField*>(GetVCLXWindow()); + if (pField) + dValue = pField->getValue(); + + return css::uno::Any(dValue); +} + +sal_Bool SVTXAccessibleNumericField::setCurrentValue(const css::uno::Any& aNumber) +{ + OExternalLockGuard aGuard(this); + + SVTXNumericField* pField = static_cast<SVTXNumericField*>(GetVCLXWindow()); + if (!pField) + return false; + + double dValue = 0; + aNumber >>= dValue; + pField->setValue(dValue); + return true; +} + +css::uno::Any SAL_CALL SVTXAccessibleNumericField::getMaximumValue() +{ + OExternalLockGuard aGuard(this); + + double dValue = 0; + SVTXNumericField* pField = static_cast<SVTXNumericField*>(GetVCLXWindow()); + if (pField) + dValue = pField->getMax(); + + return css::uno::Any(dValue); +} + +css::uno::Any SAL_CALL SVTXAccessibleNumericField::getMinimumValue() +{ + OExternalLockGuard aGuard(this); + + double dValue = 0; + SVTXNumericField* pField = static_cast<SVTXNumericField*>(GetVCLXWindow()); + if (pField) + dValue = pField->getMin(); + + return css::uno::Any(dValue); +} + +css::uno::Any SAL_CALL SVTXAccessibleNumericField::getMinimumIncrement() +{ + OExternalLockGuard aGuard(this); + + double dValue = 0; + SVTXNumericField* pField = static_cast<SVTXNumericField*>(GetVCLXWindow()); + if (pField) + dValue = pField->getSpinSize(); + + return css::uno::Any(dValue); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblebox.cxx b/accessibility/source/standard/vclxaccessiblebox.cxx new file mode 100644 index 0000000000..cbc68fb2d1 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblebox.cxx @@ -0,0 +1,523 @@ +/* -*- 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 <standard/vclxaccessiblebox.hxx> +#include <standard/vclxaccessibletextfield.hxx> +#include <standard/vclxaccessibleedit.hxx> +#include <standard/vclxaccessiblelist.hxx> + +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <vcl/svapp.hxx> +#include <vcl/toolkit/combobox.hxx> +#include <vcl/toolkit/lstbox.hxx> +#include <strings.hxx> + +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; + +VCLXAccessibleBox::VCLXAccessibleBox (VCLXWindow* pVCLWindow, BoxType aType, bool bIsDropDownBox) + : ImplInheritanceHelper (pVCLWindow), + m_aBoxType (aType), + m_bIsDropDownBox (bIsDropDownBox) +{ + // Set up the flags that indicate which children this object has. + m_bHasListChild = true; + + // A text field is not present for non drop down list boxes. + if ((m_aBoxType==LISTBOX) && ! m_bIsDropDownBox) + m_bHasTextChild = false; + else + m_bHasTextChild = true; +} + +VCLXAccessibleBox::~VCLXAccessibleBox() {} + +void VCLXAccessibleBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) +{ + uno::Any aOldValue, aNewValue; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowShow: + case VclEventId::WindowHide: + { + vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData()); + // Just compare to the combo box text field. All other children + // are identical to this object in which case this object will + // be removed in a short time. + if (m_aBoxType==COMBOBOX) + { + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if ( ( pComboBox != nullptr ) && ( pChildWindow != nullptr ) ) + if (pChildWindow == pComboBox->GetSubEdit()) + { + if (rVclWindowEvent.GetId() == VclEventId::WindowShow) + { + // Instantiate text field. + getAccessibleChild (0); + aNewValue <<= m_xText; + } + else + { + // Release text field. + aOldValue <<= m_xText; + m_xText = nullptr; + } + // Tell the listeners about the new/removed child. + NotifyAccessibleEvent ( + AccessibleEventId::CHILD, + aOldValue, aNewValue); + } + + } + } + break; + + default: + VCLXAccessibleComponent::ProcessWindowChildEvent (rVclWindowEvent); + } +} + +void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::DropdownSelect: + case VclEventId::ListboxSelect: + { + // Forward the call to the list child. + VCLXAccessibleList* pList = m_xList.get(); + if ( pList == nullptr ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = m_xList.get(); + } + if ( pList != nullptr ) + { + pList->ProcessWindowEvent (rVclWindowEvent, m_bIsDropDownBox); +#if defined(_WIN32) + if (m_bIsDropDownBox) + { + NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any()); + } +#endif + } + break; + } + case VclEventId::DropdownOpen: + { + VCLXAccessibleList* pList = m_xList.get(); + if ( pList == nullptr ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = m_xList.get(); + } + if ( pList != nullptr ) + { + pList->ProcessWindowEvent (rVclWindowEvent); + pList->HandleDropOpen(); + } + break; + } + case VclEventId::DropdownClose: + { + VCLXAccessibleList* pList = m_xList.get(); + if ( pList == nullptr ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = m_xList.get(); + } + if ( pList != nullptr ) + { + pList->ProcessWindowEvent (rVclWindowEvent); + } + VclPtr<vcl::Window> pWindow = GetWindow(); + if( pWindow && (pWindow->HasFocus() || pWindow->HasChildPathFocus()) ) + { + Any aOldValue, aNewValue; + aNewValue <<= AccessibleStateType::FOCUSED; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + } + case VclEventId::ComboboxSelect: + { + VCLXAccessibleList* pList = m_xList.get(); + if (pList != nullptr && m_xText.is()) + { + Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); + if ( xText.is() ) + { + OUString sText = xText->getSelectedText(); + if ( sText.isEmpty() ) + sText = xText->getText(); + pList->UpdateSelection_Acc(sText, m_bIsDropDownBox); +#if defined(_WIN32) + if (m_bIsDropDownBox || m_aBoxType==COMBOBOX) + NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any()); +#endif + } + } + break; + } + //case VclEventId::DropdownOpen: + //case VclEventId::DropdownClose: + case VclEventId::ListboxDoubleClick: + case VclEventId::ListboxScrolled: + //case VclEventId::ListboxSelect: + case VclEventId::ListboxItemAdded: + case VclEventId::ListboxItemRemoved: + case VclEventId::ComboboxItemAdded: + case VclEventId::ComboboxItemRemoved: + { + // Forward the call to the list child. + VCLXAccessibleList* pList = m_xList.get(); + if ( pList == nullptr ) + { + getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); + pList = m_xList.get(); + } + if ( pList != nullptr ) + pList->ProcessWindowEvent (rVclWindowEvent); + break; + } + + //case VclEventId::ComboboxSelect: + case VclEventId::ComboboxDeselect: + { + // Selection is handled by VCLXAccessibleList which operates on + // the same VCL object as this box does. In case of the + // combobox, however, we have to help by providing the list with + // the text of the currently selected item. + VCLXAccessibleList* pList = m_xList.get(); + if (pList != nullptr && m_xText.is()) + { + Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); + if ( xText.is() ) + { + OUString sText = xText->getSelectedText(); + if ( sText.isEmpty() ) + sText = xText->getText(); + pList->UpdateSelection (sText); + } + } + break; + } + + case VclEventId::EditModify: + case VclEventId::EditSelectionChanged: + case VclEventId::EditCaretChanged: + // Modify/Selection events are handled by the combo box instead of + // directly by the edit field (Why?). Therefore, delegate this + // call to the edit field. + if (m_aBoxType==COMBOBOX) + { + if (m_xText.is()) + { + Reference<XAccessibleContext> xContext = m_xText->getAccessibleContext(); + VCLXAccessibleEdit* pEdit = static_cast<VCLXAccessibleEdit*>(xContext.get()); + if (pEdit != nullptr) + pEdit->ProcessWindowEvent (rVclWindowEvent); + } + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + +//===== XAccessible ========================================================= + +Reference< XAccessibleContext > SAL_CALL VCLXAccessibleBox::getAccessibleContext( ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return this; +} + +//===== XAccessibleContext ================================================== + +sal_Int64 VCLXAccessibleBox::getAccessibleChildCount() +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return implGetAccessibleChildCount(); +} + +sal_Int64 VCLXAccessibleBox::implGetAccessibleChildCount() +{ + // Usually a box has a text field and a list of items as its children. + // Non drop down list boxes have no text field. Additionally check + // whether the object is valid. + sal_Int64 nCount = 0; + if (IsValid()) + nCount += (m_bHasTextChild?1:0) + (m_bHasListChild?1:0); + else + { + // Object not valid anymore. Release references to children. + m_bHasTextChild = false; + m_xText = nullptr; + m_bHasListChild = false; + m_xList = nullptr; + } + + return nCount; +} + +Reference<XAccessible> SAL_CALL VCLXAccessibleBox::getAccessibleChild (sal_Int64 i) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if (i<0 || i>=implGetAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + if (IsValid()) + { + if (i==1 || ! m_bHasTextChild) + { + // List. + if ( ! m_xList.is()) + { + rtl::Reference<VCLXAccessibleList> pList = new VCLXAccessibleList ( GetVCLXWindow(), + (m_aBoxType == LISTBOX ? VCLXAccessibleList::LISTBOX : VCLXAccessibleList::COMBOBOX), + this); + pList->SetIndexInParent (i); + m_xList = pList; + } + xChild = m_xList; + } + else + { + // Text Field. + if ( ! m_xText.is()) + { + if (m_aBoxType==COMBOBOX) + { + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if (pComboBox!=nullptr && pComboBox->GetSubEdit()!=nullptr) + //Set the edit's acc name the same as parent + { + pComboBox->GetSubEdit()->SetAccessibleName(getAccessibleName()); + m_xText = pComboBox->GetSubEdit()->GetAccessible(); + } + } + else if (m_bIsDropDownBox) + m_xText = new VCLXAccessibleTextField (GetVCLXWindow(),this); + } + xChild = m_xText; + } + } + + return xChild; +} + +sal_Int16 SAL_CALL VCLXAccessibleBox::getAccessibleRole() +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + // Return the role <const>COMBO_BOX</const> for both VCL combo boxes and + // VCL list boxes in DropDown-Mode else <const>PANEL</const>. + // This way the Java bridge has not to handle both independently. + //return m_bIsDropDownBox ? AccessibleRole::COMBO_BOX : AccessibleRole::PANEL; + if (m_bIsDropDownBox || (m_aBoxType == COMBOBOX)) + return AccessibleRole::COMBO_BOX; + else + return AccessibleRole::PANEL; +} + +//===== XAccessibleAction =================================================== + +sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleActionCount() +{ + ::osl::Guard< ::osl::Mutex> aGuard (GetMutex()); + + // There is one action for drop down boxes (toggle popup) and none for + // the other boxes. + return m_bIsDropDownBox ? 1 : 0; +} + +sal_Bool SAL_CALL VCLXAccessibleBox::doAccessibleAction (sal_Int32 nIndex) +{ + bool bNotify = false; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if (nIndex!=0 || !m_bIsDropDownBox) + throw css::lang::IndexOutOfBoundsException( + ("VCLXAccessibleBox::doAccessibleAction: index " + + OUString::number(nIndex) + " not among 0.." + + OUString::number(getAccessibleActionCount())), + getXWeak()); + + if (m_aBoxType == COMBOBOX) + { + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if (pComboBox != nullptr) + { + pComboBox->ToggleDropDown(); + bNotify = true; + } + } + else if (m_aBoxType == LISTBOX) + { + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if (pListBox != nullptr) + { + pListBox->ToggleDropDown(); + bNotify = true; + } + } + } + + if (bNotify) + NotifyAccessibleEvent (AccessibleEventId::ACTION_CHANGED, Any(), Any()); + + return bNotify; +} + +OUString SAL_CALL VCLXAccessibleBox::getAccessibleActionDescription (sal_Int32 nIndex) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + if (nIndex!=0 || !m_bIsDropDownBox) + throw css::lang::IndexOutOfBoundsException(); + + return RID_STR_ACC_ACTION_TOGGLEPOPUP; +} + +Reference< XAccessibleKeyBinding > VCLXAccessibleBox::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + Reference< XAccessibleKeyBinding > xRet; + + if (nIndex<0 || nIndex>=getAccessibleActionCount()) + throw css::lang::IndexOutOfBoundsException(); + + // ... which key? + return xRet; +} + +// ===== XAccessibleValue =============================================== +Any VCLXAccessibleBox::getCurrentValue( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + Any aAny; + if( m_xList.is() && m_xText.is()) + { + // VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); + Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); + if ( xText.is() ) + { + OUString sText = xText->getText(); + aAny <<= sText; + } + } + if (m_aBoxType == LISTBOX && m_bIsDropDownBox && m_xList.is() ) + { + + VCLXAccessibleList* pList = m_xList.get(); + if(pList->IsInDropDown()) + { + if(pList->getSelectedAccessibleChildCount()>0) + { + Reference<XAccessibleContext> xName (pList->getSelectedAccessibleChild(sal_Int64(0)), UNO_QUERY); + if(xName.is()) + { + aAny <<= xName->getAccessibleName(); + } + } + } + } + + return aAny; +} + +sal_Bool VCLXAccessibleBox::setCurrentValue( const Any& aNumber ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + OUString fValue; + bool bValid = (aNumber >>= fValue); + return bValid; + +} + +Any VCLXAccessibleBox::getMaximumValue( ) +{ + Any aAny; + return aAny; +} + +Any VCLXAccessibleBox::getMinimumValue( ) +{ + Any aAny; + return aAny; +} + +Any VCLXAccessibleBox::getMinimumIncrement( ) +{ + return Any(); +} + +// Set the INDETERMINATE state when there is no selected item for combobox +void VCLXAccessibleBox::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet(rStateSet); + if (m_aBoxType == COMBOBOX ) + { + OUString sText; + sal_Int32 nEntryCount = 0; + VclPtr< ComboBox > pComboBox = GetAs< ComboBox >(); + if (pComboBox != nullptr) + { + Edit* pSubEdit = pComboBox->GetSubEdit(); + if ( pSubEdit) + sText = pSubEdit->GetText(); + nEntryCount = pComboBox->GetEntryCount(); + } + if ( sText.isEmpty() && nEntryCount > 0 ) + rStateSet |= AccessibleStateType::INDETERMINATE; + } + else if (m_aBoxType == LISTBOX && m_bIsDropDownBox) + { + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if (pListBox != nullptr && pListBox->GetEntryCount() > 0) + { + sal_Int32 nSelectedEntryCount = pListBox->GetSelectedEntryCount(); + if ( nSelectedEntryCount == 0) + rStateSet |= AccessibleStateType::INDETERMINATE; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblebutton.cxx b/accessibility/source/standard/vclxaccessiblebutton.cxx new file mode 100644 index 0000000000..eb4d1f0821 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblebutton.cxx @@ -0,0 +1,312 @@ +/* -*- 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 <standard/vclxaccessiblebutton.hxx> +#include <helper/accresmgr.hxx> +#include <strings.hrc> + +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessiblekeybindinghelper.hxx> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <strings.hxx> + +#include <vcl/toolkit/button.hxx> +#include <vcl/event.hxx> +#include <vcl/vclevent.hxx> + +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; + + +// VCLXAccessibleButton + + +void VCLXAccessibleButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::PushbuttonToggle: + { + Any aOldValue; + Any aNewValue; + + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( pButton && pButton->GetState() == TRISTATE_TRUE ) + aNewValue <<= AccessibleStateType::CHECKED; + else + aOldValue <<= AccessibleStateType::CHECKED; + + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + default: + VCLXAccessibleTextComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleButton::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleTextComponent::FillAccessibleStateSet( rStateSet ); + + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( !pButton ) + return; + + rStateSet |= AccessibleStateType::FOCUSABLE; + + if (pButton->isToggleButton()) + rStateSet |= AccessibleStateType::CHECKABLE; + + if ( pButton->GetState() == TRISTATE_TRUE ) + rStateSet |= AccessibleStateType::CHECKED; + + if ( pButton->IsPressed() ) + rStateSet |= AccessibleStateType::PRESSED; + + // IA2 CWS: if the button has a popup menu, it should has the state EXPANDABLE + if( pButton->GetType() == WindowType::MENUBUTTON ) + { + rStateSet |= AccessibleStateType::EXPANDABLE; + } + if( pButton->GetStyle() & WB_DEFBUTTON ) + { + rStateSet |= AccessibleStateType::DEFAULT; + } +} + + +// XServiceInfo + + +OUString VCLXAccessibleButton::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleButton"; +} + + +Sequence< OUString > VCLXAccessibleButton::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleButton" }; +} + + +// XAccessibleContext + + +OUString VCLXAccessibleButton::getAccessibleName( ) +{ + OUString aName( VCLXAccessibleTextComponent::getAccessibleName() ); + sal_Int32 nLength = aName.getLength(); + + if ( nLength >= 3 && aName.match( "...", nLength - 3 ) ) + { + if ( nLength == 3 ) + { + // it's a browse button + aName = AccResId( RID_STR_ACC_NAME_BROWSEBUTTON ); + } + else + { + // remove the three trailing dots + aName = aName.copy( 0, nLength - 3 ); + } + } + else if ( nLength >= 3 && aName.match( "<< ", 0 ) ) + { + // remove the leading symbols + aName = aName.copy( 3, nLength - 3 ); + } + else if ( nLength >= 3 && aName.match( " >>", nLength - 3 ) ) + { + // remove the trailing symbols + aName = aName.copy( 0, nLength - 3 ); + } + + return aName; +} + + +// XAccessibleAction + + +sal_Int32 VCLXAccessibleButton::getAccessibleActionCount( ) +{ + OExternalLockGuard aGuard( this ); + + return 1; +} + + +sal_Bool VCLXAccessibleButton::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( pButton ) + { + if (pButton->isToggleButton()) + { + // PushButton::Click doesn't toggle when it's a toggle button + pButton->Check(!pButton->IsChecked()); + pButton->Toggle(); + } + else + { + pButton->Click(); + } + } + + return true; +} + + +OUString VCLXAccessibleButton::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + return RID_STR_ACC_ACTION_CLICK; +} + + +Reference< XAccessibleKeyBinding > VCLXAccessibleButton::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + rtl::Reference<OAccessibleKeyBindingHelper> pKeyBindingHelper = new OAccessibleKeyBindingHelper(); + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + KeyEvent aKeyEvent = pWindow->GetActivationKey(); + vcl::KeyCode aKeyCode = aKeyEvent.GetKeyCode(); + if ( aKeyCode.GetCode() != 0 ) + { + awt::KeyStroke aKeyStroke; + aKeyStroke.Modifiers = 0; + if ( aKeyCode.IsShift() ) + aKeyStroke.Modifiers |= awt::KeyModifier::SHIFT; + if ( aKeyCode.IsMod1() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD1; + if ( aKeyCode.IsMod2() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD2; + if ( aKeyCode.IsMod3() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD3; + aKeyStroke.KeyCode = aKeyCode.GetCode(); + aKeyStroke.KeyChar = aKeyEvent.GetCharCode(); + aKeyStroke.KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() ); + pKeyBindingHelper->AddKeyBinding( aKeyStroke ); + } + } + + return pKeyBindingHelper; +} + + +// XAccessibleValue + + +Any VCLXAccessibleButton::getCurrentValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( pButton ) + aValue <<= static_cast<sal_Int32>(pButton->IsPressed()); + + return aValue; +} + + +sal_Bool VCLXAccessibleButton::setCurrentValue( const Any& aNumber ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + VclPtr< PushButton > pButton = GetAs< PushButton >(); + if ( pButton ) + { + sal_Int32 nValue = 0; + OSL_VERIFY( aNumber >>= nValue ); + + if ( nValue < 0 ) + nValue = 0; + else if ( nValue > 1 ) + nValue = 1; + + pButton->SetPressed( nValue == 1 ); + bReturn = true; + } + + return bReturn; +} + + +Any VCLXAccessibleButton::getMaximumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +Any VCLXAccessibleButton::getMinimumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(0); + + return aValue; +} + +Any VCLXAccessibleButton::getMinimumIncrement( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblecheckbox.cxx b/accessibility/source/standard/vclxaccessiblecheckbox.cxx new file mode 100644 index 0000000000..cf75db3fa7 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblecheckbox.cxx @@ -0,0 +1,331 @@ +/* -*- 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 <standard/vclxaccessiblecheckbox.hxx> + +#include <toolkit/awt/vclxwindows.hxx> +#include <helper/accresmgr.hxx> +#include <strings.hrc> + +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessiblekeybindinghelper.hxx> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +#include <vcl/toolkit/button.hxx> +#include <vcl/event.hxx> +#include <vcl/vclevent.hxx> + +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; + + +// VCLXAccessibleCheckBox + + +VCLXAccessibleCheckBox::VCLXAccessibleCheckBox( VCLXWindow* pVCLWindow ) + :ImplInheritanceHelper( pVCLWindow ) +{ + m_bChecked = IsChecked(); + m_bIndeterminate = IsIndeterminate(); +} + + +bool VCLXAccessibleCheckBox::IsChecked() const +{ + bool bChecked = false; + + VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() ); + if ( pVCLXCheckBox && pVCLXCheckBox->getState() == sal_Int16(1) ) + bChecked = true; + + return bChecked; +} + + +bool VCLXAccessibleCheckBox::IsIndeterminate() const +{ + bool bIndeterminate = false; + + VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() ); + if ( pVCLXCheckBox && pVCLXCheckBox->getState() == sal_Int16(2) ) + bIndeterminate = true; + + return bIndeterminate; +} + + +void VCLXAccessibleCheckBox::SetChecked( bool bChecked ) +{ + if ( m_bChecked != bChecked ) + { + Any aOldValue, aNewValue; + if ( m_bChecked ) + aOldValue <<= AccessibleStateType::CHECKED; + else + aNewValue <<= AccessibleStateType::CHECKED; + m_bChecked = bChecked; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + + +void VCLXAccessibleCheckBox::SetIndeterminate( bool bIndeterminate ) +{ + if ( m_bIndeterminate != bIndeterminate ) + { + Any aOldValue, aNewValue; + if ( m_bIndeterminate ) + aOldValue <<= AccessibleStateType::INDETERMINATE; + else + aNewValue <<= AccessibleStateType::INDETERMINATE; + m_bIndeterminate = bIndeterminate; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + + +void VCLXAccessibleCheckBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::CheckboxToggle: + { + SetChecked( IsChecked() ); + SetIndeterminate( IsIndeterminate() ); + } + break; + default: + VCLXAccessibleTextComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleCheckBox::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleTextComponent::FillAccessibleStateSet( rStateSet ); + + rStateSet |= AccessibleStateType::CHECKABLE; + rStateSet |= AccessibleStateType::FOCUSABLE; + + if ( IsChecked() ) + rStateSet |= AccessibleStateType::CHECKED; + + if ( IsIndeterminate() ) + rStateSet |= AccessibleStateType::INDETERMINATE; +} + + +// XServiceInfo + + +OUString VCLXAccessibleCheckBox::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleCheckBox"; +} + + +Sequence< OUString > VCLXAccessibleCheckBox::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleCheckBox" }; +} + + +// XAccessibleAction + + +sal_Int32 VCLXAccessibleCheckBox::getAccessibleActionCount( ) +{ + OExternalLockGuard aGuard( this ); + + return 1; +} + + +sal_Bool VCLXAccessibleCheckBox::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() ); + if ( pCheckBox && pVCLXCheckBox ) + { + sal_Int32 nValueMax = sal_Int32(1); + + if ( pCheckBox->IsTriStateEnabled() ) + nValueMax = sal_Int32(2); + + sal_Int32 nValue = static_cast<sal_Int32>(pVCLXCheckBox->getState()); + + ++nValue; + + if ( nValue > nValueMax ) + nValue = 0; + + pVCLXCheckBox->setState( static_cast<sal_Int16>(nValue) ); + } + + return true; +} + + +OUString VCLXAccessibleCheckBox::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + if(IsChecked()) + return AccResId( RID_STR_ACC_ACTION_UNCHECK ); + else + return AccResId( RID_STR_ACC_ACTION_CHECK ); +} + + +Reference< XAccessibleKeyBinding > VCLXAccessibleCheckBox::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + rtl::Reference<OAccessibleKeyBindingHelper> pKeyBindingHelper = new OAccessibleKeyBindingHelper(); + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + KeyEvent aKeyEvent = pWindow->GetActivationKey(); + vcl::KeyCode aKeyCode = aKeyEvent.GetKeyCode(); + if ( aKeyCode.GetCode() != 0 ) + { + awt::KeyStroke aKeyStroke; + aKeyStroke.Modifiers = 0; + if ( aKeyCode.IsShift() ) + aKeyStroke.Modifiers |= awt::KeyModifier::SHIFT; + if ( aKeyCode.IsMod1() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD1; + if ( aKeyCode.IsMod2() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD2; + if ( aKeyCode.IsMod3() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD3; + aKeyStroke.KeyCode = aKeyCode.GetCode(); + aKeyStroke.KeyChar = aKeyEvent.GetCharCode(); + aKeyStroke.KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() ); + pKeyBindingHelper->AddKeyBinding( aKeyStroke ); + } + } + + return pKeyBindingHelper; +} + + +// XAccessibleValue + + +Any VCLXAccessibleCheckBox::getCurrentValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + + VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() ); + if ( pVCLXCheckBox ) + aValue <<= static_cast<sal_Int32>(pVCLXCheckBox->getState()); + + return aValue; +} + + +sal_Bool VCLXAccessibleCheckBox::setCurrentValue( const Any& aNumber ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() ); + if ( pVCLXCheckBox ) + { + sal_Int32 nValue = 0, nValueMin = 0, nValueMax = 0; + OSL_VERIFY( aNumber >>= nValue ); + nValueMax=implGetMaximumValue(); + + if ( nValue < nValueMin ) + nValue = nValueMin; + else if ( nValue > nValueMax ) + nValue = nValueMax; + + pVCLXCheckBox->setState( static_cast<sal_Int16>(nValue) ); + bReturn = true; + } + + return bReturn; +} + + +Any VCLXAccessibleCheckBox::getMaximumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= implGetMaximumValue(); + + return aValue; +} + +sal_Int32 VCLXAccessibleCheckBox::implGetMaximumValue( ) +{ + VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >(); + if ( pCheckBox && pCheckBox->IsTriStateEnabled() ) + return 2; + + return 1; +} + +Any VCLXAccessibleCheckBox::getMinimumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(0); + + return aValue; +} + +Any VCLXAccessibleCheckBox::getMinimumIncrement( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblecombobox.cxx b/accessibility/source/standard/vclxaccessiblecombobox.cxx new file mode 100644 index 0000000000..363c9b4c75 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblecombobox.cxx @@ -0,0 +1,55 @@ +/* -*- 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 <standard/vclxaccessiblecombobox.hxx> +#include <comphelper/sequence.hxx> +#include <vcl/window.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; + + +VCLXAccessibleComboBox::VCLXAccessibleComboBox (VCLXWindow* pVCLWindow) + : VCLXAccessibleBox (pVCLWindow, VCLXAccessibleBox::COMBOBOX, false) +{ +} + + +bool VCLXAccessibleComboBox::IsValid() const +{ + return GetWindow(); +} + +// XServiceInfo + +OUString VCLXAccessibleComboBox::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleComboBox"; +} + + +Sequence< OUString > VCLXAccessibleComboBox::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleBox::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleComboBox"}); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibledropdowncombobox.cxx b/accessibility/source/standard/vclxaccessibledropdowncombobox.cxx new file mode 100644 index 0000000000..b5de806245 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibledropdowncombobox.cxx @@ -0,0 +1,74 @@ +/* -*- 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 <standard/vclxaccessibledropdowncombobox.hxx> + +#include <comphelper/sequence.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <vcl/vclevent.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; + + +VCLXAccessibleDropDownComboBox::VCLXAccessibleDropDownComboBox (VCLXWindow* pVCLWindow) + : VCLXAccessibleBox (pVCLWindow, VCLXAccessibleBox::COMBOBOX, true) +{ +} + + +bool VCLXAccessibleDropDownComboBox::IsValid() const +{ + return GetWindow(); +} + +void VCLXAccessibleDropDownComboBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::DropdownOpen: + case VclEventId::DropdownClose: + { + break; + } + + default: + VCLXAccessibleBox::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +// XServiceInfo + +OUString VCLXAccessibleDropDownComboBox::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleDropDownComboBox"; +} + + +Sequence< OUString > VCLXAccessibleDropDownComboBox::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleBox::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleDropDownComboBox"}); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibledropdownlistbox.cxx b/accessibility/source/standard/vclxaccessibledropdownlistbox.cxx new file mode 100644 index 0000000000..f76b00a412 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibledropdownlistbox.cxx @@ -0,0 +1,52 @@ +/* -*- 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 <standard/vclxaccessibledropdownlistbox.hxx> +#include <comphelper/sequence.hxx> +#include <toolkit/awt/vclxwindow.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; + + +VCLXAccessibleDropDownListBox::VCLXAccessibleDropDownListBox (VCLXWindow* pVCLWindow) + : VCLXAccessibleBox (pVCLWindow, VCLXAccessibleBox::LISTBOX, true) +{ +} + +bool VCLXAccessibleDropDownListBox::IsValid() const +{ + return GetWindow(); +} + +// XServiceInfo +OUString VCLXAccessibleDropDownListBox::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleDropDownListBox"; +} + +Sequence< OUString > VCLXAccessibleDropDownListBox::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleBox::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleDropDownListBox"}); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibleedit.cxx b/accessibility/source/standard/vclxaccessibleedit.cxx new file mode 100644 index 0000000000..81a1a73c5c --- /dev/null +++ b/accessibility/source/standard/vclxaccessibleedit.cxx @@ -0,0 +1,609 @@ +/* -*- 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 <standard/vclxaccessibleedit.hxx> + +#include <toolkit/awt/vclxwindows.hxx> +#include <toolkit/helper/convert.hxx> + +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/accessibility/AccessibleTextType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/string.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/settings.hxx> +#include <vcl/toolkit/edit.hxx> +#include <vcl/toolkit/vclmedit.hxx> +#include <vcl/textdata.hxx> +#include <vcl/txtattr.hxx> +#include <vcl/xtextedt.hxx> +#include <sot/exchange.hxx> +#include <sot/formats.hxx> + +#include <algorithm> + +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; + + +// VCLXAccessibleEdit + + +VCLXAccessibleEdit::VCLXAccessibleEdit( VCLXWindow* pVCLWindow ) + :ImplInheritanceHelper( pVCLWindow ) +{ + m_nCaretPosition = getCaretPosition(); +} + + +void VCLXAccessibleEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::EditModify: + { + SetText( implGetText() ); + } + break; + case VclEventId::EditCaretChanged: + { + sal_Int32 nOldCaretPosition = m_nCaretPosition; + m_nCaretPosition = getCaretPosition(); + + VclPtr<vcl::Window> pWindow = GetWindow(); + if (pWindow && pWindow->HasChildPathFocus()) + { + if (m_nCaretPosition != nOldCaretPosition) + { + Any aOldValue, aNewValue; + aOldValue <<= nOldCaretPosition; + aNewValue <<= m_nCaretPosition; + NotifyAccessibleEvent( AccessibleEventId::CARET_CHANGED, aOldValue, aNewValue ); + } + } + } + break; + case VclEventId::EditSelectionChanged: + { + VclPtr<vcl::Window> pWindow = GetWindow(); + if (pWindow && pWindow->HasChildPathFocus()) + { + NotifyAccessibleEvent( AccessibleEventId::TEXT_SELECTION_CHANGED, Any(), Any() ); + } + } + break; + default: + VCLXAccessibleTextComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleEdit::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleTextComponent::FillAccessibleStateSet( rStateSet ); + + VCLXWindow* pVCLXWindow = GetVCLXWindow(); + if (pVCLXWindow) + { + rStateSet |= AccessibleStateType::FOCUSABLE; + + if (GetWindow() && GetWindow()->GetType() == WindowType::MULTILINEEDIT) + rStateSet |= AccessibleStateType::MULTI_LINE; + else + rStateSet |= AccessibleStateType::SINGLE_LINE; + + if (isEditable()) + rStateSet |= AccessibleStateType::EDITABLE; + } +} + + +// OCommonAccessibleText + + +OUString VCLXAccessibleEdit::implGetText() +{ + OUString aText; + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit ) + { + aText = removeMnemonicFromString( pEdit->GetText() ); + + if ( implGetAccessibleRole() == AccessibleRole::PASSWORD_TEXT ) + { + sal_Unicode cEchoChar = pEdit->GetEchoChar(); + if ( !cEchoChar ) + cEchoChar = '*'; + OUStringBuffer sTmp(aText.getLength()); + aText = comphelper::string::padToLength(sTmp, aText.getLength(), + cEchoChar).makeStringAndClear(); + } + } + + return aText; +} + + +void VCLXAccessibleEdit::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + Selection aSelection; + VclPtr<Edit> pEdit = GetAs<Edit>(); + if (pEdit) + aSelection = pEdit->GetSelection(); + + nStartIndex = aSelection.Min(); + nEndIndex = aSelection.Max(); +} + + +// XServiceInfo + + +OUString VCLXAccessibleEdit::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleEdit"; +} + + +Sequence< OUString > VCLXAccessibleEdit::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleEdit" }; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleEdit::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +Reference< XAccessible > VCLXAccessibleEdit::getAccessibleChild( sal_Int64 ) +{ + throw IndexOutOfBoundsException(); +} + + +sal_Int16 VCLXAccessibleEdit::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return implGetAccessibleRole(); +} + +sal_Int16 VCLXAccessibleEdit::implGetAccessibleRole( ) +{ + sal_Int16 nRole; + VclPtr< Edit > pEdit = GetAs< Edit >(); + if ( pEdit && ( pEdit->IsPassword() || pEdit->GetEchoChar() ) ) + nRole = AccessibleRole::PASSWORD_TEXT; + else if ( pEdit && ( pEdit->GetStyle() & WB_READONLY ) ) + nRole = AccessibleRole::STATIC; + else + nRole = AccessibleRole::TEXT; + + return nRole; +} + + +// XAccessibleAction + + +sal_Int32 VCLXAccessibleEdit::getAccessibleActionCount( ) +{ + OExternalLockGuard aGuard( this ); + + // There is one action: activate + return 1; +} + + +sal_Bool VCLXAccessibleEdit::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + bool bDoAction = false; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + pWindow->GrabFocus(); + bDoAction = true; + } + + return bDoAction; +} + + +OUString VCLXAccessibleEdit::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0) + throw IndexOutOfBoundsException(); + + return "activate"; +} + + +Reference< XAccessibleKeyBinding > VCLXAccessibleEdit::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + return Reference< XAccessibleKeyBinding >(); +} + + +// XAccessibleText + + +sal_Int32 VCLXAccessibleEdit::getCaretPosition( ) +{ + return getSelectionEnd(); +} + + +sal_Bool VCLXAccessibleEdit::setCaretPosition( sal_Int32 nIndex ) +{ + return setSelection( nIndex, nIndex ); +} + + +sal_Unicode VCLXAccessibleEdit::getCharacter( sal_Int32 nIndex ) +{ + return VCLXAccessibleTextComponent::getCharacter( nIndex ); +} + + +Sequence< PropertyValue > VCLXAccessibleEdit::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& aRequestedAttributes ) +{ + OExternalLockGuard aGuard( this ); + Sequence< PropertyValue > aProperties = VCLXAccessibleTextComponent::getCharacterAttributes( nIndex, aRequestedAttributes ); + auto aNonConstRange = asNonConstRange(aProperties); + + // Handle multiline edit character properties + VclPtr<VclMultiLineEdit> pMulitLineEdit = GetAsDynamic< VclMultiLineEdit >(); + if ( pMulitLineEdit ) + { + ExtTextEngine* pTextEngine = pMulitLineEdit->GetTextEngine(); + TextPaM aCursor( 0, nIndex ); + const TextAttribFontColor* pFontColor = static_cast<const TextAttribFontColor* >(pTextEngine->FindAttrib( aCursor, TEXTATTR_FONTCOLOR )); + if ( pFontColor ) + { + for (PropertyValue& aValue : aNonConstRange ) + { + if (aValue.Name == "CharColor") + { + aValue.Value <<= pFontColor->GetColor().GetRGBColor(); + break; + } + } + } + } + + // Set default character color if it is not set yet to a valid value + for (PropertyValue& aValue : aNonConstRange ) + { + if (aValue.Name == "CharColor") + { + if ( aValue.Value == sal_Int32(-1) ) + { + OutputDevice* pDev = Application::GetDefaultDevice(); + if ( pDev ) + { + aValue.Value <<= pDev->GetSettings().GetStyleSettings().GetFieldTextColor(); + } + } + break; + } + } + + return aProperties; +} + + +awt::Rectangle VCLXAccessibleEdit::getCharacterBounds( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + sal_Int32 nLength = implGetText().getLength(); + + if ( !implIsValidRange( nIndex, nIndex, nLength ) ) + throw IndexOutOfBoundsException(); + + VclPtr< Control > pControl = GetAs< Control >(); + if ( pControl ) + { + if ( nIndex == nLength ) + { + // #108914# calculate virtual bounding rectangle + for ( sal_Int32 i = 0; i < nLength; ++i ) + { + tools::Rectangle aRect = pControl->GetCharacterBounds( i ); + sal_Int32 nHeight = aRect.GetHeight(); + if ( aBounds.Height < nHeight ) + { + aBounds.Y = aRect.Top(); + aBounds.Height = nHeight; + } + if ( i == nLength - 1 ) + { + aBounds.X = aRect.Right() + 1; + aBounds.Width = 1; + } + } + } + else + { + aBounds = AWTRectangle( pControl->GetCharacterBounds( nIndex ) ); + } + } + + return aBounds; +} + + +sal_Int32 VCLXAccessibleEdit::getCharacterCount( ) +{ + return VCLXAccessibleTextComponent::getCharacterCount(); +} + + +sal_Int32 VCLXAccessibleEdit::getIndexAtPoint( const awt::Point& aPoint ) +{ + return VCLXAccessibleTextComponent::getIndexAtPoint( aPoint ); +} + + +OUString VCLXAccessibleEdit::getSelectedText( ) +{ + return VCLXAccessibleTextComponent::getSelectedText(); +} + + +sal_Int32 VCLXAccessibleEdit::getSelectionStart( ) +{ + return VCLXAccessibleTextComponent::getSelectionStart(); +} + + +sal_Int32 VCLXAccessibleEdit::getSelectionEnd( ) +{ + return VCLXAccessibleTextComponent::getSelectionEnd(); +} + + +sal_Bool VCLXAccessibleEdit::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + OUString sText( implGetText() ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + VclPtr< Edit > pEdit = GetAs< Edit >(); + if (pEdit && pEdit->IsEnabled()) + { + pEdit->SetSelection(Selection(nStartIndex, nEndIndex)); + bReturn = true; + } + + return bReturn; +} + + +OUString VCLXAccessibleEdit::getText( ) +{ + return VCLXAccessibleTextComponent::getText(); +} + + +OUString VCLXAccessibleEdit::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + return VCLXAccessibleTextComponent::getTextRange( nStartIndex, nEndIndex ); +} + + +css::accessibility::TextSegment VCLXAccessibleEdit::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + // Override general text component behavior: MultiLineEdit can have more text portions + if ( aTextType == AccessibleTextType::ATTRIBUTE_RUN ) + { + VclPtr<VclMultiLineEdit> pMulitLineEdit = GetAsDynamic< VclMultiLineEdit >(); + if ( pMulitLineEdit ) + { + ExtTextEngine* pTextEngine = pMulitLineEdit->GetTextEngine(); + TextPaM aCursor( 0, nIndex ); + TextSegment aResult; + pTextEngine->GetTextPortionRange( aCursor, aResult.SegmentStart, aResult.SegmentEnd ); + return aResult; + } + } + + return VCLXAccessibleTextComponent::getTextAtIndex( nIndex, aTextType ); +} + + +css::accessibility::TextSegment VCLXAccessibleEdit::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + return VCLXAccessibleTextComponent::getTextBeforeIndex( nIndex, aTextType ); +} + + +css::accessibility::TextSegment VCLXAccessibleEdit::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + return VCLXAccessibleTextComponent::getTextBehindIndex( nIndex, aTextType ); +} + + +sal_Bool VCLXAccessibleEdit::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + return VCLXAccessibleTextComponent::copyText( nStartIndex, nEndIndex ); +} + +sal_Bool VCLXAccessibleEdit::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + +// XAccessibleEditableText + + +sal_Bool VCLXAccessibleEdit::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + return copyText( nStartIndex, nEndIndex ) && deleteText( nStartIndex, nEndIndex ); +} + + +sal_Bool VCLXAccessibleEdit::pasteText( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + if ( GetWindow() ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow()->GetClipboard(); + if ( xClipboard.is() ) + { + Reference< datatransfer::XTransferable > xDataObj; + { + SolarMutexReleaser aReleaser; + xDataObj = xClipboard->getContents(); + } + if ( xDataObj.is() ) + { + datatransfer::DataFlavor aFlavor; + SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor ); + if ( xDataObj->isDataFlavorSupported( aFlavor ) ) + { + Any aData = xDataObj->getTransferData( aFlavor ); + OUString sText; + aData >>= sText; + bReturn = replaceText( nIndex, nIndex, sText ); + } + } + } + } + + return bReturn; +} + + +sal_Bool VCLXAccessibleEdit::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + return replaceText( nStartIndex, nEndIndex, OUString() ); +} + + +sal_Bool VCLXAccessibleEdit::insertText( const OUString& sText, sal_Int32 nIndex ) +{ + return replaceText( nIndex, nIndex, sText ); +} + + +sal_Bool VCLXAccessibleEdit::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString& sReplacement ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + OUString sText( implGetText() ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + sal_Int32 nMinIndex = std::min( nStartIndex, nEndIndex ); + sal_Int32 nMaxIndex = std::max( nStartIndex, nEndIndex ); + + + if (isEditable()) + { + VclPtr<Edit> pEdit = GetAs<Edit>(); + assert(pEdit); + pEdit->SetText(sText.replaceAt(nMinIndex, nMaxIndex - nMinIndex, sReplacement)); + sal_Int32 nIndex = nMinIndex + sReplacement.getLength(); + setSelection( nIndex, nIndex ); + bReturn = true; + } + + return bReturn; +} + + +sal_Bool VCLXAccessibleEdit::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const Sequence<PropertyValue>& ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; // attributes cannot be set for an edit +} + + +sal_Bool VCLXAccessibleEdit::setText( const OUString& sText ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + if (isEditable()) + { + VclPtr<Edit> pEdit = GetAs<Edit>(); + assert(pEdit); + pEdit->SetText(sText); + sal_Int32 nSize = sText.getLength(); + pEdit->SetSelection(Selection(nSize, nSize) ); + bReturn = true; + } + + return bReturn; +} + +bool VCLXAccessibleEdit::isEditable() +{ + VclPtr<Edit> pEdit = GetAs<Edit>(); + return pEdit && !pEdit->IsReadOnly() && pEdit->IsEnabled(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblefixedhyperlink.cxx b/accessibility/source/standard/vclxaccessiblefixedhyperlink.cxx new file mode 100644 index 0000000000..9e28743652 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblefixedhyperlink.cxx @@ -0,0 +1,38 @@ +/* -*- 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 <standard/vclxaccessiblefixedhyperlink.hxx> + +using namespace ::com::sun::star; + +// VCLXAccessibleFixedHyperlink + +// XServiceInfo + +OUString VCLXAccessibleFixedHyperlink::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleFixedHyperlink"; +} + +uno::Sequence<OUString> VCLXAccessibleFixedHyperlink::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleFixedHyperlink" }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblefixedtext.cxx b/accessibility/source/standard/vclxaccessiblefixedtext.cxx new file mode 100644 index 0000000000..56105c5d1c --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblefixedtext.cxx @@ -0,0 +1,53 @@ +/* -*- 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 <standard/vclxaccessiblefixedtext.hxx> + +#include <vcl/window.hxx> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> + +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; + +// VCLXAccessibleFixedText + +void VCLXAccessibleFixedText::FillAccessibleStateSet(sal_Int64& rStateSet) +{ + VCLXAccessibleTextComponent::FillAccessibleStateSet(rStateSet); + + if (GetWindow() && GetWindow()->GetStyle() & WB_WORDBREAK) + rStateSet |= AccessibleStateType::MULTI_LINE; +} + +// XServiceInfo + +OUString VCLXAccessibleFixedText::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleFixedText"; +} + +Sequence<OUString> VCLXAccessibleFixedText::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleFixedText" }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibleheaderbar.cxx b/accessibility/source/standard/vclxaccessibleheaderbar.cxx new file mode 100644 index 0000000000..23d2db4be3 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibleheaderbar.cxx @@ -0,0 +1,130 @@ +/* -*- 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 <standard/vclxaccessibleheaderbar.hxx> +#include <standard/vclxaccessibleheaderbaritem.hxx> + +#include <o3tl/safeint.hxx> +#include <vcl/headbar.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + +VCLXAccessibleHeaderBar::VCLXAccessibleHeaderBar(VCLXWindow* pVCLWindow) + : VCLXAccessibleComponent(pVCLWindow) +{ + m_pHeadBar = GetAs<HeaderBar>(); +} + +VCLXAccessibleHeaderBar::~VCLXAccessibleHeaderBar() {} + +// XServiceInfo + +OUString VCLXAccessibleHeaderBar::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleHeaderBar"; +} + +Sequence<OUString> VCLXAccessibleHeaderBar::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleHeaderBar" }; +} + +// =======XAccessibleContext======= + +sal_Int64 SAL_CALL VCLXAccessibleHeaderBar::getAccessibleChildCount() +{ + SolarMutexGuard g; + + sal_Int64 nCount = 0; + if (m_pHeadBar) + nCount = m_pHeadBar->GetItemCount(); + + return nCount; +} +css::uno::Reference<css::accessibility::XAccessible> + SAL_CALL VCLXAccessibleHeaderBar::getAccessibleChild(sal_Int64 i) +{ + SolarMutexGuard g; + + if (i < 0 || i >= getAccessibleChildCount()) + throw IndexOutOfBoundsException(); + + Reference<XAccessible> xChild; + // search for the child + if (o3tl::make_unsigned(i) >= m_aAccessibleChildren.size()) + xChild = CreateChild(i); + else + { + xChild = m_aAccessibleChildren[i]; + if (!xChild.is()) + xChild = CreateChild(i); + } + return xChild; +} + +sal_Int16 SAL_CALL VCLXAccessibleHeaderBar::getAccessibleRole() +{ + return css::accessibility::AccessibleRole::LIST; +} + +void SAL_CALL VCLXAccessibleHeaderBar::disposing() +{ + SolarMutexGuard g; + + ListItems().swap(m_aAccessibleChildren); + VCLXAccessibleComponent::disposing(); +} + +css::uno::Reference<css::accessibility::XAccessible> +VCLXAccessibleHeaderBar::CreateChild(sal_Int32 i) +{ + Reference<XAccessible> xChild; + + sal_uInt16 nPos = static_cast<sal_uInt16>(i); + if (nPos >= m_aAccessibleChildren.size()) + { + m_aAccessibleChildren.resize(nPos + 1); + + // insert into the container + xChild = new VCLXAccessibleHeaderBarItem(m_pHeadBar, i); + m_aAccessibleChildren[nPos] = xChild; + } + else + { + xChild = m_aAccessibleChildren[nPos]; + // check if position is empty and can be used else we have to adjust all entries behind this + if (!xChild.is()) + { + xChild = new VCLXAccessibleHeaderBarItem(m_pHeadBar, i); + m_aAccessibleChildren[nPos] = xChild; + } + } + return xChild; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibleheaderbaritem.cxx b/accessibility/source/standard/vclxaccessibleheaderbaritem.cxx new file mode 100644 index 0000000000..d3463f5cda --- /dev/null +++ b/accessibility/source/standard/vclxaccessibleheaderbaritem.cxx @@ -0,0 +1,253 @@ +/* -*- 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 <standard/vclxaccessibleheaderbaritem.hxx> + +#include <vcl/headbar.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <toolkit/helper/convert.hxx> +#include <i18nlangtag/languagetag.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + + + +VCLXAccessibleHeaderBarItem::VCLXAccessibleHeaderBarItem( HeaderBar* pHeadBar, sal_Int32 _nIndexInParent ) + :m_pHeadBar( pHeadBar ) + ,m_nIndexInParent(_nIndexInParent + 1) + +{ +} + +VCLXAccessibleHeaderBarItem::~VCLXAccessibleHeaderBarItem() +{ +} + +void VCLXAccessibleHeaderBarItem::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + if ( m_pHeadBar ) + { + if ( m_pHeadBar->IsEnabled() ) + rStateSet |= AccessibleStateType::ENABLED; + + if ( m_pHeadBar->IsVisible() ) + { + rStateSet |= AccessibleStateType::VISIBLE; + } + rStateSet |= AccessibleStateType::SELECTABLE; + rStateSet |= AccessibleStateType::RESIZABLE; + } +} + +// OCommonAccessibleComponent +awt::Rectangle VCLXAccessibleHeaderBarItem::implGetBounds() +{ + awt::Rectangle aBounds; + OExternalLockGuard aGuard( this ); + + if ( m_pHeadBar ) + aBounds = AWTRectangle( m_pHeadBar->GetItemRect( sal_uInt16( m_nIndexInParent ) ) ); + + return aBounds; +} + + +// XServiceInfo +OUString VCLXAccessibleHeaderBarItem::getImplementationName() +{ + return "com.sun.star.comp.svtools.AccessibleHeaderBarItem"; +} + +sal_Bool VCLXAccessibleHeaderBarItem::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService( this, rServiceName ); +} + +Sequence< OUString > VCLXAccessibleHeaderBarItem::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleHeaderBarItem" }; +} + +// XAccessible +Reference< XAccessibleContext > VCLXAccessibleHeaderBarItem::getAccessibleContext() +{ + return this; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleHeaderBarItem::getAccessibleChildCount() +{ + return 0; +} + + +Reference< XAccessible > VCLXAccessibleHeaderBarItem::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + return Reference< XAccessible >(); +} + + +Reference< XAccessible > VCLXAccessibleHeaderBarItem::getAccessibleParent() +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pHeadBar ) + { + xParent = m_pHeadBar->GetAccessible(); + } + + return xParent; +} + + +sal_Int64 VCLXAccessibleHeaderBarItem::getAccessibleIndexInParent() +{ + OExternalLockGuard aGuard( this ); + return m_nIndexInParent - 1; +} + + +sal_Int16 VCLXAccessibleHeaderBarItem::getAccessibleRole() +{ + return AccessibleRole::COLUMN_HEADER; +} + + +OUString VCLXAccessibleHeaderBarItem::getAccessibleDescription() +{ + return OUString(); +} + + +OUString VCLXAccessibleHeaderBarItem::getAccessibleName() +{ + OExternalLockGuard aGuard( this ); + + OUString sName; + if(m_pHeadBar) + sName = m_pHeadBar->GetItemText( sal_uInt16( m_nIndexInParent ) ); + return sName; +} + + +Reference< XAccessibleRelationSet > VCLXAccessibleHeaderBarItem::getAccessibleRelationSet( ) +{ + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; +} + + +sal_Int64 VCLXAccessibleHeaderBarItem::getAccessibleStateSet( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; +} + + +css::lang::Locale VCLXAccessibleHeaderBarItem::getLocale() +{ + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +// XAccessibleComponent + + +Reference< XAccessible > VCLXAccessibleHeaderBarItem::getAccessibleAtPoint( const awt::Point& ) +{ + return Reference< XAccessible >(); +} + + +sal_Int32 VCLXAccessibleHeaderBarItem::getForeground() +{ + return 0; +} + + +sal_Int32 VCLXAccessibleHeaderBarItem::getBackground() +{ + return 0; +} + + +// XAccessibleExtendedComponent + + +Reference< awt::XFont > VCLXAccessibleHeaderBarItem::getFont() +{ + return Reference< awt::XFont >(); +} + + +OUString VCLXAccessibleHeaderBarItem::getTitledBorderText() +{ + return OUString(); +} + + +OUString VCLXAccessibleHeaderBarItem::getToolTipText() +{ + OExternalLockGuard aGuard( this ); + + OUString sText; + if ( m_pHeadBar ) + sText = m_pHeadBar->GetQuickHelpText(); + + return sText; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblelist.cxx b/accessibility/source/standard/vclxaccessiblelist.cxx new file mode 100644 index 0000000000..36573dcbb3 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblelist.cxx @@ -0,0 +1,951 @@ +/* -*- 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 <standard/vclxaccessiblelist.hxx> +#include <standard/vclxaccessiblelistitem.hxx> +#include <helper/listboxhelper.hxx> + +#include <unotools/accessiblerelationsethelper.hxx> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <o3tl/safeint.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolkit/combobox.hxx> +#include <vcl/toolkit/lstbox.hxx> +#include <toolkit/helper/convert.hxx> + +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 ::accessibility; + +namespace +{ + /// @throws css::lang::IndexOutOfBoundsException + void checkSelection_Impl( sal_Int64 _nIndex, const IComboListBoxHelper& _rListBox, bool bSelected ) + { + sal_Int32 nCount = bSelected ? _rListBox.GetSelectedEntryCount() + : _rListBox.GetEntryCount(); + if ( _nIndex < 0 || _nIndex >= nCount ) + throw css::lang::IndexOutOfBoundsException(); + } +} + +VCLXAccessibleList::VCLXAccessibleList (VCLXWindow* pVCLWindow, BoxType aBoxType, + const Reference< XAccessible >& _xParent) + : ImplInheritanceHelper (pVCLWindow), + m_aBoxType (aBoxType), + m_nVisibleLineCount (0), + m_nIndexInParent (DEFAULT_INDEX_IN_PARENT), + m_nLastTopEntry ( 0 ), + m_nLastSelectedPos ( LISTBOX_ENTRY_NOTFOUND ), + m_bDisableProcessEvent ( false ), + m_bVisible ( true ), + m_nCurSelectedPos ( LISTBOX_ENTRY_NOTFOUND ), + m_xParent ( _xParent ) +{ + // Because combo boxes and list boxes don't have a common interface for + // methods with identical signature we have to write down twice the + // same code. + switch (m_aBoxType) + { + case COMBOBOX: + { + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + m_pListBoxHelper.reset( new VCLListBoxHelper<ComboBox> (*pBox) ); + break; + } + + case LISTBOX: + { + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if ( pBox ) + m_pListBoxHelper.reset( new VCLListBoxHelper<ListBox> (*pBox) ); + break; + } + } + UpdateVisibleLineCount(); + if(m_pListBoxHelper) + { + m_nCurSelectedPos=m_pListBoxHelper->GetSelectedEntryPos(0); + } + sal_uInt16 nCount = static_cast<sal_uInt16>(getAccessibleChildCount()); + m_aAccessibleChildren.reserve(nCount); +} + + +void VCLXAccessibleList::SetIndexInParent (sal_Int32 nIndex) +{ + m_nIndexInParent = nIndex; +} + + +void SAL_CALL VCLXAccessibleList::disposing() +{ + VCLXAccessibleComponent::disposing(); + + // Dispose all items in the list. + for (rtl::Reference<VCLXAccessibleListItem>& rxChild : m_aAccessibleChildren) + { + if (rxChild.is()) + rxChild->dispose(); + } + + m_aAccessibleChildren.clear(); + + m_pListBoxHelper.reset(); +} + + +void VCLXAccessibleList::FillAccessibleStateSet (sal_Int64& rStateSet) +{ + SolarMutexGuard aSolarGuard; + + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + // check if our list should be visible + if ( m_pListBoxHelper + && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN + && !m_pListBoxHelper->IsInDropDown() ) + { + rStateSet &= ~AccessibleStateType::VISIBLE; + rStateSet &= ~AccessibleStateType::SHOWING; + m_bVisible = false; + } + + // Both the combo box and list box are handled identical in the + // following but for some reason they don't have a common interface for + // the methods used. + if ( m_pListBoxHelper ) + { + if ( m_pListBoxHelper->IsMultiSelectionEnabled() ) + rStateSet |= AccessibleStateType::MULTI_SELECTABLE; + rStateSet |= AccessibleStateType::FOCUSABLE; + // All children are transient. + rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS; + } +} + +void VCLXAccessibleList::notifyVisibleStates(bool _bSetNew ) +{ + m_bVisible = _bSetNew; + Any aOldValue, aNewValue; + (_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::VISIBLE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + (_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + + auto aIter = m_aAccessibleChildren.begin(); + UpdateVisibleLineCount(); + // adjust the index inside the VCLXAccessibleListItem + for ( ; aIter != m_aAccessibleChildren.end(); ) + { + rtl::Reference<VCLXAccessibleListItem> xChild = *aIter; + if (!xChild.is()) + { + aIter = m_aAccessibleChildren.erase(aIter); + } + else + { + const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0; + const sal_Int32 nPos = static_cast<sal_Int32>(aIter - m_aAccessibleChildren.begin()); + bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) ); + xChild->SetVisible(m_bVisible && bVisible); + ++aIter; + } + + } +} + +void VCLXAccessibleList::UpdateSelection_Acc (std::u16string_view /*sTextOfSelectedItem*/, bool b_IsDropDownList) +{ + if ( m_aBoxType != COMBOBOX ) + return; + + /* FIXME: is there something missing here? nIndex is unused. Looks like + * copy-paste from VCLXAccessibleList::UpdateSelection() */ + // VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + // if ( pBox ) + // { + // // Find the index of the selected item inside the VCL control... + // sal_Int32 nIndex = pBox->GetEntryPos(sTextOfSelectedItem); + // // ...and then find the associated accessibility object. + // if ( nIndex == LISTBOX_ENTRY_NOTFOUND ) + // nIndex = 0; + UpdateSelection_Impl_Acc(b_IsDropDownList); + // } +} + + +void VCLXAccessibleList::UpdateSelection_Impl_Acc(bool bHasDropDownList) +{ + uno::Any aOldValue, aNewValue; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + Reference< XAccessible > xNewAcc; + if ( m_pListBoxHelper ) + { + sal_Int32 i=0; + m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND; + for (const rtl::Reference<VCLXAccessibleListItem>& rxChild : m_aAccessibleChildren) + { + if (rxChild.is()) + { + // Retrieve the item's index from the list entry. + bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i); + if (bNowSelected) + m_nCurSelectedPos = i; + + if (bNowSelected && !rxChild->IsSelected()) + { + xNewAcc = rxChild; + aNewValue <<= xNewAcc; + } + else if (rxChild->IsSelected()) + m_nLastSelectedPos = i; + + rxChild->SetSelected(bNowSelected); + } + else + { // it could happen that a child was not created before + checkEntrySelected(i,aNewValue,xNewAcc); + } + ++i; + } + const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount(); + if ( i < nCount ) // here we have to check the if any other listbox entry is selected + { + for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i ) + ; + } + if ( xNewAcc.is() && GetWindow()->HasFocus() ) + { + if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND ) + aOldValue <<= getAccessibleChild( m_nLastSelectedPos ); + aNewValue <<= xNewAcc; + } + } + } + + // since an active descendant is the UI element with keyboard focus, only send + // ACTIVE_DESCENDANT_CHANGED if the listbox/combobox has focus + vcl::Window* pWindow = GetWindow(); + assert(pWindow); + const bool bFocused = pWindow->HasChildPathFocus(); + + if (m_aBoxType == COMBOBOX) + { + //VCLXAccessibleDropDownComboBox + //when in list is dropped down, xText = NULL + if (bHasDropDownList && m_pListBoxHelper && m_pListBoxHelper->IsInDropDown()) + { + if ( aNewValue.hasValue() || aOldValue.hasValue() ) + { + if (bFocused) + { + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + } + + NotifyListItem(aNewValue); + } + } + else + { + //VCLXAccessibleComboBox + NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, uno::Any(), uno::Any() ); + } + } + else if (m_aBoxType == LISTBOX) + { + if ( aNewValue.hasValue() || aOldValue.hasValue() ) + { + if (bFocused) + { + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + } + + NotifyListItem(aNewValue); + } + } +} + +void VCLXAccessibleList::NotifyListItem(css::uno::Any const & val) +{ + Reference< XAccessible > xCurItem; + val >>= xCurItem; + if (xCurItem.is()) + { + VCLXAccessibleListItem* pCurItem = static_cast< VCLXAccessibleListItem* >(xCurItem.get()); + if (pCurItem) + { + pCurItem->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED,Any(),Any()); + } + } +} + +void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent, bool b_IsDropDownList) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::DropdownSelect: + case VclEventId::ListboxSelect: + if ( !m_bDisableProcessEvent ) + UpdateSelection_Impl_Acc(b_IsDropDownList); + break; + case VclEventId::WindowGetFocus: + break; + case VclEventId::ControlGetFocus: + { + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + if (m_aBoxType == COMBOBOX && b_IsDropDownList) + { + //VCLXAccessibleDropDownComboBox + } + else if (m_aBoxType == LISTBOX && b_IsDropDownList) + { + } + else if ( m_aBoxType == LISTBOX && !b_IsDropDownList) + { + if ( m_pListBoxHelper ) + { + uno::Any aOldValue, + aNewValue; + sal_Int32 nPos = m_nCurSelectedPos; //m_pListBoxHelper->GetSelectedEntryPos(); + + if ( nPos == LISTBOX_ENTRY_NOTFOUND ) + nPos = m_pListBoxHelper->GetTopEntry(); + if ( nPos != LISTBOX_ENTRY_NOTFOUND ) + aNewValue <<= uno::Reference<XAccessible>(CreateChild(nPos)); + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + } + } + } + break; + default: + break; + } + +} + +void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) +{ + // Create a reference to this object to prevent an early release of the + // listbox (VclEventId::ObjectDying). + Reference< XAccessible > xHoldAlive = this; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::DropdownOpen: + notifyVisibleStates(true); + break; + case VclEventId::DropdownClose: + notifyVisibleStates(false); + break; + case VclEventId::ListboxScrolled: + UpdateEntryRange_Impl(); + break; + + // The selection events VclEventId::ComboboxSelect and + // VclEventId::ComboboxDeselect are not handled here because here we + // have no access to the edit field. Its text is necessary to + // identify the currently selected item. + + case VclEventId::ObjectDying: + { + dispose(); + + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + break; + } + + case VclEventId::ListboxItemRemoved: + case VclEventId::ComboboxItemRemoved: + case VclEventId::ListboxItemAdded: + case VclEventId::ComboboxItemAdded: + HandleChangedItemList(); + break; + case VclEventId::ControlGetFocus: + { + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + // Added by IBM Symphony Acc team to handle the list item focus when List control get focus + bool b_IsDropDownList = true; + if (m_pListBoxHelper) + b_IsDropDownList = ((m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN); + if ( m_aBoxType == LISTBOX && !b_IsDropDownList ) + { + if ( m_pListBoxHelper ) + { + uno::Any aOldValue, + aNewValue; + sal_Int32 nPos = m_nCurSelectedPos; + + if ( nPos == LISTBOX_ENTRY_NOTFOUND ) + nPos = m_pListBoxHelper->GetTopEntry(); + if ( nPos != LISTBOX_ENTRY_NOTFOUND ) + aNewValue <<= Reference<XAccessible>(CreateChild(nPos)); + NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + } + } + } + break; + + default: + VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); + } +} + + void VCLXAccessibleList::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) +{ + VclPtr< ListBox > pBox = GetAs< ListBox >(); + if( m_aBoxType == LISTBOX ) + { + if (m_pListBoxHelper && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) != WB_DROPDOWN) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pBox->GetAccessible() }; + rRelationSet.AddRelation( com::sun::star::accessibility::AccessibleRelation( com::sun::star::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); + } + } + else + { + VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet); + } +} + + +/** To find out which item is currently selected and to update the SELECTED + state of the associated accessibility objects accordingly we exploit the + fact that the +*/ +void VCLXAccessibleList::UpdateSelection (std::u16string_view sTextOfSelectedItem) +{ + if ( m_aBoxType != COMBOBOX ) + return; + + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + { + // Find the index of the selected item inside the VCL control... + sal_Int32 nIndex = pBox->GetEntryPos(sTextOfSelectedItem); + // ...and then find the associated accessibility object. + if ( nIndex == LISTBOX_ENTRY_NOTFOUND ) + nIndex = 0; + UpdateSelection_Impl(nIndex); + } +} + + +rtl::Reference<VCLXAccessibleListItem> VCLXAccessibleList::CreateChild(sal_Int32 nPos) +{ + rtl::Reference<VCLXAccessibleListItem> xChild; + + if ( o3tl::make_unsigned(nPos) >= m_aAccessibleChildren.size() ) + { + m_aAccessibleChildren.resize(nPos + 1); + + // insert into the container + xChild = new VCLXAccessibleListItem(nPos, this); + m_aAccessibleChildren[nPos] = xChild; + } + else + { + xChild = m_aAccessibleChildren[nPos]; + // check if position is empty and can be used else we have to adjust all entries behind this + if (!xChild.is()) + { + xChild = new VCLXAccessibleListItem(nPos, this); + m_aAccessibleChildren[nPos] = xChild; + } + } + + if ( xChild.is() ) + { + // Just add the SELECTED state. + bool bNowSelected = false; + if ( m_pListBoxHelper ) + bNowSelected = m_pListBoxHelper->IsEntryPosSelected(nPos); + if (bNowSelected) + m_nCurSelectedPos = nPos; + xChild->SetSelected(bNowSelected); + + // Set the child's VISIBLE state. + UpdateVisibleLineCount(); + const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0; + bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) ); + xChild->SetVisible(m_bVisible && bVisible); + } + + return xChild; +} + + +void VCLXAccessibleList::HandleChangedItemList() +{ + m_aAccessibleChildren.clear(); + NotifyAccessibleEvent ( + AccessibleEventId::INVALIDATE_ALL_CHILDREN, + Any(), Any()); +} + +// XAccessible + +Reference<XAccessibleContext> SAL_CALL + VCLXAccessibleList::getAccessibleContext() +{ + return this; +} + + +// XAccessibleContext + +sal_Int64 SAL_CALL VCLXAccessibleList::getAccessibleChildCount() +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return implGetAccessibleChildCount(); +} + +sal_Int64 VCLXAccessibleList::implGetAccessibleChildCount() +{ + sal_Int32 nCount = 0; + if ( m_pListBoxHelper ) + nCount = m_pListBoxHelper->GetEntryCount(); + + return nCount; +} + +Reference<XAccessible> SAL_CALL VCLXAccessibleList::getAccessibleChild (sal_Int64 i) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if ( i < 0 || i >= getAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + // search for the child + if ( o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + xChild = CreateChild (i); + else + { + xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + xChild = CreateChild (i); + } + OSL_ENSURE( xChild.is(), "VCLXAccessibleList::getAccessibleChild: returning empty child!" ); + return xChild; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleList::getAccessibleParent( ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return m_xParent; +} + +sal_Int64 SAL_CALL VCLXAccessibleList::getAccessibleIndexInParent() +{ + if (m_nIndexInParent != DEFAULT_INDEX_IN_PARENT) + return m_nIndexInParent; + else + return VCLXAccessibleComponent::getAccessibleIndexInParent(); +} + +sal_Int16 SAL_CALL VCLXAccessibleList::getAccessibleRole() +{ + return AccessibleRole::LIST; +} + +// XServiceInfo +OUString VCLXAccessibleList::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleList"; +} + +Sequence< OUString > VCLXAccessibleList::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleList"}); +} + +void VCLXAccessibleList::UpdateVisibleLineCount() +{ + if ( m_pListBoxHelper ) + { + if ( (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN ) + m_nVisibleLineCount = m_pListBoxHelper->GetDisplayLineCount(); + else + { + sal_uInt16 nCols = 0, + nLines = 0; + m_pListBoxHelper->GetMaxVisColumnsAndLines (nCols, nLines); + m_nVisibleLineCount = nLines; + } + } +} + +void VCLXAccessibleList::UpdateEntryRange_Impl() +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_Int32 nTop = m_nLastTopEntry; + + if ( m_pListBoxHelper ) + nTop = m_pListBoxHelper->GetTopEntry(); + if ( nTop != m_nLastTopEntry ) + { + UpdateVisibleLineCount(); + sal_Int32 nBegin = std::min( m_nLastTopEntry, nTop ); + sal_Int32 nEnd = std::max( m_nLastTopEntry + m_nVisibleLineCount, nTop + m_nVisibleLineCount ); + for (sal_Int32 i = nBegin; (i <= nEnd); ++i) + { + bool bVisible = ( i >= nTop && i < ( nTop + m_nVisibleLineCount ) ); + rtl::Reference<VCLXAccessibleListItem> xChild; + if ( o3tl::make_unsigned(i) < m_aAccessibleChildren.size() ) + xChild = m_aAccessibleChildren[i]; + else if ( bVisible ) + xChild = CreateChild(i); + + if (xChild.is()) + xChild->SetVisible(m_bVisible && bVisible); + } + } + + m_nLastTopEntry = nTop; +} + +bool VCLXAccessibleList::checkEntrySelected(sal_Int32 _nPos,Any& _rNewValue,Reference< XAccessible >& _rxNewAcc) +{ + OSL_ENSURE(m_pListBoxHelper,"Helper is not valid!"); + bool bNowSelected = false; + if ( m_pListBoxHelper ) + { + bNowSelected = m_pListBoxHelper->IsEntryPosSelected (_nPos); + if ( bNowSelected ) + { + _rxNewAcc = CreateChild(_nPos); + _rNewValue <<= _rxNewAcc; + } + } + return bNowSelected; +} + + +void VCLXAccessibleList::UpdateSelection_Impl(sal_Int32) +{ + uno::Any aOldValue, aNewValue; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + Reference< XAccessible > xNewAcc; + + if ( m_pListBoxHelper ) + { + sal_Int32 i=0; + m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND; + for (const rtl::Reference<VCLXAccessibleListItem>& rxChild : m_aAccessibleChildren) + { + if (rxChild.is()) + { + // Retrieve the item's index from the list entry. + bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i); + if (bNowSelected) + m_nCurSelectedPos = i; + + if (bNowSelected && !rxChild->IsSelected()) + { + xNewAcc = rxChild; + aNewValue <<= xNewAcc; + } + else if (rxChild->IsSelected()) + m_nLastSelectedPos = i; + + rxChild->SetSelected(bNowSelected); + } + else + { // it could happen that a child was not created before + checkEntrySelected(i,aNewValue,xNewAcc); + } + ++i; + } + const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount(); + if ( i < nCount ) // here we have to check the if any other listbox entry is selected + { + for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i ) + ; + } + if ( xNewAcc.is() && GetWindow()->HasFocus() ) + { + if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND ) + aOldValue <<= getAccessibleChild( m_nLastSelectedPos ); + aNewValue <<= xNewAcc; + } + if (m_pListBoxHelper->IsInDropDown()) + { + if ( aNewValue.hasValue() || aOldValue.hasValue() ) + NotifyAccessibleEvent( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + aOldValue, + aNewValue ); + //the SELECTION_CHANGED is not necessary + //NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + } + } + } +} + + +// XAccessibleSelection + +void SAL_CALL VCLXAccessibleList::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + bool bNotify = false; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if ( m_pListBoxHelper ) + { + checkSelection_Impl(nChildIndex,*m_pListBoxHelper,false); + + m_pListBoxHelper->SelectEntryPos( static_cast<sal_uInt16>(nChildIndex) ); + // call the select handler, don't handle events in this time + m_bDisableProcessEvent = true; + m_pListBoxHelper->Select(); + m_bDisableProcessEvent = false; + bNotify = true; + } + } + + if ( bNotify ) + UpdateSelection_Impl(); +} + +sal_Bool SAL_CALL VCLXAccessibleList::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + bool bRet = false; + if ( m_pListBoxHelper ) + { + checkSelection_Impl(nChildIndex,*m_pListBoxHelper,false); + + bRet = m_pListBoxHelper->IsEntryPosSelected( static_cast<sal_uInt16>(nChildIndex) ); + } + return bRet; +} + +void SAL_CALL VCLXAccessibleList::clearAccessibleSelection( ) +{ + bool bNotify = false; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if ( m_pListBoxHelper ) + { + m_pListBoxHelper->SetNoSelection(); + bNotify = true; + } + } + + if ( bNotify ) + UpdateSelection_Impl(); +} + +void SAL_CALL VCLXAccessibleList::selectAllAccessibleChildren( ) +{ + bool bNotify = false; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if ( m_pListBoxHelper ) + { + const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + m_pListBoxHelper->SelectEntryPos( i ); + // call the select handler, don't handle events in this time + m_bDisableProcessEvent = true; + m_pListBoxHelper->Select(); + m_bDisableProcessEvent = false; + bNotify = true; + } + } + + if ( bNotify ) + UpdateSelection_Impl(); +} + +sal_Int64 SAL_CALL VCLXAccessibleList::getSelectedAccessibleChildCount( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_Int64 nCount = 0; + if ( m_pListBoxHelper ) + nCount = m_pListBoxHelper->GetSelectedEntryCount(); + return nCount; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleList::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if ( m_pListBoxHelper ) + { + checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,true); + return getAccessibleChild( m_pListBoxHelper->GetSelectedEntryPos( static_cast<sal_uInt16>(nSelectedChildIndex) ) ); + } + + return nullptr; +} + +void SAL_CALL VCLXAccessibleList::deselectAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + bool bNotify = false; + + { + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if ( m_pListBoxHelper ) + { + checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,false); + + m_pListBoxHelper->SelectEntryPos( static_cast<sal_uInt16>(nSelectedChildIndex), false ); + // call the select handler, don't handle events in this time + m_bDisableProcessEvent = true; + m_pListBoxHelper->Select(); + m_bDisableProcessEvent = false; + bNotify = true; + } + } + + if ( bNotify ) + UpdateSelection_Impl(); +} + +awt::Rectangle VCLXAccessibleList::implGetBounds() +{ + awt::Rectangle aBounds ( 0, 0, 0, 0 ); + if ( m_pListBoxHelper + && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN ) + { + if ( m_pListBoxHelper->IsInDropDown() ) + aBounds = AWTRectangle(m_pListBoxHelper->GetDropDownPosSizePixel()); + } + else + { + // a list has the same bounds as his parent but starts at (0,0) + aBounds = VCLXAccessibleComponent::implGetBounds(); + aBounds.X = 0; + aBounds.Y = 0; + if ( m_aBoxType == COMBOBOX ) + { + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + { + Size aSize = pBox->GetSubEdit()->GetSizePixel(); + aBounds.Y += aSize.Height(); + aBounds.Height -= aSize.Height(); + } + } + } + return aBounds; +} + + +awt::Point VCLXAccessibleList::getLocationOnScreen( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + awt::Point aPos; + if ( m_pListBoxHelper + && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN ) + { + if ( m_pListBoxHelper->IsInDropDown() ) + aPos = AWTPoint(m_pListBoxHelper->GetDropDownPosSizePixel().TopLeft()); + } + else + { + aPos = VCLXAccessibleComponent::getLocationOnScreen(); + if ( m_aBoxType == COMBOBOX ) + { + VclPtr< ComboBox > pBox = GetAs< ComboBox >(); + if ( pBox ) + { + aPos.Y += pBox->GetSubEdit()->GetSizePixel().Height(); + } + } + } + return aPos; +} + + +bool VCLXAccessibleList::IsInDropDown() const +{ + return m_pListBoxHelper->IsInDropDown(); +} + + +void VCLXAccessibleList::HandleDropOpen() +{ + if ( !m_bDisableProcessEvent ) + UpdateSelection_Impl(); + if (m_nCurSelectedPos != LISTBOX_ENTRY_NOTFOUND && + m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND) + { + Reference< XAccessible > xChild = getAccessibleChild(m_nCurSelectedPos); + if(xChild.is()) + { + uno::Any aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, uno::Any(), aNewValue ); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblelistbox.cxx b/accessibility/source/standard/vclxaccessiblelistbox.cxx new file mode 100644 index 0000000000..673000f221 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblelistbox.cxx @@ -0,0 +1,54 @@ +/* -*- 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 <standard/vclxaccessiblelistbox.hxx> +#include <comphelper/sequence.hxx> +#include <toolkit/awt/vclxwindow.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; + +VCLXAccessibleListBox::VCLXAccessibleListBox (VCLXWindow* pVCLWindow) + : VCLXAccessibleBox (pVCLWindow, VCLXAccessibleBox::LISTBOX, false) +{ +} + + +bool VCLXAccessibleListBox::IsValid() const +{ + return GetWindow(); +} + +// XServiceInfo + +OUString VCLXAccessibleListBox::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleListBox"; +} + + +Sequence< OUString > VCLXAccessibleListBox::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleBox::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleListBox"}); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblelistitem.cxx b/accessibility/source/standard/vclxaccessiblelistitem.cxx new file mode 100644 index 0000000000..5339f93824 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblelistitem.cxx @@ -0,0 +1,615 @@ +/* -*- 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 <standard/vclxaccessiblelistitem.hxx> +#include <toolkit/helper/convert.hxx> +#include <helper/IComboListBoxHelper.hxx> +#include <com/sun/star/awt/Rectangle.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/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <utility> +#include <vcl/svapp.hxx> +#include <vcl/toolkit/lstbox.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/settings.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <i18nlangtag/languagetag.hxx> + +namespace +{ + /// @throws css::lang::IndexOutOfBoundsException + void checkIndex_Impl( sal_Int32 _nIndex, std::u16string_view _sText ) + { + if ( _nIndex < 0 || _nIndex > static_cast<sal_Int32>(_sText.size()) ) + throw css::lang::IndexOutOfBoundsException(); + } +} + +// class VCLXAccessibleListItem ------------------------------------------ + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; + + +// Ctor() and Dtor() + +VCLXAccessibleListItem::VCLXAccessibleListItem(sal_Int32 _nIndexInParent, rtl::Reference< VCLXAccessibleList > _xParent) + : VCLXAccessibleListItem_BASE(m_aMutex) + , m_nIndexInParent(_nIndexInParent) + , m_bSelected(false) + , m_bVisible(false) + , m_nClientId(0) + , m_xParent(std::move(_xParent)) +{ + assert(m_xParent.is()); + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent->getListBoxHelper(); + if (pListBoxHelper) + m_sEntryText = pListBoxHelper->GetEntry(static_cast<sal_uInt16>(_nIndexInParent)); +} + +void VCLXAccessibleListItem::SetSelected( bool _bSelected ) +{ + if ( m_bSelected != _bSelected ) + { + Any aOldValue; + Any aNewValue; + if ( m_bSelected ) + aOldValue <<= AccessibleStateType::SELECTED; + else + aNewValue <<= AccessibleStateType::SELECTED; + m_bSelected = _bSelected; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + +void VCLXAccessibleListItem::SetVisible( bool _bVisible ) +{ + if ( m_bVisible != _bVisible ) + { + Any aOldValue, aNewValue; + m_bVisible = _bVisible; + (_bVisible ? aNewValue : aOldValue ) <<= AccessibleStateType::VISIBLE; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + (_bVisible ? aNewValue : aOldValue ) <<= AccessibleStateType::SHOWING; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + +void VCLXAccessibleListItem::NotifyAccessibleEvent( sal_Int16 _nEventId, + const css::uno::Any& _aOldValue, + const css::uno::Any& _aNewValue ) +{ + AccessibleEventObject aEvt; + aEvt.Source = *this; + aEvt.EventId = _nEventId; + aEvt.OldValue = _aOldValue; + aEvt.NewValue = _aNewValue; + + if (m_nClientId) + comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEvt ); +} + +// OCommonAccessibleText + +OUString VCLXAccessibleListItem::implGetText() +{ + return m_sEntryText; +} + +Locale VCLXAccessibleListItem::implGetLocale() +{ + return Application::GetSettings().GetLanguageTag().getLocale(); +} + +void VCLXAccessibleListItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + nStartIndex = 0; + nEndIndex = 0; +} + +// XTypeProvider + +Sequence< sal_Int8 > VCLXAccessibleListItem::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// XComponent + +void SAL_CALL VCLXAccessibleListItem::disposing() +{ + comphelper::AccessibleEventNotifier::TClientId nId( 0 ); + Reference< XInterface > xEventSource; + { + ::osl::MutexGuard aGuard( m_aMutex ); + + VCLXAccessibleListItem_BASE::disposing(); + m_sEntryText.clear(); + m_xParent = nullptr; + + nId = m_nClientId; + m_nClientId = 0; + if ( nId ) + xEventSource = *this; + } + + // Send a disposing to all listeners. + if ( nId ) + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); +} + +// XServiceInfo + +OUString VCLXAccessibleListItem::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleListItem"; +} + +sal_Bool VCLXAccessibleListItem::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +Sequence< OUString > VCLXAccessibleListItem::getSupportedServiceNames() +{ + return {"com.sun.star.accessibility.AccessibleContext", + "com.sun.star.accessibility.AccessibleComponent", + "com.sun.star.accessibility.AccessibleListItem"}; +} + +// XAccessible + +Reference< XAccessibleContext > SAL_CALL VCLXAccessibleListItem::getAccessibleContext( ) +{ + return this; +} + +// XAccessibleContext + +sal_Int64 SAL_CALL VCLXAccessibleListItem::getAccessibleChildCount( ) +{ + return 0; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleListItem::getAccessibleChild( sal_Int64 ) +{ + return Reference< XAccessible >(); +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleListItem::getAccessibleParent( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + return m_xParent; +} + +sal_Int64 SAL_CALL VCLXAccessibleListItem::getAccessibleIndexInParent( ) +{ + return m_nIndexInParent; +} + +sal_Int16 SAL_CALL VCLXAccessibleListItem::getAccessibleRole( ) +{ + return AccessibleRole::LIST_ITEM; + // return AccessibleRole::LABEL; +} + +OUString SAL_CALL VCLXAccessibleListItem::getAccessibleDescription( ) +{ + // no description for every item + return OUString(); +} + +OUString SAL_CALL VCLXAccessibleListItem::getAccessibleName( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + // entry text == accessible name + return m_sEntryText; +} + +Reference< XAccessibleRelationSet > SAL_CALL VCLXAccessibleListItem::getAccessibleRelationSet( ) +{ + return new utl::AccessibleRelationSetHelper; +} + +sal_Int64 SAL_CALL VCLXAccessibleListItem::getAccessibleStateSet( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + nStateSet |= AccessibleStateType::TRANSIENT; + + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper && pListBoxHelper->IsEnabled()) + { + nStateSet |= AccessibleStateType::SELECTABLE; + nStateSet |= AccessibleStateType::ENABLED; + nStateSet |= AccessibleStateType::SENSITIVE; + } + + if ( m_bSelected ) + nStateSet |= AccessibleStateType::SELECTED; + if ( m_bVisible ) + { + nStateSet |= AccessibleStateType::VISIBLE; + nStateSet |= AccessibleStateType::SHOWING; + } + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; +} + +Locale SAL_CALL VCLXAccessibleListItem::getLocale( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return implGetLocale(); +} + +// XAccessibleComponent + +sal_Bool SAL_CALL VCLXAccessibleListItem::containsPoint( const awt::Point& _aPoint ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + bool bInside = false; + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + { + tools::Rectangle aRect(pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent))); + aRect.Move(-aRect.Left(), -aRect.Top()); + bInside = aRect.Contains( VCLPoint( _aPoint ) ); + } + return bInside; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleListItem::getAccessibleAtPoint( const awt::Point& ) +{ + return Reference< XAccessible >(); +} + +awt::Rectangle SAL_CALL VCLXAccessibleListItem::getBounds( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + awt::Rectangle aRect; + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + aRect = AWTRectangle(pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent))); + + return aRect; +} + +awt::Point SAL_CALL VCLXAccessibleListItem::getLocation( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + Point aPoint(0,0); + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + { + tools::Rectangle aRect = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) ); + aPoint = aRect.TopLeft(); + } + return AWTPoint( aPoint ); +} + +awt::Point SAL_CALL VCLXAccessibleListItem::getLocationOnScreen( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + Point aPoint(0,0); + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + { + tools::Rectangle aRect = pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent)); + aPoint = aRect.TopLeft(); + aPoint += Point(pListBoxHelper->GetWindowExtentsAbsolute().TopLeft()); + } + return AWTPoint( aPoint ); +} + +awt::Size SAL_CALL VCLXAccessibleListItem::getSize( ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + Size aSize; + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + aSize = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) ).GetSize(); + + return AWTSize( aSize ); +} + +void SAL_CALL VCLXAccessibleListItem::grabFocus( ) +{ + // no focus for each item +} + +// XAccessibleText + +sal_Int32 SAL_CALL VCLXAccessibleListItem::getCaretPosition() +{ + return -1; +} + +sal_Bool SAL_CALL VCLXAccessibleListItem::setCaretPosition( sal_Int32 nIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !implIsValidRange( nIndex, nIndex, m_sEntryText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + +sal_Unicode SAL_CALL VCLXAccessibleListItem::getCharacter( sal_Int32 nIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return OCommonAccessibleText::implGetCharacter( m_sEntryText, nIndex ); +} + +Sequence< PropertyValue > SAL_CALL VCLXAccessibleListItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !implIsValidIndex( nIndex, m_sEntryText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return Sequence< PropertyValue >(); +} + +awt::Rectangle SAL_CALL VCLXAccessibleListItem::getCharacterBounds( sal_Int32 nIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !implIsValidIndex( nIndex, m_sEntryText.getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + { + tools::Rectangle aCharRect = pListBoxHelper->GetEntryCharacterBounds( m_nIndexInParent, nIndex ); + tools::Rectangle aItemRect = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; +} + +sal_Int32 SAL_CALL VCLXAccessibleListItem::getCharacterCount() +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return m_sEntryText.getLength(); +} + +sal_Int32 SAL_CALL VCLXAccessibleListItem::getIndexAtPoint( const awt::Point& aPoint ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nIndex = -1; + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + { + sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND; + tools::Rectangle aItemRect = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + sal_Int32 nI = pListBoxHelper->GetIndexForPoint( aPnt, nPos ); + if ( nI != -1 && m_nIndexInParent == nPos ) + nIndex = nI; + } + return nIndex; +} + +OUString SAL_CALL VCLXAccessibleListItem::getSelectedText() +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return OUString(); +} + +sal_Int32 SAL_CALL VCLXAccessibleListItem::getSelectionStart() +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return 0; +} + +sal_Int32 SAL_CALL VCLXAccessibleListItem::getSelectionEnd() +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return 0; +} + +sal_Bool SAL_CALL VCLXAccessibleListItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, m_sEntryText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + +OUString SAL_CALL VCLXAccessibleListItem::getText() +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return m_sEntryText; +} + +OUString SAL_CALL VCLXAccessibleListItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return OCommonAccessibleText::implGetTextRange( m_sEntryText, nStartIndex, nEndIndex ); +} + +css::accessibility::TextSegment SAL_CALL VCLXAccessibleListItem::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); +} + +css::accessibility::TextSegment SAL_CALL VCLXAccessibleListItem::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); +} + +css::accessibility::TextSegment SAL_CALL VCLXAccessibleListItem::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); +} + +sal_Bool SAL_CALL VCLXAccessibleListItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + checkIndex_Impl( nStartIndex, m_sEntryText ); + checkIndex_Impl( nEndIndex, m_sEntryText ); + + bool bRet = false; + ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr; + if (pListBoxHelper) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = pListBoxHelper->GetClipboard(); + if ( xClipboard.is() ) + { + OUString sText( getTextRange( nStartIndex, nEndIndex ) ); + rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText ); + + SolarMutexReleaser aReleaser; + xClipboard->setContents( pDataObj, nullptr ); + Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + + bRet = true; + } + } + + return bRet; +} + +sal_Bool VCLXAccessibleListItem::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + +// XAccessibleEventBroadcaster + +void SAL_CALL VCLXAccessibleListItem::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener ) +{ + if (xListener.is()) + { + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); + } +} + +void SAL_CALL VCLXAccessibleListItem::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener ) +{ + if ( !(xListener.is() && m_nClientId) ) + return; + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); + if ( nListenerCount ) + return; + + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + if ( m_nClientId ) + { + comphelper::AccessibleEventNotifier::TClientId nId( m_nClientId ); + m_nClientId = 0; + comphelper::AccessibleEventNotifier::revokeClient( nId ); + } +} + + +// AF (Oct. 29 2002): Return black as constant foreground color. This is an +// initial implementation and has to be substituted by code that determines +// the color that is actually used. +sal_Int32 SAL_CALL VCLXAccessibleListItem::getForeground() +{ + return sal_Int32(COL_BLACK); +} + +// AF (Oct. 29 2002): Return white as constant background color. This is an +// initial implementation and has to be substituted by code that determines +// the color that is actually used. +sal_Int32 SAL_CALL VCLXAccessibleListItem::getBackground() +{ + return sal_Int32(COL_WHITE); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblemenu.cxx b/accessibility/source/standard/vclxaccessiblemenu.cxx new file mode 100644 index 0000000000..5d1d54e400 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblemenu.cxx @@ -0,0 +1,222 @@ +/* -*- 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 <standard/vclxaccessiblemenu.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <vcl/menu.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + +// VCLXAccessibleMenu + + +bool VCLXAccessibleMenu::IsFocused() +{ + bool bFocused = false; + + if ( IsHighlighted() && !IsChildHighlighted() ) + bFocused = true; + + return bFocused; +} + + +bool VCLXAccessibleMenu::IsPopupMenuOpen() +{ + bool bPopupMenuOpen = false; + + if ( m_pParent ) + { + PopupMenu* pPopupMenu = m_pParent->GetPopupMenu( m_pParent->GetItemId( m_nItemPos ) ); + if ( pPopupMenu && pPopupMenu->IsMenuVisible() ) + bPopupMenuOpen = true; + } + + return bPopupMenuOpen; +} + + +// XServiceInfo + + +OUString VCLXAccessibleMenu::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleMenu"; +} + + +Sequence< OUString > VCLXAccessibleMenu::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleMenu" }; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleMenu::getAccessibleChildCount( ) +{ + OExternalLockGuard aGuard( this ); + + return GetChildCount(); +} + + +Reference< XAccessible > VCLXAccessibleMenu::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + return GetChild( i ); +} + + +sal_Int16 VCLXAccessibleMenu::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::MENU; +} + + +// XAccessibleComponent + + +Reference< XAccessible > VCLXAccessibleMenu::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + OExternalLockGuard aGuard( this ); + + return GetChildAt( rPoint ); +} + + +// XAccessibleSelection + + +void VCLXAccessibleMenu::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + SelectChild( nChildIndex ); +} + + +sal_Bool VCLXAccessibleMenu::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + return IsChildSelected( nChildIndex ); +} + + +void VCLXAccessibleMenu::clearAccessibleSelection( ) +{ + OExternalLockGuard aGuard( this ); + + DeSelectAll(); +} + + +void VCLXAccessibleMenu::selectAllAccessibleChildren( ) +{ + // This method makes no sense in a menu, and so does nothing. +} + + +sal_Int64 VCLXAccessibleMenu::getSelectedAccessibleChildCount( ) +{ + OExternalLockGuard aGuard( this ); + + return implGetSelectedAccessibleChildCount(); +} + +sal_Int64 VCLXAccessibleMenu::implGetSelectedAccessibleChildCount( ) +{ + sal_Int64 nRet = 0; + + for ( sal_Int64 i = 0, nCount = GetChildCount(); i < nCount; i++ ) + { + if ( IsChildSelected( i ) ) + ++nRet; + } + + return nRet; +} + +Reference< XAccessible > VCLXAccessibleMenu::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + + for ( sal_Int64 i = 0, j = 0, nCount = GetChildCount(); i < nCount; i++ ) + { + if ( IsChildSelected( i ) && ( j++ == nSelectedChildIndex ) ) + { + xChild = GetChild( i ); + break; + } + } + + return xChild; +} + + +void VCLXAccessibleMenu::deselectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || nChildIndex >= GetChildCount() ) + throw IndexOutOfBoundsException(); + + DeSelectAll(); +} + + +OUString VCLXAccessibleMenu::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) + throw IndexOutOfBoundsException(); + + return OUString( ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblemenubar.cxx b/accessibility/source/standard/vclxaccessiblemenubar.cxx new file mode 100644 index 0000000000..c54f376fe0 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblemenubar.cxx @@ -0,0 +1,188 @@ +/* -*- 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 <standard/vclxaccessiblemenubar.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/menu.hxx> +#include <vcl/settings.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::comphelper; + + + + +VCLXAccessibleMenuBar::VCLXAccessibleMenuBar( Menu* pMenu ) + :OAccessibleMenuComponent( pMenu ) +{ + if ( pMenu ) + { + m_pWindow = pMenu->GetWindow(); + + if ( m_pWindow ) + m_pWindow->AddEventListener( LINK( this, VCLXAccessibleMenuBar, WindowEventListener ) ); + } +} + + +VCLXAccessibleMenuBar::~VCLXAccessibleMenuBar() +{ + if ( m_pWindow ) + m_pWindow->RemoveEventListener( LINK( this, VCLXAccessibleMenuBar, WindowEventListener ) ); +} + + +bool VCLXAccessibleMenuBar::IsFocused() +{ + bool bFocused = false; + + if ( m_pWindow && m_pWindow->HasFocus() && !IsChildHighlighted() ) + bFocused = true; + + return bFocused; +} + + +IMPL_LINK( VCLXAccessibleMenuBar, WindowEventListener, VclWindowEvent&, rEvent, void ) +{ + assert( rEvent.GetWindow() ); + if ( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent.GetId() == VclEventId::ObjectDying ) ) + { + ProcessWindowEvent( rEvent ); + } +} + + +void VCLXAccessibleMenuBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowGetFocus: + case VclEventId::WindowLoseFocus: + { + SetFocused( rVclWindowEvent.GetId() == VclEventId::WindowGetFocus ); + } + break; + case VclEventId::ObjectDying: + { + if ( m_pWindow ) + { + m_pWindow->RemoveEventListener( LINK( this, VCLXAccessibleMenuBar, WindowEventListener ) ); + m_pWindow = nullptr; + } + } + break; + default: + { + } + break; + } +} + + +// XComponent + + +void VCLXAccessibleMenuBar::disposing() +{ + OAccessibleMenuComponent::disposing(); + + if ( m_pWindow ) + { + m_pWindow->RemoveEventListener( LINK( this, VCLXAccessibleMenuBar, WindowEventListener ) ); + m_pWindow = nullptr; + } +} + + +// XServiceInfo + + +OUString VCLXAccessibleMenuBar::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleMenuBar"; +} + + +Sequence< OUString > VCLXAccessibleMenuBar::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleMenuBar" }; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleMenuBar::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nIndexInParent = -1; + + if ( m_pMenu ) + { + vcl::Window* pWindow = m_pMenu->GetWindow(); + if ( pWindow ) + { + vcl::Window* pParent = pWindow->GetAccessibleParentWindow(); + if ( pParent ) + { + for ( sal_uInt16 n = pParent->GetAccessibleChildWindowCount(); n; ) + { + vcl::Window* pChild = pParent->GetAccessibleChildWindow( --n ); + if ( pChild == pWindow ) + { + nIndexInParent = n; + break; + } + } + } + } + } + + return nIndexInParent; +} + + +sal_Int16 VCLXAccessibleMenuBar::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::MENU_BAR; +} + + +// XAccessibleExtendedComponent + + +sal_Int32 VCLXAccessibleMenuBar::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + return sal_Int32(Application::GetSettings().GetStyleSettings().GetMenuBarColor()); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblemenuitem.cxx b/accessibility/source/standard/vclxaccessiblemenuitem.cxx new file mode 100644 index 0000000000..03bdc88c93 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblemenuitem.cxx @@ -0,0 +1,577 @@ +/* -*- 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 <standard/vclxaccessiblemenuitem.hxx> +#include <toolkit/helper/convert.hxx> +#include <helper/characterattributeshelper.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessiblekeybindinghelper.hxx> +#include <com/sun/star/awt/KeyModifier.hpp> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/sequence.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <vcl/event.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/menu.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/settings.hxx> +#include <strings.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; +using namespace ::comphelper; + + + + +VCLXAccessibleMenuItem::VCLXAccessibleMenuItem( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu ) + :ImplInheritanceHelper( pParent, nItemPos, pMenu ) +{ +} + + +bool VCLXAccessibleMenuItem::IsFocused() +{ + return IsHighlighted(); +} + + +bool VCLXAccessibleMenuItem::IsSelected() +{ + return IsHighlighted(); +} + +bool VCLXAccessibleMenuItem::IsCheckable() +{ + if (!m_pParent) + return false; + + const sal_uInt16 nItemId = m_pParent->GetItemId(m_nItemPos); + return m_pParent->IsItemCheckable(nItemId); +} + +bool VCLXAccessibleMenuItem::IsChecked() +{ + bool bChecked = false; + + if ( m_pParent ) + { + sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos ); + if ( m_pParent->IsItemChecked( nItemId ) ) + bChecked = true; + } + + return bChecked; +} + + +bool VCLXAccessibleMenuItem::IsHighlighted() +{ + bool bHighlighted = false; + + if ( m_pParent && m_pParent->IsHighlighted( m_nItemPos ) ) + bHighlighted = true; + + return bHighlighted; +} + + +void VCLXAccessibleMenuItem::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + OAccessibleMenuItemComponent::FillAccessibleStateSet( rStateSet ); + + rStateSet |= AccessibleStateType::FOCUSABLE; + + if ( IsFocused() ) + rStateSet |= AccessibleStateType::FOCUSED; + + rStateSet |= AccessibleStateType::SELECTABLE; + + if ( IsSelected() ) + rStateSet |= AccessibleStateType::SELECTED; + + if (IsCheckable()) + rStateSet |= AccessibleStateType::CHECKABLE; + if ( IsChecked() ) + rStateSet |= AccessibleStateType::CHECKED; +} + + +// OCommonAccessibleText + + +OUString VCLXAccessibleMenuItem::implGetText() +{ + return m_sItemText; +} + + +Locale VCLXAccessibleMenuItem::implGetLocale() +{ + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +void VCLXAccessibleMenuItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + nStartIndex = 0; + nEndIndex = 0; +} + + +// XServiceInfo + + +OUString VCLXAccessibleMenuItem::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleMenuItem"; +} + + +Sequence< OUString > VCLXAccessibleMenuItem::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleMenuItem" }; +} + + +// XAccessibleContext + + +sal_Int16 VCLXAccessibleMenuItem::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + // IA2 CWS. MT: We had the additional roles in UAA for ever, but never used them anywhere. + // Looks reasonable, but need to verify in Orca and VoiceOver. + sal_Int16 nRole = AccessibleRole::MENU_ITEM; + if ( m_pParent ) + { + sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos ); + MenuItemBits nItemBits = m_pParent->GetItemBits(nItemId); + if( nItemBits & MenuItemBits::RADIOCHECK) + nRole = AccessibleRole::RADIO_MENU_ITEM; + else if( nItemBits & MenuItemBits::CHECKABLE) + nRole = AccessibleRole::CHECK_MENU_ITEM; + } + return nRole; +} + + +// XAccessibleText + + +sal_Int32 VCLXAccessibleMenuItem::getCaretPosition() +{ + return -1; +} + + +sal_Bool VCLXAccessibleMenuItem::setCaretPosition( sal_Int32 nIndex ) +{ + + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nIndex, nIndex, m_sItemText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +sal_Unicode VCLXAccessibleMenuItem::getCharacter( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); +} + + +Sequence< PropertyValue > VCLXAccessibleMenuItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& aRequestedAttributes ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidIndex( nIndex, m_sItemText.getLength() ) ) + throw IndexOutOfBoundsException(); + + vcl::Font aFont = Application::GetSettings().GetStyleSettings().GetMenuFont(); + sal_Int32 nBackColor = getBackground(); + sal_Int32 nColor = getForeground(); + return CharacterAttributesHelper( aFont, nBackColor, nColor ) + .GetCharacterAttributes( aRequestedAttributes ); +} + + +awt::Rectangle VCLXAccessibleMenuItem::getCharacterBounds( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidIndex( nIndex, m_sItemText.getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( m_pParent ) + { + sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos ); + tools::Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos ); + tools::Rectangle aCharRect = m_pParent->GetCharacterBounds( nItemId, nIndex ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; +} + + +sal_Int32 VCLXAccessibleMenuItem::getCharacterCount() +{ + OExternalLockGuard aGuard( this ); + + return m_sItemText.getLength(); +} + + +sal_Int32 VCLXAccessibleMenuItem::getIndexAtPoint( const awt::Point& aPoint ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndex = -1; + if ( m_pParent ) + { + sal_uInt16 nItemId = 0; + tools::Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + sal_Int32 nI = m_pParent->GetIndexForPoint( aPnt, nItemId ); + if ( nI != -1 && m_pParent->GetItemId( m_nItemPos ) == nItemId ) + nIndex = nI; + } + + return nIndex; +} + + +OUString VCLXAccessibleMenuItem::getSelectedText() +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +sal_Int32 VCLXAccessibleMenuItem::getSelectionStart() +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +sal_Int32 VCLXAccessibleMenuItem::getSelectionEnd() +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +sal_Bool VCLXAccessibleMenuItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, m_sItemText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +OUString VCLXAccessibleMenuItem::getText() +{ + OExternalLockGuard aGuard( this ); + + return m_sItemText; +} + + +OUString VCLXAccessibleMenuItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ); +} + + +css::accessibility::TextSegment VCLXAccessibleMenuItem::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); +} + + +css::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); +} + + +css::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); +} + + +sal_Bool VCLXAccessibleMenuItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + if ( m_pParent ) + { + vcl::Window* pWindow = m_pParent->GetWindow(); + if ( pWindow ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = pWindow->GetClipboard(); + if ( xClipboard.is() ) + { + OUString sText( getTextRange( nStartIndex, nEndIndex ) ); + + rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText ); + + SolarMutexReleaser aReleaser; + xClipboard->setContents( pDataObj, nullptr ); + Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + + bReturn = true; + } + } + } + + return bReturn; +} + +sal_Bool VCLXAccessibleMenuItem::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + + +// XAccessibleAction + + +sal_Int32 VCLXAccessibleMenuItem::getAccessibleActionCount( ) +{ + return 1; +} + + +sal_Bool VCLXAccessibleMenuItem::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + Click(); + + return true; +} + + +OUString VCLXAccessibleMenuItem::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + return RID_STR_ACC_ACTION_SELECT; +} + + +Reference< XAccessibleKeyBinding > VCLXAccessibleMenuItem::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + rtl::Reference<OAccessibleKeyBindingHelper> pKeyBindingHelper = new OAccessibleKeyBindingHelper(); + + if ( m_pParent ) + { + // create auto mnemonics + if (!(m_pParent->GetMenuFlags() & MenuFlags::NoAutoMnemonics)) + m_pParent->CreateAutoMnemonics(); + + // activation key + KeyEvent aKeyEvent = m_pParent->GetActivationKey( m_pParent->GetItemId( m_nItemPos ) ); + vcl::KeyCode aKeyCode = aKeyEvent.GetKeyCode(); + Sequence< awt::KeyStroke > aSeq1 + { + { + 0, // Modifiers + static_cast< sal_Int16 >(aKeyCode.GetCode()), + aKeyEvent.GetCharCode(), + static_cast< sal_Int16 >( aKeyCode.GetFunction()) + } + }; + Reference< XAccessible > xParent( getAccessibleParent() ); + if ( xParent.is() ) + { + Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); + if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU_BAR ) + aSeq1.getArray()[0].Modifiers |= awt::KeyModifier::MOD2; + } + pKeyBindingHelper->AddKeyBinding( aSeq1 ); + + // complete menu activation key sequence + Sequence< awt::KeyStroke > aSeq; + if ( xParent.is() ) + { + Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); + if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU ) + { + Reference< XAccessibleAction > xAction( xParentContext, UNO_QUERY ); + if ( xAction.is() && xAction->getAccessibleActionCount() > 0 ) + { + Reference< XAccessibleKeyBinding > xKeyB( xAction->getAccessibleActionKeyBinding( 0 ) ); + if ( xKeyB.is() && xKeyB->getAccessibleKeyBindingCount() > 1 ) + aSeq = xKeyB->getAccessibleKeyBinding( 1 ); + } + } + } + Sequence< awt::KeyStroke > aSeq2 = ::comphelper::concatSequences( aSeq, aSeq1 ); + pKeyBindingHelper->AddKeyBinding( aSeq2 ); + + // accelerator key + vcl::KeyCode aAccelKeyCode = m_pParent->GetAccelKey( m_pParent->GetItemId( m_nItemPos ) ); + if ( aAccelKeyCode.GetCode() != 0 ) + { + Sequence< awt::KeyStroke > aSeq3 + { + { + 0, // Modifiers + static_cast< sal_Int16 >(aAccelKeyCode.GetCode()), + aKeyEvent.GetCharCode(), + static_cast< sal_Int16 >(aAccelKeyCode.GetFunction()) + } + }; + if (aAccelKeyCode.GetModifier() != 0) + { + auto pSeq3 = aSeq3.getArray(); + if ( aAccelKeyCode.IsShift() ) + pSeq3[0].Modifiers |= awt::KeyModifier::SHIFT; + if ( aAccelKeyCode.IsMod1() ) + pSeq3[0].Modifiers |= awt::KeyModifier::MOD1; + if ( aAccelKeyCode.IsMod2() ) + pSeq3[0].Modifiers |= awt::KeyModifier::MOD2; + if ( aAccelKeyCode.IsMod3() ) + pSeq3[0].Modifiers |= awt::KeyModifier::MOD3; + } + pKeyBindingHelper->AddKeyBinding( aSeq3 ); + } + } + + return pKeyBindingHelper; +} + + +// XAccessibleValue + + +Any VCLXAccessibleMenuItem::getCurrentValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + if ( IsSelected() ) + aValue <<= sal_Int32(1); + else + aValue <<= sal_Int32(0); + + return aValue; +} + + +sal_Bool VCLXAccessibleMenuItem::setCurrentValue( const Any& aNumber ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + sal_Int32 nValue = 0; + OSL_VERIFY( aNumber >>= nValue ); + + if ( nValue <= 0 ) + { + DeSelect(); + bReturn = true; + } + else if ( nValue >= 1 ) + { + Select(); + bReturn = true; + } + + return bReturn; +} + + +Any VCLXAccessibleMenuItem::getMaximumValue( ) +{ + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +Any VCLXAccessibleMenuItem::getMinimumValue( ) +{ + Any aValue; + aValue <<= sal_Int32(0); + + return aValue; +} + +Any VCLXAccessibleMenuItem::getMinimumIncrement( ) +{ + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblemenuseparator.cxx b/accessibility/source/standard/vclxaccessiblemenuseparator.cxx new file mode 100644 index 0000000000..50a70df01f --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblemenuseparator.cxx @@ -0,0 +1,50 @@ +/* -*- 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 <standard/vclxaccessiblemenuseparator.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::comphelper; + +VCLXAccessibleMenuSeparator::VCLXAccessibleMenuSeparator(Menu* pParent, sal_uInt16 nItemPos) + : OAccessibleMenuItemComponent(pParent, nItemPos, nullptr) +{ +} + +// XServiceInfo + +OUString VCLXAccessibleMenuSeparator::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleMenuSeparator"; +} + +Sequence<OUString> VCLXAccessibleMenuSeparator::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleMenuSeparator" }; +} + +// XAccessibleContext + +sal_Int16 VCLXAccessibleMenuSeparator::getAccessibleRole() { return AccessibleRole::SEPARATOR; } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblepopupmenu.cxx b/accessibility/source/standard/vclxaccessiblepopupmenu.cxx new file mode 100644 index 0000000000..65d4043187 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblepopupmenu.cxx @@ -0,0 +1,85 @@ +/* -*- 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 <standard/vclxaccessiblepopupmenu.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::comphelper; + + + + +bool VCLXAccessiblePopupMenu::IsFocused() +{ + return !IsChildHighlighted(); +} + + +// XServiceInfo + + +OUString VCLXAccessiblePopupMenu::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessiblePopupMenu"; +} + + +Sequence< OUString > VCLXAccessiblePopupMenu::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessiblePopupMenu" }; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessiblePopupMenu::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +sal_Int16 VCLXAccessiblePopupMenu::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::POPUP_MENU; +} + + +// XAccessibleExtendedComponent + + +sal_Int32 VCLXAccessiblePopupMenu::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + return sal_Int32(Application::GetSettings().GetStyleSettings().GetMenuColor()); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibleradiobutton.cxx b/accessibility/source/standard/vclxaccessibleradiobutton.cxx new file mode 100644 index 0000000000..c81dead756 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibleradiobutton.cxx @@ -0,0 +1,271 @@ +/* -*- 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 <standard/vclxaccessibleradiobutton.hxx> + +#include <toolkit/awt/vclxwindows.hxx> + +#include <unotools/accessiblerelationsethelper.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessiblekeybindinghelper.hxx> +#include <comphelper/sequence.hxx> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <vcl/window.hxx> +#include <vcl/toolkit/button.hxx> +#include <vcl/event.hxx> +#include <vcl/vclevent.hxx> +#include <strings.hxx> + +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; + + +// VCLXAccessibleRadioButton + + +void VCLXAccessibleRadioButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::RadiobuttonToggle: + { + Any aOldValue; + Any aNewValue; + + VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() ); + if ( pVCLXRadioButton && pVCLXRadioButton->getState() ) + aNewValue <<= AccessibleStateType::CHECKED; + else + aOldValue <<= AccessibleStateType::CHECKED; + + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } + break; + default: + VCLXAccessibleTextComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleRadioButton::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ) +{ + VCLXAccessibleTextComponent::FillAccessibleRelationSet( rRelationSet ); + + VclPtr< RadioButton > pRadioButton = GetAsDynamic< RadioButton >(); + if ( !pRadioButton ) + return; + + std::vector< VclPtr<RadioButton> > aGroup(pRadioButton->GetRadioButtonGroup()); + if (!aGroup.empty()) + { + std::vector< Reference< XInterface > > aVec; + aVec.reserve(aGroup.size()); + std::transform(aGroup.begin(), aGroup.end(), std::back_inserter(aVec), + [](const VclPtr<RadioButton>& rxItem) { return rxItem->GetAccessible(); }); + rRelationSet.AddRelation( AccessibleRelation( AccessibleRelationType::MEMBER_OF, + comphelper::containerToSequence(aVec) ) ); + } +} + + +void VCLXAccessibleRadioButton::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleTextComponent::FillAccessibleStateSet( rStateSet ); + + VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() ); + if ( pVCLXRadioButton ) + { + rStateSet |= AccessibleStateType::CHECKABLE; + rStateSet |= AccessibleStateType::FOCUSABLE; + if ( pVCLXRadioButton->getState() ) + rStateSet |= AccessibleStateType::CHECKED; + } +} + + +// XServiceInfo + + +OUString VCLXAccessibleRadioButton::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleRadioButton"; +} + + +Sequence< OUString > VCLXAccessibleRadioButton::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleRadioButton" }; +} + + +// XAccessibleAction + + +sal_Int32 VCLXAccessibleRadioButton::getAccessibleActionCount( ) +{ + OExternalLockGuard aGuard( this ); + + return 1; +} + + +sal_Bool VCLXAccessibleRadioButton::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() ); + if ( pVCLXRadioButton && !pVCLXRadioButton->getState() ) + pVCLXRadioButton->setState( true ); + + return true; +} + +OUString VCLXAccessibleRadioButton::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + return RID_STR_ACC_ACTION_SELECT; +} + +Reference< XAccessibleKeyBinding > VCLXAccessibleRadioButton::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + rtl::Reference<OAccessibleKeyBindingHelper> pKeyBindingHelper = new OAccessibleKeyBindingHelper(); + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + KeyEvent aKeyEvent = pWindow->GetActivationKey(); + vcl::KeyCode aKeyCode = aKeyEvent.GetKeyCode(); + if ( aKeyCode.GetCode() != 0 ) + { + awt::KeyStroke aKeyStroke; + aKeyStroke.Modifiers = 0; + if ( aKeyCode.IsShift() ) + aKeyStroke.Modifiers |= awt::KeyModifier::SHIFT; + if ( aKeyCode.IsMod1() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD1; + if ( aKeyCode.IsMod2() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD2; + if ( aKeyCode.IsMod3() ) + aKeyStroke.Modifiers |= awt::KeyModifier::MOD3; + aKeyStroke.KeyCode = aKeyCode.GetCode(); + aKeyStroke.KeyChar = aKeyEvent.GetCharCode(); + aKeyStroke.KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() ); + pKeyBindingHelper->AddKeyBinding( aKeyStroke ); + } + } + + return pKeyBindingHelper; +} + + +// XAccessibleValue + + +Any VCLXAccessibleRadioButton::getCurrentValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + + VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() ); + if ( pVCLXRadioButton ) + aValue <<= static_cast<sal_Int32>(pVCLXRadioButton->getState()); + + return aValue; +} + + +sal_Bool VCLXAccessibleRadioButton::setCurrentValue( const Any& aNumber ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() ); + if ( pVCLXRadioButton ) + { + sal_Int32 nValue = 0; + OSL_VERIFY( aNumber >>= nValue ); + + if ( nValue < 0 ) + nValue = 0; + else if ( nValue > 1 ) + nValue = 1; + + pVCLXRadioButton->setState( nValue == 1 ); + bReturn = true; + } + + return bReturn; +} + + +Any VCLXAccessibleRadioButton::getMaximumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +Any VCLXAccessibleRadioButton::getMinimumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(0); + + return aValue; +} + +Any VCLXAccessibleRadioButton::getMinimumIncrement( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(1); + + return aValue; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblescrollbar.cxx b/accessibility/source/standard/vclxaccessiblescrollbar.cxx new file mode 100644 index 0000000000..d608ec22e8 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblescrollbar.cxx @@ -0,0 +1,260 @@ +/* -*- 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 <standard/vclxaccessiblescrollbar.hxx> + +#include <toolkit/awt/vclxwindows.hxx> +#include <helper/accresmgr.hxx> +#include <strings.hrc> + +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/awt/ScrollBarOrientation.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <vcl/toolkit/scrbar.hxx> +#include <vcl/vclevent.hxx> +#include <strings.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + +// VCLXAccessibleScrollBar + + +void VCLXAccessibleScrollBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ScrollbarScroll: + { + NotifyAccessibleEvent( AccessibleEventId::VALUE_CHANGED, Any(), Any() ); + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleScrollBar::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + + VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); + if ( pVCLXScrollBar ) + { + // IA2 CWS: scroll bar should not have FOCUSABLE state. + // rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::HORIZONTAL ) + rStateSet |= AccessibleStateType::HORIZONTAL; + else if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::VERTICAL ) + rStateSet |= AccessibleStateType::VERTICAL; + } +} + + +// XServiceInfo + + +OUString VCLXAccessibleScrollBar::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleScrollBar"; +} + + +Sequence< OUString > VCLXAccessibleScrollBar::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleScrollBar" }; +} + + +// XAccessibleAction + +constexpr sal_Int32 ACCESSIBLE_ACTION_COUNT=4; + +sal_Int32 VCLXAccessibleScrollBar::getAccessibleActionCount( ) +{ + OExternalLockGuard aGuard( this ); + + return ACCESSIBLE_ACTION_COUNT; +} + + +sal_Bool VCLXAccessibleScrollBar::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex < 0 || nIndex >= ACCESSIBLE_ACTION_COUNT ) + throw IndexOutOfBoundsException(); + + bool bReturn = false; + VclPtr< ScrollBar > pScrollBar = GetAs< ScrollBar >(); + if ( pScrollBar ) + { + ScrollType eScrollType; + switch ( nIndex ) + { + case 0: eScrollType = ScrollType::LineUp; break; + case 1: eScrollType = ScrollType::LineDown; break; + case 2: eScrollType = ScrollType::PageUp; break; + case 3: eScrollType = ScrollType::PageDown; break; + default: eScrollType = ScrollType::DontKnow; break; + } + if ( pScrollBar->DoScrollAction( eScrollType ) ) + bReturn = true; + } + + return bReturn; +} + + +OUString VCLXAccessibleScrollBar::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex < 0 || nIndex >= ACCESSIBLE_ACTION_COUNT ) + throw IndexOutOfBoundsException(); + + OUString sDescription; + + switch ( nIndex ) + { + case 0: sDescription = RID_STR_ACC_ACTION_DECLINE; break; + case 1: sDescription = RID_STR_ACC_ACTION_INCLINE; break; + case 2: sDescription = RID_STR_ACC_ACTION_DECBLOCK; break; + case 3: sDescription = RID_STR_ACC_ACTION_INCBLOCK; break; + default: break; + } + + return sDescription; +} + + +Reference< XAccessibleKeyBinding > VCLXAccessibleScrollBar::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex < 0 || nIndex >= ACCESSIBLE_ACTION_COUNT ) + throw IndexOutOfBoundsException(); + + return Reference< XAccessibleKeyBinding >(); +} + + +// XAccessibleValue + + +Any VCLXAccessibleScrollBar::getCurrentValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + + VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); + if ( pVCLXScrollBar ) + aValue <<= pVCLXScrollBar->getValue(); + + return aValue; +} + + +sal_Bool VCLXAccessibleScrollBar::setCurrentValue( const Any& aNumber ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); + if ( pVCLXScrollBar ) + { + sal_Int32 nValue = 0, nValueMin = 0, nValueMax = 0; + OSL_VERIFY( aNumber >>= nValue ); + OSL_VERIFY( getMinimumValue() >>= nValueMin ); + OSL_VERIFY( getMaximumValue() >>= nValueMax ); + + if ( nValue < nValueMin ) + nValue = nValueMin; + else if ( nValue > nValueMax ) + nValue = nValueMax; + + pVCLXScrollBar->setValue( nValue ); + bReturn = true; + } + + return bReturn; +} + + +Any VCLXAccessibleScrollBar::getMaximumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + + VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); + if ( pVCLXScrollBar ) + aValue <<= pVCLXScrollBar->getMaximum(); + + return aValue; +} + + +Any VCLXAccessibleScrollBar::getMinimumValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + aValue <<= sal_Int32(0); + + return aValue; +} + +Any VCLXAccessibleScrollBar::getMinimumIncrement( ) +{ + OExternalLockGuard aGuard( this ); + + return Any(); +} + + +OUString VCLXAccessibleScrollBar::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + OUString aName; + VCLXScrollBar* pVCLXScrollBar = static_cast< VCLXScrollBar* >( GetVCLXWindow() ); + if ( pVCLXScrollBar ) + { + if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::HORIZONTAL ) + aName = AccResId( RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL ); + else if ( pVCLXScrollBar->getOrientation() == ScrollBarOrientation::VERTICAL ) + aName = AccResId( RID_STR_ACC_SCROLLBAR_NAME_VERTICAL ); + } + return aName; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblestatusbar.cxx b/accessibility/source/standard/vclxaccessiblestatusbar.cxx new file mode 100644 index 0000000000..5726193715 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblestatusbar.cxx @@ -0,0 +1,320 @@ +/* -*- 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 <standard/vclxaccessiblestatusbar.hxx> +#include <standard/vclxaccessiblestatusbaritem.hxx> +#include <toolkit/helper/convert.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <o3tl/safeint.hxx> +#include <vcl/status.hxx> +#include <vcl/vclevent.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + + + +VCLXAccessibleStatusBar::VCLXAccessibleStatusBar( VCLXWindow* pVCLXWindow ) + :VCLXAccessibleComponent( pVCLXWindow ) +{ + m_pStatusBar = GetAs<StatusBar>(); + + if ( m_pStatusBar ) + m_aAccessibleChildren.assign( m_pStatusBar->GetItemCount(), rtl::Reference< VCLXAccessibleStatusBarItem >() ); +} + + +void VCLXAccessibleStatusBar::UpdateShowing( sal_Int32 i, bool bShowing ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() ) + { + rtl::Reference< VCLXAccessibleStatusBarItem > pVCLXAccessibleStatusBarItem( m_aAccessibleChildren[i] ); + if ( pVCLXAccessibleStatusBarItem ) + pVCLXAccessibleStatusBarItem->SetShowing( bShowing ); + } +} + + +void VCLXAccessibleStatusBar::UpdateItemName( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + return; + + rtl::Reference< VCLXAccessibleStatusBarItem > pVCLXAccessibleStatusBarItem( m_aAccessibleChildren[i] ); + if ( pVCLXAccessibleStatusBarItem.is() ) + { + OUString sItemName = pVCLXAccessibleStatusBarItem->GetItemName(); + pVCLXAccessibleStatusBarItem->SetItemName( sItemName ); + } +} + + +void VCLXAccessibleStatusBar::UpdateItemText( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + return; + + rtl::Reference< VCLXAccessibleStatusBarItem > pVCLXAccessibleStatusBarItem( m_aAccessibleChildren[i] ); + if ( pVCLXAccessibleStatusBarItem.is() ) + { + OUString sItemText = pVCLXAccessibleStatusBarItem->GetItemText(); + pVCLXAccessibleStatusBarItem->SetItemText( sItemText ); + } +} + + +void VCLXAccessibleStatusBar::InsertChild( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) > m_aAccessibleChildren.size() ) + return; + + // insert entry in child list + m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, rtl::Reference< VCLXAccessibleStatusBarItem >() ); + + // send accessible child event + Reference< XAccessible > xChild( getAccessibleChild( i ) ); + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } +} + + +void VCLXAccessibleStatusBar::RemoveChild( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + return; + + // get the accessible of the removed page + Reference< XAccessible > xChild( m_aAccessibleChildren[i] ); + + // remove entry in child list + m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i ); + + // send accessible child event + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aOldValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + Reference< XComponent > xComponent( xChild, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } +} + + +void VCLXAccessibleStatusBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::StatusbarItemAdded: + { + if ( m_pStatusBar ) + { + sal_uInt16 nItemId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId ); + InsertChild( nItemPos ); + } + } + break; + case VclEventId::StatusbarItemRemoved: + { + if ( m_pStatusBar ) + { + OExternalLockGuard aGuard( this ); + + sal_uInt16 nItemId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + for ( sal_Int64 i = 0, nCount = m_aAccessibleChildren.size(); i < nCount; ++i ) + { + sal_uInt16 nChildItemId = m_pStatusBar->GetItemId( static_cast<sal_uInt16>(i) ); + if ( nChildItemId == nItemId ) + { + RemoveChild( i ); + break; + } + } + } + } + break; + case VclEventId::StatusbarAllItemsRemoved: + { + for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i ) + RemoveChild( i ); + } + break; + case VclEventId::StatusbarShowItem: + case VclEventId::StatusbarHideItem: + { + if ( m_pStatusBar ) + { + sal_uInt16 nItemId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId ); + UpdateShowing( nItemPos, rVclWindowEvent.GetId() == VclEventId::StatusbarShowItem ); + } + } + break; + case VclEventId::StatusbarNameChanged: + { + if ( m_pStatusBar ) + { + sal_uInt16 nItemId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId ); + UpdateItemName( nItemPos ); + } + } + break; + case VclEventId::StatusbarDrawItem: + { + if ( m_pStatusBar ) + { + sal_uInt16 nItemId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId ); + UpdateItemText( nItemPos ); + } + } + break; + case VclEventId::ObjectDying: + { + if ( m_pStatusBar ) + { + m_pStatusBar = nullptr; + + // dispose all children + for (const rtl::Reference<VCLXAccessibleStatusBarItem>& xComponent : m_aAccessibleChildren) + { + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren.clear(); + } + + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +// XComponent + + +void VCLXAccessibleStatusBar::disposing() +{ + VCLXAccessibleComponent::disposing(); + + if ( !m_pStatusBar ) + return; + + m_pStatusBar = nullptr; + + // dispose all children + for (const rtl::Reference<VCLXAccessibleStatusBarItem>& xComponent : m_aAccessibleChildren) + { + if ( xComponent.is() ) + xComponent->dispose(); + } + m_aAccessibleChildren.clear(); +} + + +// XServiceInfo + + +OUString VCLXAccessibleStatusBar::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleStatusBar"; +} + + +Sequence< OUString > VCLXAccessibleStatusBar::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleStatusBar" }; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleStatusBar::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + return m_aAccessibleChildren.size(); +} + + +Reference< XAccessible > VCLXAccessibleStatusBar::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + throw IndexOutOfBoundsException(); + + rtl::Reference< VCLXAccessibleStatusBarItem > xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + { + if ( m_pStatusBar ) + { + sal_uInt16 nItemId = m_pStatusBar->GetItemId( static_cast<sal_uInt16>(i) ); + + xChild = new VCLXAccessibleStatusBarItem( m_pStatusBar, nItemId ); + + // insert into status bar item list + m_aAccessibleChildren[i] = xChild; + } + } + + return xChild; +} + + +// XAccessibleComponent + + +Reference< XAccessible > VCLXAccessibleStatusBar::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xChild; + if ( m_pStatusBar ) + { + sal_uInt16 nItemId = m_pStatusBar->GetItemId( VCLPoint( rPoint ) ); + sal_Int32 nItemPos = m_pStatusBar->GetItemPos( nItemId ); + if ( nItemPos >= 0 && o3tl::make_unsigned(nItemPos) < m_aAccessibleChildren.size() ) + xChild = getAccessibleChild( nItemPos ); + } + + return xChild; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessiblestatusbaritem.cxx b/accessibility/source/standard/vclxaccessiblestatusbaritem.cxx new file mode 100644 index 0000000000..4c4bf62347 --- /dev/null +++ b/accessibility/source/standard/vclxaccessiblestatusbaritem.cxx @@ -0,0 +1,575 @@ +/* -*- 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 <standard/vclxaccessiblestatusbaritem.hxx> +#include <toolkit/helper/convert.hxx> +#include <helper/characterattributeshelper.hxx> + +#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/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/ctrl.hxx> +#include <vcl/svapp.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/status.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star; +using namespace ::comphelper; + + + + +VCLXAccessibleStatusBarItem::VCLXAccessibleStatusBarItem( StatusBar* pStatusBar, sal_uInt16 nItemId ) + :m_pStatusBar( pStatusBar ) + ,m_nItemId( nItemId ) +{ + + m_sItemName = GetItemName(); + m_sItemText = GetItemText(); + m_bShowing = IsShowing(); +} + + +bool VCLXAccessibleStatusBarItem::IsShowing() +{ + bool bShowing = false; + + if ( m_pStatusBar ) + bShowing = m_pStatusBar->IsItemVisible( m_nItemId ); + + return bShowing; +} + + +void VCLXAccessibleStatusBarItem::SetShowing( bool bShowing ) +{ + if ( m_bShowing != bShowing ) + { + Any aOldValue, aNewValue; + if ( m_bShowing ) + aOldValue <<= AccessibleStateType::SHOWING; + else + aNewValue <<= AccessibleStateType::SHOWING; + m_bShowing = bShowing; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + + +void VCLXAccessibleStatusBarItem::SetItemName( const OUString& sItemName ) +{ + if ( m_sItemName != sItemName ) + { + Any aOldValue, aNewValue; + aOldValue <<= m_sItemName; + aNewValue <<= sItemName; + m_sItemName = sItemName; + NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } +} + + +OUString VCLXAccessibleStatusBarItem::GetItemName() +{ + OUString sName; + if ( m_pStatusBar ) + sName = m_pStatusBar->GetAccessibleName( m_nItemId ); + + return sName; +} + + +void VCLXAccessibleStatusBarItem::SetItemText( const OUString& sItemText ) +{ + Any aOldValue, aNewValue; + if ( implInitTextChangedEvent( m_sItemText, sItemText, aOldValue, aNewValue ) ) + { + m_sItemText = sItemText; + NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue ); + } +} + + +OUString VCLXAccessibleStatusBarItem::GetItemText() +{ + OUString sText; + if ( m_pStatusBar ) + sText = m_pStatusBar->GetItemText( m_nItemId ); + + return sText; +} + + +void VCLXAccessibleStatusBarItem::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + + rStateSet |= AccessibleStateType::VISIBLE; + + if ( IsShowing() ) + rStateSet |= AccessibleStateType::SHOWING; +} + + +// OCommonAccessibleComponent + + +awt::Rectangle VCLXAccessibleStatusBarItem::implGetBounds() +{ + awt::Rectangle aBounds( 0, 0, 0, 0 ); + + if ( m_pStatusBar ) + aBounds = AWTRectangle( m_pStatusBar->GetItemRect( m_nItemId ) ); + + return aBounds; +} + + +// OCommonAccessibleText + + +OUString VCLXAccessibleStatusBarItem::implGetText() +{ + return GetItemText(); +} + + +lang::Locale VCLXAccessibleStatusBarItem::implGetLocale() +{ + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +void VCLXAccessibleStatusBarItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + nStartIndex = 0; + nEndIndex = 0; +} + + +// XComponent + + +void VCLXAccessibleStatusBarItem::disposing() +{ + AccessibleTextHelper_BASE::disposing(); + + m_pStatusBar = nullptr; + m_sItemName.clear(); + m_sItemText.clear(); +} + + +// XServiceInfo + + +OUString VCLXAccessibleStatusBarItem::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleStatusBarItem"; +} + + +sal_Bool VCLXAccessibleStatusBarItem::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + + +Sequence< OUString > VCLXAccessibleStatusBarItem::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleStatusBarItem" }; +} + + +// XAccessible + + +Reference< XAccessibleContext > VCLXAccessibleStatusBarItem::getAccessibleContext( ) +{ + OExternalLockGuard aGuard( this ); + + return this; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleStatusBarItem::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +Reference< XAccessible > VCLXAccessibleStatusBarItem::getAccessibleChild( sal_Int64 ) +{ + throw IndexOutOfBoundsException(); +} + + +Reference< XAccessible > VCLXAccessibleStatusBarItem::getAccessibleParent( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pStatusBar ) + xParent = m_pStatusBar->GetAccessible(); + + return xParent; +} + + +sal_Int64 VCLXAccessibleStatusBarItem::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nIndexInParent = -1; + if ( m_pStatusBar ) + nIndexInParent = m_pStatusBar->GetItemPos( m_nItemId ); + + return nIndexInParent; +} + + +sal_Int16 VCLXAccessibleStatusBarItem::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::LABEL; +} + + +OUString VCLXAccessibleStatusBarItem::getAccessibleDescription( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sDescription; + if ( m_pStatusBar ) + sDescription = m_pStatusBar->GetHelpText( m_nItemId ); + + return sDescription; +} + + +OUString VCLXAccessibleStatusBarItem::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + return GetItemName(); +} + + +Reference< XAccessibleRelationSet > VCLXAccessibleStatusBarItem::getAccessibleRelationSet( ) +{ + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; +} + + +sal_Int64 VCLXAccessibleStatusBarItem::getAccessibleStateSet( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; +} + + +Locale VCLXAccessibleStatusBarItem::getLocale( ) +{ + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +// XAccessibleComponent + + +Reference< XAccessible > VCLXAccessibleStatusBarItem::getAccessibleAtPoint( const awt::Point& ) +{ + OExternalLockGuard aGuard( this ); + + return Reference< XAccessible >(); +} + + +void VCLXAccessibleStatusBarItem::grabFocus( ) +{ + // no focus for status bar items +} + + +sal_Int32 VCLXAccessibleStatusBarItem::getForeground( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; +} + + +sal_Int32 VCLXAccessibleStatusBarItem::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; +} + + +// XAccessibleExtendedComponent + + +Reference< awt::XFont > VCLXAccessibleStatusBarItem::getFont( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; +} + + +OUString VCLXAccessibleStatusBarItem::getTitledBorderText( ) +{ + OExternalLockGuard aGuard( this ); + + return GetItemText(); +} + + +OUString VCLXAccessibleStatusBarItem::getToolTipText( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +// XAccessibleText + +OUString VCLXAccessibleStatusBarItem::getText() +{ + OExternalLockGuard aGuard( this ); + + return GetItemText(); +} + +OUString VCLXAccessibleStatusBarItem::getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetTextRange(GetItemText(), nStartIndex, nEndIndex); +} + + +sal_Int32 VCLXAccessibleStatusBarItem::getCharacterCount() +{ + OExternalLockGuard aGuard( this ); + + return GetItemText().getLength(); +} + +sal_Unicode VCLXAccessibleStatusBarItem::getCharacter( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetCharacter( GetItemText(), nIndex ); +} + +sal_Int32 VCLXAccessibleStatusBarItem::getCaretPosition() +{ + OExternalLockGuard aGuard( this ); + + return -1; +} + + +sal_Bool VCLXAccessibleStatusBarItem::setCaretPosition( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nIndex, nIndex, GetItemText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +Sequence< PropertyValue > VCLXAccessibleStatusBarItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& aRequestedAttributes ) +{ + OExternalLockGuard aGuard( this ); + + Sequence< PropertyValue > aValues; + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + if ( m_pStatusBar ) + { + vcl::Font aFont = m_pStatusBar->GetFont(); + sal_Int32 nBackColor = getBackground(); + sal_Int32 nColor = getForeground(); + aValues = CharacterAttributesHelper( aFont, nBackColor, nColor ) + .GetCharacterAttributes( aRequestedAttributes ); + } + + return aValues; +} + + +awt::Rectangle VCLXAccessibleStatusBarItem::getCharacterBounds( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( m_pStatusBar ) + { + vcl::ControlLayoutData aLayoutData; + tools::Rectangle aItemRect = m_pStatusBar->GetItemRect( m_nItemId ); + m_pStatusBar->RecordLayoutData( &aLayoutData, aItemRect ); + tools::Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; +} + + +sal_Int32 VCLXAccessibleStatusBarItem::getIndexAtPoint( const awt::Point& aPoint ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndex = -1; + if ( m_pStatusBar ) + { + vcl::ControlLayoutData aLayoutData; + tools::Rectangle aItemRect = m_pStatusBar->GetItemRect( m_nItemId ); + m_pStatusBar->RecordLayoutData( &aLayoutData, aItemRect ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + nIndex = aLayoutData.GetIndexForPoint( aPnt ); + } + + return nIndex; +} + + +sal_Bool VCLXAccessibleStatusBarItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +sal_Bool VCLXAccessibleStatusBarItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + if ( m_pStatusBar ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = m_pStatusBar->GetClipboard(); + if ( xClipboard.is() ) + { + OUString sText( implGetTextRange( GetItemText(), nStartIndex, nEndIndex ) ); + + rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText ); + + SolarMutexReleaser aReleaser; + xClipboard->setContents( pDataObj, nullptr ); + + Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + + bReturn = true; + } + } + + return bReturn; +} + + +sal_Bool VCLXAccessibleStatusBarItem::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletabcontrol.cxx b/accessibility/source/standard/vclxaccessibletabcontrol.cxx new file mode 100644 index 0000000000..e03e913041 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletabcontrol.cxx @@ -0,0 +1,450 @@ +/* -*- 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 <standard/vclxaccessibletabcontrol.hxx> +#include <standard/vclxaccessibletabpage.hxx> + +#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 <comphelper/accessiblecontexthelper.hxx> +#include <o3tl/safeint.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/vclevent.hxx> + +#include <vector> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + + + +VCLXAccessibleTabControl::VCLXAccessibleTabControl( VCLXWindow* pVCLXWindow ) + :ImplInheritanceHelper( pVCLXWindow ) +{ + m_pTabControl = GetAs<TabControl>(); + if (!m_pTabControl) + return; + if (m_pTabControl->isDisposed()) + { + m_pTabControl.clear(); + return; + } + m_aAccessibleChildren.assign( m_pTabControl->GetPageCount(), rtl::Reference< VCLXAccessibleTabPage >() ); +} + + +void VCLXAccessibleTabControl::UpdateFocused() +{ + for (const rtl::Reference<VCLXAccessibleTabPage>& pVCLXAccessibleTabPage : m_aAccessibleChildren) + { + if ( pVCLXAccessibleTabPage ) + pVCLXAccessibleTabPage->SetFocused( pVCLXAccessibleTabPage->IsFocused() ); + } +} + + +void VCLXAccessibleTabControl::UpdateSelected( sal_Int32 i, bool bSelected ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() ) + { + rtl::Reference< VCLXAccessibleTabPage > pVCLXAccessibleTabPage( m_aAccessibleChildren[i] ); + if ( pVCLXAccessibleTabPage ) + pVCLXAccessibleTabPage->SetSelected( bSelected ); + } +} + + +void VCLXAccessibleTabControl::UpdatePageText( sal_Int32 i ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() ) + { + rtl::Reference< VCLXAccessibleTabPage > pVCLXAccessibleTabPage( m_aAccessibleChildren[i] ); + if ( pVCLXAccessibleTabPage ) + pVCLXAccessibleTabPage->SetPageText( pVCLXAccessibleTabPage->GetPageText() ); + } +} + + +void VCLXAccessibleTabControl::UpdateTabPage( sal_Int32 i, bool bNew ) +{ + if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() ) + { + rtl::Reference< VCLXAccessibleTabPage > pVCLXAccessibleTabPage( m_aAccessibleChildren[i] ); + if ( pVCLXAccessibleTabPage ) + pVCLXAccessibleTabPage->Update( bNew ); + } +} + + +void VCLXAccessibleTabControl::InsertChild( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) > m_aAccessibleChildren.size() ) + return; + + // insert entry in child list + m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, rtl::Reference< VCLXAccessibleTabPage >() ); + + // send accessible child event + Reference< XAccessible > xChild( getAccessibleChild( i ) ); + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aNewValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } +} + + +void VCLXAccessibleTabControl::RemoveChild( sal_Int32 i ) +{ + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + return; + + // get the accessible of the removed page + rtl::Reference< VCLXAccessibleTabPage > xChild( m_aAccessibleChildren[i] ); + + // remove entry in child list + m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i ); + + // send accessible child event + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + aOldValue <<= uno::Reference<XAccessible>(xChild); + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + + xChild->dispose(); + } +} + + +void VCLXAccessibleTabControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::TabpageActivate: + case VclEventId::TabpageDeactivate: + { + if ( m_pTabControl ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabControl->GetPagePos( nPageId ); + UpdateFocused(); + UpdateSelected( nPagePos, rVclWindowEvent.GetId() == VclEventId::TabpageActivate ); + } + } + break; + case VclEventId::TabpagePageTextChanged: + { + if ( m_pTabControl ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabControl->GetPagePos( nPageId ); + UpdatePageText( nPagePos ); + } + } + break; + case VclEventId::TabpageInserted: + { + if ( m_pTabControl ) + { + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + sal_uInt16 nPagePos = m_pTabControl->GetPagePos( nPageId ); + InsertChild( nPagePos ); + } + } + break; + case VclEventId::TabpageRemoved: + { + if ( m_pTabControl ) + { + OExternalLockGuard aGuard( this ); + sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + for ( sal_Int64 i = 0, nCount = m_aAccessibleChildren.size(); i < nCount; ++i ) + { + if ( m_aAccessibleChildren[i] && m_aAccessibleChildren[i]->GetPageId() == nPageId ) + { + RemoveChild( i ); + break; + } + } + } + } + break; + case VclEventId::TabpageRemovedAll: + { + for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i ) + RemoveChild( i ); + } + break; + case VclEventId::WindowGetFocus: + case VclEventId::WindowLoseFocus: + { + UpdateFocused(); + } + break; + case VclEventId::ObjectDying: + { + if ( m_pTabControl ) + { + m_pTabControl = nullptr; + + // dispose all tab pages + for (const rtl::Reference<VCLXAccessibleTabPage>& i : m_aAccessibleChildren) + { + if (i.is()) + i->dispose(); + } + m_aAccessibleChildren.clear(); + } + + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleTabControl::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowShow: + case VclEventId::WindowHide: + { + if ( m_pTabControl ) + { + vcl::Window* pChild = static_cast< vcl::Window* >( rVclWindowEvent.GetData() ); + if ( pChild && pChild->GetType() == WindowType::TABPAGE ) + { + for ( sal_Int32 i = 0, nCount = m_pTabControl->GetPageCount(); i < nCount; ++i ) + { + sal_uInt16 nPageId = m_pTabControl->GetPageId( static_cast<sal_uInt16>(i) ); + TabPage* pTabPage = m_pTabControl->GetTabPage( nPageId ); + if ( pTabPage == static_cast<TabPage*>(pChild) ) + UpdateTabPage( i, rVclWindowEvent.GetId() == VclEventId::WindowShow ); + } + } + } + } + break; + default: + VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent ); + } +} + + +void VCLXAccessibleTabControl::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + + if ( m_pTabControl ) + rStateSet |= AccessibleStateType::FOCUSABLE; +} + + +// XComponent + + +void VCLXAccessibleTabControl::disposing() +{ + VCLXAccessibleComponent::disposing(); + + if ( !m_pTabControl ) + return; + + m_pTabControl = nullptr; + + // dispose all tab pages + for (const rtl::Reference<VCLXAccessibleTabPage>& xComponent : m_aAccessibleChildren) + if ( xComponent.is() ) + xComponent->dispose(); + m_aAccessibleChildren.clear(); +} + + +// XServiceInfo + + +OUString VCLXAccessibleTabControl::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleTabControl"; +} + + +Sequence< OUString > VCLXAccessibleTabControl::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleTabControl" }; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleTabControl::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + + return m_aAccessibleChildren.size(); +} + + +Reference< XAccessible > VCLXAccessibleTabControl::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() ) + throw IndexOutOfBoundsException(); + + return implGetAccessibleChild( i ); +} + +Reference< XAccessible > VCLXAccessibleTabControl::implGetAccessibleChild( sal_Int64 i ) +{ + rtl::Reference< VCLXAccessibleTabPage > xChild = m_aAccessibleChildren[i]; + if ( !xChild.is() ) + { + sal_uInt16 nPageId = m_pTabControl ? m_pTabControl->GetPageId(static_cast<sal_uInt16>(i)) : 0; + if (nPageId) + { + xChild = new VCLXAccessibleTabPage( m_pTabControl, nPageId ); + + // insert into tab page list + m_aAccessibleChildren[i] = xChild; + } + } + + return xChild; +} + + +sal_Int16 VCLXAccessibleTabControl::getAccessibleRole( ) +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::PAGE_TAB_LIST; +} + + +OUString VCLXAccessibleTabControl::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +// XAccessibleSelection + + +void VCLXAccessibleTabControl::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= m_aAccessibleChildren.size() ) + throw IndexOutOfBoundsException(); + + if ( m_pTabControl ) + m_pTabControl->SelectTabPage( m_pTabControl->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) ); +} + + +sal_Bool VCLXAccessibleTabControl::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= m_aAccessibleChildren.size() ) + throw IndexOutOfBoundsException(); + + return implIsAccessibleChildSelected( nChildIndex ); +} + +bool VCLXAccessibleTabControl::implIsAccessibleChildSelected( sal_Int32 nChildIndex ) +{ + bool bSelected = false; + if ( m_pTabControl && m_pTabControl->GetCurPageId() == m_pTabControl->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) ) + bSelected = true; + + return bSelected; +} + + +void VCLXAccessibleTabControl::clearAccessibleSelection( ) +{ + // This method makes no sense in a tab control, and so does nothing. +} + + +void VCLXAccessibleTabControl::selectAllAccessibleChildren( ) +{ + selectAccessibleChild( 0 ); +} + + +sal_Int64 VCLXAccessibleTabControl::getSelectedAccessibleChildCount( ) +{ + OExternalLockGuard aGuard( this ); + + return 1; +} + + +Reference< XAccessible > VCLXAccessibleTabControl::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nSelectedChildIndex != 0 ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + + for ( std::size_t i = 0, nCount = m_aAccessibleChildren.size(); i < nCount; i++ ) + { + if ( implIsAccessibleChildSelected( i ) ) + { + xChild = implGetAccessibleChild( i ); + break; + } + } + + return xChild; +} + + +void VCLXAccessibleTabControl::deselectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= m_aAccessibleChildren.size() ) + throw IndexOutOfBoundsException(); + + // This method makes no sense in a tab control, and so does nothing. +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletabpage.cxx b/accessibility/source/standard/vclxaccessibletabpage.cxx new file mode 100644 index 0000000000..89b0d6c29b --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletabpage.cxx @@ -0,0 +1,664 @@ +/* -*- 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 <standard/vclxaccessibletabpage.hxx> +#include <toolkit/helper/convert.hxx> +#include <helper/characterattributeshelper.hxx> + +#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/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/svapp.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star; +using namespace ::comphelper; + + + + +VCLXAccessibleTabPage::VCLXAccessibleTabPage( TabControl* pTabControl, sal_uInt16 nPageId ) + :m_pTabControl( pTabControl ) + ,m_nPageId( nPageId ) +{ + m_bFocused = IsFocused(); + m_bSelected = IsSelected(); + m_sPageText = GetPageText(); +} + + +VCLXAccessibleTabPage::~VCLXAccessibleTabPage() +{ +} + + +bool VCLXAccessibleTabPage::IsFocused() const +{ + bool bFocused = false; + + if ( m_pTabControl && m_pTabControl->HasFocus() && m_pTabControl->GetCurPageId() == m_nPageId ) + bFocused = true; + + return bFocused; +} + + +bool VCLXAccessibleTabPage::IsSelected() const +{ + bool bSelected = false; + + if ( m_pTabControl && m_pTabControl->GetCurPageId() == m_nPageId ) + bSelected = true; + + return bSelected; +} + + +void VCLXAccessibleTabPage::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 VCLXAccessibleTabPage::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 ); + } +} + + +void VCLXAccessibleTabPage::SetPageText( const OUString& sPageText ) +{ + Any aOldValue, aNewValue; + if ( OCommonAccessibleText::implInitTextChangedEvent( m_sPageText, sPageText, aOldValue, aNewValue ) ) + { + Any aOldName, aNewName; + aOldName <<= m_sPageText; + aNewName <<= sPageText; + m_sPageText = sPageText; + NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldName, aNewName ); + NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue ); + } +} + + +OUString VCLXAccessibleTabPage::GetPageText() +{ + OUString sText; + if ( m_pTabControl ) + sText = removeMnemonicFromString( m_pTabControl->GetPageText( m_nPageId ) ); + + return sText; +} + + +void VCLXAccessibleTabPage::Update( bool bNew ) +{ + if ( !m_pTabControl ) + return; + + TabPage* pTabPage = m_pTabControl->GetTabPage( m_nPageId ); + if ( !pTabPage ) + return; + + Reference< XAccessible > xChild( pTabPage->GetAccessible( bNew ) ); + if ( xChild.is() ) + { + Any aOldValue, aNewValue; + if ( bNew ) + aNewValue <<= xChild; + else + aOldValue <<= xChild; + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); + } +} + + +void VCLXAccessibleTabPage::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + rStateSet |= AccessibleStateType::ENABLED; + rStateSet |= AccessibleStateType::SENSITIVE; + + rStateSet |= AccessibleStateType::FOCUSABLE; + + if ( IsFocused() ) + rStateSet |= AccessibleStateType::FOCUSED; + + rStateSet |= AccessibleStateType::VISIBLE; + + rStateSet |= AccessibleStateType::SHOWING; + + rStateSet |= AccessibleStateType::SELECTABLE; + + if ( IsSelected() ) + rStateSet |= AccessibleStateType::SELECTED; +} + + +// OCommonAccessibleComponent + + +awt::Rectangle VCLXAccessibleTabPage::implGetBounds() +{ + awt::Rectangle aBounds( 0, 0, 0, 0 ); + + if ( m_pTabControl ) + aBounds = AWTRectangle( m_pTabControl->GetTabBounds( m_nPageId ) ); + + return aBounds; +} + + +// OCommonAccessibleText + + +OUString VCLXAccessibleTabPage::implGetText() +{ + return GetPageText(); +} + + +lang::Locale VCLXAccessibleTabPage::implGetLocale() +{ + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +void VCLXAccessibleTabPage::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + nStartIndex = 0; + nEndIndex = 0; +} + + +// XComponent + + +void VCLXAccessibleTabPage::disposing() +{ + AccessibleTextHelper_BASE::disposing(); + + m_pTabControl = nullptr; + m_sPageText.clear(); +} + + +// XServiceInfo + + +OUString VCLXAccessibleTabPage::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleTabPage"; +} + + +sal_Bool VCLXAccessibleTabPage::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + + +Sequence< OUString > VCLXAccessibleTabPage::getSupportedServiceNames() +{ + return { "com.sun.star.awt.AccessibleTabPage" }; +} + + +// XAccessible + + +Reference< XAccessibleContext > VCLXAccessibleTabPage::getAccessibleContext( ) +{ + OExternalLockGuard aGuard( this ); + + return this; +} + + +// XAccessibleContext + + +sal_Int64 VCLXAccessibleTabPage::getAccessibleChildCount() +{ + OExternalLockGuard aGuard( this ); + return implGetAccessibleChildCount(); +} + +sal_Int64 VCLXAccessibleTabPage::implGetAccessibleChildCount() +{ + sal_Int64 nCount = 0; + if ( m_pTabControl ) + { + TabPage* pTabPage = m_pTabControl->GetTabPage( m_nPageId ); + if ( pTabPage && pTabPage->IsVisible() ) + nCount = 1; + } + + return nCount; +} + + +Reference< XAccessible > VCLXAccessibleTabPage::getAccessibleChild( sal_Int64 i ) +{ + OExternalLockGuard aGuard( this ); + + if ( i < 0 || i >= implGetAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + if ( m_pTabControl ) + { + TabPage* pTabPage = m_pTabControl->GetTabPage( m_nPageId ); + if ( pTabPage && pTabPage->IsVisible() ) + xChild = pTabPage->GetAccessible(); + } + + return xChild; +} + + +Reference< XAccessible > VCLXAccessibleTabPage::getAccessibleParent( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pTabControl ) + xParent = m_pTabControl->GetAccessible(); + + return xParent; +} + + +sal_Int64 VCLXAccessibleTabPage::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nIndexInParent = -1; + if ( m_pTabControl ) + nIndexInParent = m_pTabControl->GetPagePos( m_nPageId ); + + return nIndexInParent; +} + +sal_Int16 VCLXAccessibleTabPage::getAccessibleRole() +{ + OExternalLockGuard aGuard( this ); + + return AccessibleRole::PAGE_TAB; +} + +OUString VCLXAccessibleTabPage::getAccessibleDescription() +{ + OExternalLockGuard aGuard( this ); + + OUString sDescription; + if ( m_pTabControl ) + sDescription = m_pTabControl->GetAccessibleDescription( m_nPageId ); + + return sDescription; +} + +OUString VCLXAccessibleTabPage::getAccessibleName() +{ + OExternalLockGuard aGuard( this ); + + OUString sName; + if ( m_pTabControl ) + sName = m_pTabControl->GetAccessibleName( m_nPageId ); + + return sName; +} + +Reference< XAccessibleRelationSet > VCLXAccessibleTabPage::getAccessibleRelationSet( ) +{ + OExternalLockGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; +} + + +sal_Int64 VCLXAccessibleTabPage::getAccessibleStateSet( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + FillAccessibleStateSet( nStateSet ); + } + else + { + nStateSet |= AccessibleStateType::DEFUNC; + } + + return nStateSet; +} + + +Locale VCLXAccessibleTabPage::getLocale( ) +{ + OExternalLockGuard aGuard( this ); + + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +// XAccessibleComponent + + +Reference< XAccessible > VCLXAccessibleTabPage::getAccessibleAtPoint( const awt::Point& rPoint ) +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xChild; + for ( sal_Int64 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i ) + { + Reference< XAccessible > xAcc = getAccessibleChild( i ); + if ( xAcc.is() ) + { + Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY ); + if ( xComp.is() ) + { + tools::Rectangle aRect = VCLRectangle( xComp->getBounds() ); + Point aPos = VCLPoint( rPoint ); + if ( aRect.Contains( aPos ) ) + { + xChild = xAcc; + break; + } + } + } + } + + return xChild; +} + + +void VCLXAccessibleTabPage::grabFocus( ) +{ + OExternalLockGuard aGuard( this ); + + if ( m_pTabControl ) + { + m_pTabControl->SelectTabPage( m_nPageId ); + m_pTabControl->GrabFocus(); + } +} + + +sal_Int32 VCLXAccessibleTabPage::getForeground( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getForeground(); + } + + return nColor; +} + + +sal_Int32 VCLXAccessibleTabPage::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nColor = 0; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + nColor = xParentComp->getBackground(); + } + + return nColor; +} + + +// XAccessibleExtendedComponent + + +Reference< awt::XFont > VCLXAccessibleTabPage::getFont( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< awt::XFont > xFont; + Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); + if ( xParentComp.is() ) + xFont = xParentComp->getFont(); + } + + return xFont; +} + + +OUString VCLXAccessibleTabPage::getTitledBorderText( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +OUString VCLXAccessibleTabPage::getToolTipText( ) +{ + OExternalLockGuard aGuard( this ); + + return OUString(); +} + + +// XAccessibleText + +OUString VCLXAccessibleTabPage::getText() +{ + OExternalLockGuard aGuard( this ); + + return GetPageText(); +} + +OUString VCLXAccessibleTabPage::getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetTextRange(GetPageText(), nStartIndex, nEndIndex); +} + +sal_Unicode VCLXAccessibleTabPage::getCharacter( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetCharacter( GetPageText(), nIndex ); +} + +sal_Int32 VCLXAccessibleTabPage::getCharacterCount() +{ + return GetPageText().getLength(); +} + +sal_Int32 VCLXAccessibleTabPage::getCaretPosition() +{ + OExternalLockGuard aGuard( this ); + + return -1; +} + + +sal_Bool VCLXAccessibleTabPage::setCaretPosition( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nIndex, nIndex, GetPageText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +Sequence< PropertyValue > VCLXAccessibleTabPage::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& aRequestedAttributes ) +{ + OExternalLockGuard aGuard( this ); + + Sequence< PropertyValue > aValues; + OUString sText( GetPageText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + if ( m_pTabControl ) + { + vcl::Font aFont = m_pTabControl->GetFont(); + sal_Int32 nBackColor = getBackground(); + sal_Int32 nColor = getForeground(); + aValues = CharacterAttributesHelper( aFont, nBackColor, nColor ) + .GetCharacterAttributes( aRequestedAttributes ); + } + + return aValues; +} + + +awt::Rectangle VCLXAccessibleTabPage::getCharacterBounds( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidIndex( nIndex, GetPageText().getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( m_pTabControl ) + { + tools::Rectangle aPageRect = m_pTabControl->GetTabBounds( m_nPageId ); + tools::Rectangle aCharRect; // m_pTabControl->GetCharacterBounds( m_nPageId, nIndex ); + aCharRect.Move( -aPageRect.Left(), -aPageRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; +} + + +sal_Int32 VCLXAccessibleTabPage::getIndexAtPoint( const awt::Point& /*aPoint*/ ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndex = -1; +// if ( m_pTabControl ) +// { +// sal_uInt16 nPageId = 0; +// tools::Rectangle aPageRect = m_pTabControl->GetTabBounds( m_nPageId ); +// Point aPnt( VCLPoint( aPoint ) ); +// aPnt += aPageRect.TopLeft(); +// sal_Int32 nI = m_pTabControl->GetIndexForPoint( aPnt, nPageId ); +// if ( nI != -1 && m_nPageId == nPageId ) +// nIndex = nI; +// } + + return nIndex; +} + + +sal_Bool VCLXAccessibleTabPage::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, GetPageText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +sal_Bool VCLXAccessibleTabPage::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + if ( m_pTabControl ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = m_pTabControl->GetClipboard(); + if ( xClipboard.is() ) + { + OUString sText( implGetTextRange( GetPageText(), nStartIndex, nEndIndex ) ); + + rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText ); + + SolarMutexReleaser aReleaser; + xClipboard->setContents( pDataObj, nullptr ); + + Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + + bReturn = true; + } + } + + return bReturn; +} + +sal_Bool VCLXAccessibleTabPage::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletabpagewindow.cxx b/accessibility/source/standard/vclxaccessibletabpagewindow.cxx new file mode 100644 index 0000000000..dea12aed6f --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletabpagewindow.cxx @@ -0,0 +1,134 @@ +/* -*- 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 <standard/vclxaccessibletabpagewindow.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <toolkit/helper/convert.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> +#include <sal/log.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + + + + +VCLXAccessibleTabPageWindow::VCLXAccessibleTabPageWindow( VCLXWindow* pVCLXWindow ) + :VCLXAccessibleComponent( pVCLXWindow ) +{ + m_pTabPage = GetAs<TabPage>(); + m_pTabControl = nullptr; + m_nPageId = 0; + if ( !m_pTabPage ) + return; + + vcl::Window* pParent = m_pTabPage->GetAccessibleParentWindow(); + if ( !(pParent && pParent->GetType() == WindowType::TABCONTROL) ) + return; + + m_pTabControl = static_cast< TabControl* >( pParent ); + if ( m_pTabControl ) + { + for ( sal_uInt16 i = 0, nCount = m_pTabControl->GetPageCount(); i < nCount; ++i ) + { + sal_uInt16 nPageId = m_pTabControl->GetPageId( i ); + if ( m_pTabControl->GetTabPage( nPageId ) == m_pTabPage.get() ) + m_nPageId = nPageId; + } + } +} + + +// OCommonAccessibleComponent + + +awt::Rectangle VCLXAccessibleTabPageWindow::implGetBounds() +{ + awt::Rectangle aBounds( 0, 0, 0, 0 ); + + if ( m_pTabControl ) + { + tools::Rectangle aPageRect = m_pTabControl->GetTabBounds( m_nPageId ); + if ( m_pTabPage ) + { + tools::Rectangle aRect( m_pTabPage->GetPosPixel(), m_pTabPage->GetSizePixel() ); + aRect.Move( -aPageRect.Left(), -aPageRect.Top() ); + aBounds = AWTRectangle( aRect ); + } + } + + return aBounds; +} + + +// XComponent + + +void VCLXAccessibleTabPageWindow::disposing() +{ + VCLXAccessibleComponent::disposing(); + + m_pTabControl = nullptr; + m_pTabPage = nullptr; +} + + +// XAccessibleContext + + +Reference< XAccessible > VCLXAccessibleTabPageWindow::getAccessibleParent( ) +{ + OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xParent; + if ( m_pTabControl ) + { + Reference< XAccessible > xAcc( m_pTabControl->GetAccessible() ); + if ( xAcc.is() ) + { + Reference< XAccessibleContext > xCont( xAcc->getAccessibleContext() ); + if ( xCont.is() ) + { + sal_uInt16 const nPagePos(m_pTabControl->GetPagePos(m_nPageId)); + SAL_WARN_IF(nPagePos == TAB_PAGE_NOTFOUND, "accessibility", + "getAccessibleParent(): no tab page"); + if (nPagePos != TAB_PAGE_NOTFOUND) + { + xParent = xCont->getAccessibleChild(nPagePos); + } + } + } + } + + return xParent; +} + + +sal_Int64 VCLXAccessibleTabPageWindow::getAccessibleIndexInParent( ) +{ + OExternalLockGuard aGuard( this ); + + return 0; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletextcomponent.cxx b/accessibility/source/standard/vclxaccessibletextcomponent.cxx new file mode 100644 index 0000000000..f876f0b9ed --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletextcomponent.cxx @@ -0,0 +1,374 @@ +/* -*- 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 <standard/vclxaccessibletextcomponent.hxx> +#include <toolkit/helper/convert.hxx> +#include <helper/characterattributeshelper.hxx> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <vcl/window.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/svapp.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/ctrl.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> + +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; + + + + +VCLXAccessibleTextComponent::VCLXAccessibleTextComponent( VCLXWindow* pVCLXWindow ) + :ImplInheritanceHelper( pVCLXWindow ) +{ + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + m_sText = removeMnemonicFromString( pWindow->GetText() ); +} + + +void VCLXAccessibleTextComponent::SetText( const OUString& sText ) +{ + Any aOldValue, aNewValue; + if ( implInitTextChangedEvent( m_sText, sText, aOldValue, aNewValue ) ) + { + m_sText = sText; + NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue ); + } + + // check whether accessible name has also changed, since text is (often) used as name as well + const OUString sName = getAccessibleName(); + if (sName != m_sOldName) + { + NotifyAccessibleEvent(AccessibleEventId::NAME_CHANGED, Any(m_sOldName), Any(sName)); + m_sOldName = sName; + } +} + + +void VCLXAccessibleTextComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowFrameTitleChanged: + { + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + SetText( implGetText() ); + } + break; + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + + +// OCommonAccessibleText + + +OUString VCLXAccessibleTextComponent::implGetText() +{ + OUString aText; + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + aText = removeMnemonicFromString( pWindow->GetText() ); + + return aText; +} + + +lang::Locale VCLXAccessibleTextComponent::implGetLocale() +{ + return Application::GetSettings().GetLanguageTag().getLocale(); +} + + +void VCLXAccessibleTextComponent::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + nStartIndex = 0; + nEndIndex = 0; +} + + +// XComponent + + +void VCLXAccessibleTextComponent::disposing() +{ + VCLXAccessibleComponent::disposing(); + + m_sText.clear(); +} + + +// XAccessibleText + + +sal_Int32 VCLXAccessibleTextComponent::getCaretPosition() +{ + return -1; +} + + +sal_Bool VCLXAccessibleTextComponent::setCaretPosition( sal_Int32 nIndex ) +{ + return setSelection( nIndex, nIndex ); +} + + +sal_Unicode VCLXAccessibleTextComponent::getCharacter( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); +} + + +Sequence< PropertyValue > VCLXAccessibleTextComponent::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& aRequestedAttributes ) +{ + OExternalLockGuard aGuard( this ); + + Sequence< PropertyValue > aValues; + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + vcl::Font aFont = pWindow->GetControlFont(); + + Color nBackColor = pWindow->GetControlBackground(); + Color nColor = pWindow->GetControlForeground(); + + // MT: Code with default font was introduced with the IA2 CWS, but I am not convinced that this is the correct font... + // Decide what to do when we have a concrete issue. + /* + Font aDefaultVCLFont; + OutputDevice* pDev = Application::GetDefaultDevice(); + if ( pDev ) + { + aDefaultVCLFont = pDev->GetSettings().GetStyleSettings().GetAppFont(); + if ( !aFont.GetName().Len() ) + { + String aDefaultName = aDefaultVCLFont.GetName(); + aFont.SetName( aDefaultName ); + } + if ( !aFont.GetHeight() ) + { + aFont.SetHeight( aDefaultVCLFont.GetHeight() ); + } + if ( aFont.GetWeight() == WEIGHT_DONTKNOW ) + { + aFont.SetWeight( aDefaultVCLFont.GetWeight() ); + } + + //if nColor is -1, it may indicate that the default color black is using. + if ( nColor == -1) + { + nColor = aDefaultVCLFont.GetColor().GetColor(); + } + } + */ + + // MT: Adjustment stuff was introduced with the IA2 CWS, but adjustment is not a character attribute... + // In case we reintroduce it, use adjustment as extra parameter for the CharacterAttributesHelper... + /* + WinBits aBits = GetWindow()->GetStyle(); + sal_Int16 nAdjust = -1; + if ( aBits & WB_LEFT ) + { + nAdjust = style::ParagraphAdjust_LEFT; + } + else if ( aBits & WB_RIGHT ) + { + nAdjust = style::ParagraphAdjust_RIGHT; + } + else if ( aBits & WB_CENTER ) + { + nAdjust = style::ParagraphAdjust_CENTER; + } + */ + + aValues = CharacterAttributesHelper( aFont, sal_Int32(nBackColor), sal_Int32(nColor) ) + .GetCharacterAttributes( aRequestedAttributes ); + } + + return aValues; +} + + +awt::Rectangle VCLXAccessibleTextComponent::getCharacterBounds( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aRect; + VclPtr< Control > pControl = GetAs< Control >(); + if ( pControl ) + aRect = AWTRectangle( pControl->GetCharacterBounds( nIndex ) ); + + return aRect; +} + + +sal_Int32 VCLXAccessibleTextComponent::getCharacterCount() +{ + OExternalLockGuard aGuard( this ); + + return implGetText().getLength(); +} + + +sal_Int32 VCLXAccessibleTextComponent::getIndexAtPoint( const awt::Point& aPoint ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndex = -1; + VclPtr< Control > pControl = GetAs< Control >(); + if ( pControl ) + nIndex = pControl->GetIndexForPoint( VCLPoint( aPoint ) ); + + return nIndex; +} + + +OUString VCLXAccessibleTextComponent::getSelectedText() +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getSelectedText(); +} + + +sal_Int32 VCLXAccessibleTextComponent::getSelectionStart() +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getSelectionStart(); +} + + +sal_Int32 VCLXAccessibleTextComponent::getSelectionEnd() +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getSelectionEnd(); +} + + +sal_Bool VCLXAccessibleTextComponent::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + + +OUString VCLXAccessibleTextComponent::getText() +{ + OExternalLockGuard aGuard( this ); + + return implGetText(); +} + + +OUString VCLXAccessibleTextComponent::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ); +} + + +css::accessibility::TextSegment VCLXAccessibleTextComponent::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); +} + + +css::accessibility::TextSegment VCLXAccessibleTextComponent::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); +} + + +css::accessibility::TextSegment VCLXAccessibleTextComponent::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); +} + + +sal_Bool VCLXAccessibleTextComponent::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + VclPtr<vcl::Window> pWindow = GetWindow(); + if ( pWindow ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = pWindow->GetClipboard(); + if ( xClipboard.is() ) + { + OUString sText( OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ) ); + + rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText ); + + SolarMutexReleaser aReleaser; + xClipboard->setContents( pDataObj, nullptr ); + + Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + + bReturn = true; + } + } + + return bReturn; +} + +sal_Bool VCLXAccessibleTextComponent::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletextfield.cxx b/accessibility/source/standard/vclxaccessibletextfield.cxx new file mode 100644 index 0000000000..6b37f44be5 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletextfield.cxx @@ -0,0 +1,103 @@ +/* -*- 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 <standard/vclxaccessibletextfield.hxx> +#include <comphelper/sequence.hxx> +#include <vcl/toolkit/lstbox.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +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; + + +VCLXAccessibleTextField::VCLXAccessibleTextField (VCLXWindow* pVCLWindow, const Reference< XAccessible >& _xParent) : + ImplInheritanceHelper (pVCLWindow), + m_xParent( _xParent ) + +{ +} + + +OUString VCLXAccessibleTextField::implGetText() +{ + OUString aText; + VclPtr< ListBox > pListBox = GetAs< ListBox >(); + if (pListBox && !pListBox->IsInDropDown()) + aText = pListBox->GetSelectedEntry(); + + return aText; +} + + +// XAccessible + +Reference<XAccessibleContext> SAL_CALL + VCLXAccessibleTextField::getAccessibleContext() +{ + return this; +} + + +// XAccessibleContext + +sal_Int64 SAL_CALL VCLXAccessibleTextField::getAccessibleChildCount() +{ + return 0; +} + + +Reference<XAccessible> SAL_CALL VCLXAccessibleTextField::getAccessibleChild (sal_Int64) +{ + throw IndexOutOfBoundsException(); +} + + +sal_Int16 SAL_CALL VCLXAccessibleTextField::getAccessibleRole() +{ + return AccessibleRole::TEXT; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleTextField::getAccessibleParent( ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return m_xParent; +} + + +// XServiceInfo + +OUString VCLXAccessibleTextField::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleTextField"; +} + + +Sequence< OUString > VCLXAccessibleTextField::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleTextComponent::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleTextField"}); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletoolbox.cxx b/accessibility/source/standard/vclxaccessibletoolbox.cxx new file mode 100644 index 0000000000..acb1d25471 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletoolbox.cxx @@ -0,0 +1,792 @@ +/* -*- 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 <string.h> + +#include <standard/vclxaccessibletoolbox.hxx> +#include <standard/vclxaccessibletoolboxitem.hxx> +#include <toolkit/helper/convert.hxx> + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <o3tl/safeint.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/vclevent.hxx> +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessiblewrapper.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> + +using namespace ::comphelper; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; + +namespace +{ + + // = OToolBoxWindowItemContext + + /** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window + */ + class OToolBoxWindowItemContext final : public OAccessibleContextWrapper + { + sal_Int32 m_nIndexInParent; + public: + OToolBoxWindowItemContext(sal_Int32 _nIndexInParent, + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerAccessibleContext, + const css::uno::Reference< css::accessibility::XAccessible >& _rxOwningAccessible, + const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible + ) : OAccessibleContextWrapper( + _rxContext, + _rxInnerAccessibleContext, + _rxOwningAccessible, + _rxParentAccessible ) + ,m_nIndexInParent(_nIndexInParent) + { + } + virtual sal_Int64 SAL_CALL getAccessibleIndexInParent( ) override; + }; + + + sal_Int64 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent( ) + { + return m_nIndexInParent; + } + + + // = OToolBoxWindowItem + + /** XAccessible implementation for a toolbox item which is represented by a VCL Window + */ + class OToolBoxWindowItem : public OAccessibleWrapper + { + private: + sal_Int32 m_nIndexInParent; + + public: + OToolBoxWindowItem(sal_Int32 _nIndexInParent, + const css::uno::Reference< css::uno::XComponentContext >& _rxContext, + const css::uno::Reference< css::accessibility::XAccessible >& _rxInnerAccessible, + const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible + ) : OAccessibleWrapper( + _rxContext, + _rxInnerAccessible, + _rxParentAccessible) + ,m_nIndexInParent(_nIndexInParent) + { + } + + protected: + // OAccessibleWrapper + virtual rtl::Reference<OAccessibleContextWrapper> createAccessibleContext( + const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerContext + ) override; + }; + + rtl::Reference<OAccessibleContextWrapper> OToolBoxWindowItem::createAccessibleContext( + const Reference< XAccessibleContext >& _rxInnerContext ) + { + return new OToolBoxWindowItemContext( m_nIndexInParent, getComponentContext(), _rxInnerContext, this, getParent() ); + } +} + +// VCLXAccessibleToolBox + +VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ) : + + ImplInheritanceHelper( pVCLXWindow ) + +{ +} + +VCLXAccessibleToolBox::~VCLXAccessibleToolBox() +{ +} + +VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( ToolBox::ImplToolItems::size_type _nPos ) +{ + VCLXAccessibleToolBoxItem* pItem = nullptr; + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( pToolBox ) + { + ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos ); + //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32! + // returns only toolbox buttons, not windows + if ( aIter != m_aAccessibleChildren.end() && aIter->second.is()) + pItem = aIter->second.get(); + } + + return pItem; +} + +void VCLXAccessibleToolBox::UpdateFocus_Impl() +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if( !pToolBox ) + return; + + // submit events only if toolbox has the focus to avoid sending events due to mouse move + bool bHasFocus = false; + if ( pToolBox->HasFocus() ) + bHasFocus = true; + else + { + // check for subtoolbar, i.e. check if our parent is a toolbar + ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() ); + // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it + if ( pToolBoxParent && pToolBoxParent->HasFocus() ) + bHasFocus = true; + } + + if ( !bHasFocus ) + return; + + ToolBoxItemId nHighlightItemId = pToolBox->GetHighlightItemId(); + sal_uInt16 nFocusCount = 0; + for ( const auto& [rPos, rxChild] : m_aAccessibleChildren ) + { + ToolBoxItemId nItemId = pToolBox->GetItemId( rPos ); + + if ( rxChild.is() ) + { + VCLXAccessibleToolBoxItem* pItem = rxChild.get(); + if ( pItem->HasFocus() && nItemId != nHighlightItemId ) + { + // reset the old focused item + pItem->SetFocus( false ); + nFocusCount++; + } + if ( nItemId == nHighlightItemId ) + { + // set the new focused item + pItem->SetFocus( true ); + nFocusCount++; + } + } + // both items changed? + if ( nFocusCount > 1 ) + break; + } +} + +void VCLXAccessibleToolBox::ReleaseFocus_Impl( ToolBox::ImplToolItems::size_type _nPos ) +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( pToolBox ) // #107124#, do not check for focus because this message is also handled in losefocus + { + ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos ); + //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32! + if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() ) + { + VCLXAccessibleToolBoxItem* pItem = aIter->second.get(); + if ( pItem->HasFocus() ) + pItem->SetFocus( false ); + } + } +} + +void VCLXAccessibleToolBox::UpdateChecked_Impl( ToolBox::ImplToolItems::size_type _nPos ) +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( !pToolBox ) + return; + + ToolBoxItemId nFocusId = pToolBox->GetItemId( _nPos ); + VCLXAccessibleToolBoxItem* pFocusItem = nullptr; + + for ( const auto& [rPos, rxChild] : m_aAccessibleChildren ) + { + ToolBoxItemId nItemId = pToolBox->GetItemId( rPos ); + + VCLXAccessibleToolBoxItem* pItem = rxChild.get(); + pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) ); + if ( nItemId == nFocusId ) + pFocusItem = pItem; + } + //Solution:If the position is not a child item,the focus should not be called + if ( pFocusItem && _nPos != ToolBox::ITEM_NOTFOUND ) + pFocusItem->SetFocus( true ); +} + +void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( ToolBox::ImplToolItems::size_type _nPos ) +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( !pToolBox ) + return; + + ToolBoxItemId nItemId = pToolBox->GetItemId( _nPos ); + + ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos ); + //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32! + if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() ) + { + VCLXAccessibleToolBoxItem* pItem = aIter->second.get(); + if ( pItem ) + pItem->SetIndeterminate( pToolBox->GetItemState( nItemId ) == TRISTATE_INDET ); + } +} + +void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator const & _rMapPos, + bool _bNotifyRemoval ) +{ + rtl::Reference<VCLXAccessibleToolBoxItem> xItemAcc(_rMapPos->second); + if ( !xItemAcc.is() ) + return; + + if ( _bNotifyRemoval ) + { + NotifyAccessibleEvent(AccessibleEventId::CHILD, Any(Reference<XAccessible>(xItemAcc)), Any()); + } + + xItemAcc->ReleaseToolBox(); + xItemAcc->dispose(); +} + +void VCLXAccessibleToolBox::UpdateItem_Impl( ToolBox::ImplToolItems::size_type _nPos) +{ + if ( _nPos < m_aAccessibleChildren.size() ) + { + UpdateAllItems_Impl(); + return; + } + + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( !pToolBox ) + return; + + // adjust the "index-in-parent"s + ToolBoxItemsMap::iterator aIndexAdjust = m_aAccessibleChildren.upper_bound( _nPos ); + //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32! + while ( m_aAccessibleChildren.end() != aIndexAdjust ) + { + rtl::Reference<VCLXAccessibleToolBoxItem> xItem(aIndexAdjust->second); + if (xItem.is()) + { + sal_Int32 nIndex = xItem->getIndexInParent(); + nIndex++; + xItem->setIndexInParent(nIndex); + } + + ++aIndexAdjust; + } + + // TODO: we should make this dependent on the existence of event listeners + // with the current implementation, we always create accessible object + Any aNewChild( getAccessibleChild( static_cast<sal_Int64>(_nPos) ) ); + //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32! + NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewChild ); +} + +void VCLXAccessibleToolBox::UpdateAllItems_Impl() +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( !pToolBox ) + return; + + // deregister the old items + for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin(); + aIter != m_aAccessibleChildren.end(); ++aIter ) + { + implReleaseToolboxItem( aIter, true ); + } + m_aAccessibleChildren.clear(); + + // register the new items + ToolBox::ImplToolItems::size_type i, nCount = pToolBox->GetItemCount(); + for ( i = 0; i < nCount; ++i ) + { + Any aNewValue; + aNewValue <<= getAccessibleChild(i); + NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue ); + } +} + +void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( vcl::Window* pWindow, bool bOpen ) +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if( !(pWindow && pToolBox) ) + return; + + const ToolBoxItemId nDownItem = pToolBox->GetDownItemId(); + if ( !nDownItem ) + // No item is currently in down state. + // Moreover, calling GetItemPos with 0 will find a separator if there is any. + return; + + Reference< XAccessible > xChild( pWindow->GetAccessible() ); + if( xChild.is() ) + { + Reference< XAccessible > xChildItem( getAccessibleChild(pToolBox->GetItemPos(nDownItem))); + VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xChildItem.get() ); + + pItem->SetChild( xChild ); + pItem->NotifyChildEvent( xChild, bOpen ); + } +} + +void VCLXAccessibleToolBox::UpdateItemName_Impl( ToolBox::ImplToolItems::size_type _nPos ) +{ + VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos ); + if ( pItem ) + pItem->NameChanged(); +} + +void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( ToolBox::ImplToolItems::size_type _nPos ) +{ + VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos ); + if ( pItem ) + pItem->ToggleEnableState(); +} + +void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent& rVclWindowEvent ) +{ + vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData()); + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( !(pChildWindow + && pToolBox + && pToolBox == pChildWindow->GetParent() + && pChildWindow->GetType() == WindowType::TOOLBOX) ) + return; + + const ToolBoxItemId nCurItemId( pToolBox->GetCurItemId() ); + if ( !nCurItemId ) + // No item is currently active (might happen when opening the overflow popup). + // Moreover, calling GetItemPos with 0 will find a separator if there is any. + return; + + ToolBox::ImplToolItems::size_type nIndex = pToolBox->GetItemPos( nCurItemId ); + Reference< XAccessible > xItem = getAccessibleChild( nIndex ); + if ( xItem.is() ) + { + Reference< XAccessible > xChild = pChildWindow->GetAccessible(); + VCLXAccessibleToolBoxItem* pItem = + static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() ); + pItem->SetChild( xChild ); + pItem->NotifyChildEvent( xChild, true/*_bShow*/ ); + } +} + +void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox* _pSubToolBox ) +{ + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( !pToolBox ) + return; + + ToolBox::ImplToolItems::size_type nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() ); + if ( nIndex == ToolBox::ITEM_NOTFOUND ) + return; // not found + + Reference< XAccessible > xItem = getAccessibleChild( nIndex ); + if ( !xItem.is() ) + return; + + Reference< XAccessible > xChild = _pSubToolBox->GetAccessible(); + VCLXAccessibleToolBoxItem* pItem = + static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() ); + if ( pItem->GetChild() == xChild ) + { + pItem->SetChild( Reference< XAccessible >() ); + pItem->NotifyChildEvent( xChild, false ); + } +} + +void VCLXAccessibleToolBox::FillAccessibleStateSet( sal_Int64& rStateSet ) +{ + VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); + + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( pToolBox ) + { + rStateSet |= AccessibleStateType::FOCUSABLE; + if ( pToolBox->IsHorizontal() ) + rStateSet |= AccessibleStateType::HORIZONTAL; + else + rStateSet |= AccessibleStateType::VERTICAL; + } +} + +void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + // to prevent an early release of the toolbox (VclEventId::ObjectDying) + Reference< XAccessibleContext > xHoldAlive = this; + + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::ToolboxClick: + case VclEventId::ToolboxSelect: + { + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( rVclWindowEvent.GetData() ) + { + UpdateChecked_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + } + else if( pToolBox->GetItemPos(pToolBox->GetCurItemId()) != ToolBox::ITEM_NOTFOUND ) + { + UpdateChecked_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) ); + UpdateIndeterminate_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) ); + } + break; + } + case VclEventId::ToolboxDoubleClick: + case VclEventId::ToolboxActivate: + case VclEventId::ToolboxDeactivate: + //case VclEventId::ToolboxSelect: + break; + + case VclEventId::ToolboxItemUpdated: + { + if ( rVclWindowEvent.GetData() ) + { + UpdateChecked_Impl( ToolBox::ITEM_NOTFOUND ); + UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + } + break; + } + + case VclEventId::ToolboxHighlight: + UpdateFocus_Impl(); + break; + + case VclEventId::ToolboxHighlightOff: + ReleaseFocus_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + break; + + case VclEventId::ToolboxItemAdded : + UpdateItem_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + break; + + case VclEventId::ToolboxItemRemoved : + case VclEventId::ToolboxAllItemsChanged : + { + UpdateAllItems_Impl(); + break; + } + + case VclEventId::ToolboxItemWindowChanged: + { + auto nPos = static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())); + ToolBoxItemsMap::iterator aAccessiblePos( m_aAccessibleChildren.find( nPos ) ); + //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32! + if ( m_aAccessibleChildren.end() != aAccessiblePos ) + { + implReleaseToolboxItem( aAccessiblePos, false ); + m_aAccessibleChildren.erase (aAccessiblePos); + } + + Any aNewValue; + aNewValue <<= getAccessibleChild(nPos); + NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue ); + break; + } + case VclEventId::ToolboxItemTextChanged : + UpdateItemName_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + break; + + case VclEventId::ToolboxItemEnabled : + case VclEventId::ToolboxItemDisabled : + { + UpdateItemEnabled_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) ); + break; + } + + case VclEventId::DropdownOpen: + case VclEventId::DropdownClose: + { + UpdateCustomPopupItemp_Impl( static_cast< vcl::Window* >( rVclWindowEvent.GetData() ), rVclWindowEvent.GetId() == VclEventId::DropdownOpen ); + break; + } + + case VclEventId::ObjectDying : + { + // if this toolbox is a subtoolbox, we have to release it from its parent + VclPtr< vcl::Window > pWin = GetAs< vcl::Window >(); + if ( pWin && pWin->GetParent() && + pWin->GetParent()->GetType() == WindowType::TOOLBOX ) + { + auto pParentAccContext = pWin->GetParent()->GetAccessible()->getAccessibleContext(); + VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >( pParentAccContext.get() ); + if ( pParent ) + pParent->ReleaseSubToolBox(static_cast<ToolBox *>(pWin.get())); + } + + // dispose all items + for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin(); + aIter != m_aAccessibleChildren.end(); ++aIter ) + { + implReleaseToolboxItem( aIter, false ); + } + m_aAccessibleChildren.clear(); + + [[fallthrough]]; // call base class + } + + default: + VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); + } +} + +void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VclEventId::WindowShow: // send create on show for direct accessible children + { + Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent); + if ( xReturn.is() ) + NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), Any(xReturn) ); + else + HandleSubToolBarEvent( rVclWindowEvent ); + } + break; + + default: + VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent ); + + } +} + +// XComponent +void SAL_CALL VCLXAccessibleToolBox::disposing() +{ + VCLXAccessibleComponent::disposing(); + + // release the items + for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin(); + aIter != m_aAccessibleChildren.end(); ++aIter ) + { + implReleaseToolboxItem( aIter, false ); + } + m_aAccessibleChildren.clear(); +} + +// XServiceInfo +OUString VCLXAccessibleToolBox::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleToolBox"; +} + +Sequence< OUString > VCLXAccessibleToolBox::getSupportedServiceNames() +{ + return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(), + Sequence<OUString>{"com.sun.star.accessibility.AccessibleToolBox"}); +} + +// XAccessibleContext +sal_Int64 SAL_CALL VCLXAccessibleToolBox::getAccessibleChildCount( ) +{ + comphelper::OExternalLockGuard aGuard( this ); + return implGetAccessibleChildCount(); +} + + sal_Int64 VCLXAccessibleToolBox::implGetAccessibleChildCount( ) + { + sal_Int64 nCount = 0; + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( pToolBox ) + nCount = pToolBox->GetItemCount(); + + return nCount; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleChild( sal_Int64 i ) +{ + comphelper::OExternalLockGuard aGuard( this ); + + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( (!pToolBox) || i < 0 || o3tl::make_unsigned(i) >= pToolBox->GetItemCount() ) + throw IndexOutOfBoundsException(); + + rtl::Reference< VCLXAccessibleToolBoxItem > xChild; + // search for the child + ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find(i); + if ( m_aAccessibleChildren.end() == aIter ) + { + ToolBoxItemId nItemId = pToolBox->GetItemId( i ); + ToolBoxItemId nHighlightItemId = pToolBox->GetHighlightItemId(); + vcl::Window* pItemWindow = pToolBox->GetItemWindow( nItemId ); + // not found -> create a new child + xChild = new VCLXAccessibleToolBoxItem( pToolBox, i ); + if ( pItemWindow ) + { + Reference< XAccessible> xParent = xChild; + rtl::Reference<OToolBoxWindowItem> xChild2( new OToolBoxWindowItem(0,::comphelper::getProcessComponentContext(),pItemWindow->GetAccessible(),xParent) ); + pItemWindow->SetAccessible(xChild2); + xChild->SetChild( xChild2 ); + } + if ( nHighlightItemId > ToolBoxItemId(0) && nItemId == nHighlightItemId ) + xChild->SetFocus( true ); + if ( pToolBox->IsItemChecked( nItemId ) ) + xChild->SetChecked( true ); + if ( pToolBox->GetItemState( nItemId ) == TRISTATE_INDET ) + xChild->SetIndeterminate( true ); + m_aAccessibleChildren.emplace( i, xChild ); + } + else + { + // found it + xChild = aIter->second; + } + return xChild; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point& _rPoint ) +{ + comphelper::OExternalLockGuard aGuard( this ); + + Reference< XAccessible > xAccessible; + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( pToolBox ) + { + ToolBox::ImplToolItems::size_type nItemPos = pToolBox->GetItemPos( VCLPoint( _rPoint ) ); + if ( nItemPos != ToolBox::ITEM_NOTFOUND ) + xAccessible = getAccessibleChild( nItemPos ); + } + + return xAccessible; +} + +Reference< XAccessible > VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent ) +{ + Reference< XAccessible > xReturn; + vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData()); + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( pChildWindow && pToolBox ) + { + ToolBox::ImplToolItems::size_type nCount = pToolBox->GetItemCount(); + for (ToolBox::ImplToolItems::size_type i = 0 ; i < nCount && !xReturn.is() ; ++i) + { + ToolBoxItemId nItemId = pToolBox->GetItemId( i ); + vcl::Window* pItemWindow = pToolBox->GetItemWindow( nItemId ); + if ( pItemWindow == pChildWindow ) + xReturn = getAccessibleChild(i); + } + } + return xReturn; +} + +Reference< XAccessible > VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent& rVclWindowEvent ) +{ + Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent); + + if ( !xReturn.is() ) + xReturn = VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent); + return xReturn; +} + +// XAccessibleSelection +void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( (!pToolBox) || nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= pToolBox->GetItemCount() ) + throw IndexOutOfBoundsException(); + + pToolBox->ChangeHighlight( nChildIndex ); +} + +sal_Bool VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if ( (!pToolBox) || nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= pToolBox->GetItemCount() ) + throw IndexOutOfBoundsException(); + + if ( pToolBox->GetHighlightItemId() == pToolBox->GetItemId( nChildIndex ) ) + return true; + else + return false; +} + +void VCLXAccessibleToolBox::clearAccessibleSelection( ) +{ + OExternalLockGuard aGuard( this ); + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + pToolBox -> LoseFocus(); +} + +void VCLXAccessibleToolBox::selectAllAccessibleChildren( ) +{ + OExternalLockGuard aGuard( this ); + // intentionally empty. makes no sense for a toolbox +} + +sal_Int64 VCLXAccessibleToolBox::getSelectedAccessibleChildCount( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nRet = 0; + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if (pToolBox) + { + ToolBoxItemId nHighlightItemId = pToolBox->GetHighlightItemId(); + for ( size_t i = 0, nCount = pToolBox->GetItemCount(); i < nCount; i++ ) + { + if ( nHighlightItemId == pToolBox->GetItemId( i ) ) + { + nRet = 1; + break; // a toolbox can only have (n)one selected child + } + } + } + + return nRet; +} + +Reference< XAccessible > VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex ) +{ + OExternalLockGuard aGuard( this ); + if ( nSelectedChildIndex != 0 ) + throw IndexOutOfBoundsException(); + + Reference< XAccessible > xChild; + VclPtr< ToolBox > pToolBox = GetAs< ToolBox >(); + if (pToolBox) + { + ToolBoxItemId nHighlightItemId = pToolBox->GetHighlightItemId(); + for (ToolBox::ImplToolItems::size_type i = 0, nCount = pToolBox->GetItemCount(); i < nCount; i++ ) + { + if ( nHighlightItemId == pToolBox->GetItemId( i ) ) + { + xChild = getAccessibleChild( i ); + break; + } + } + } + + if (!xChild) + throw IndexOutOfBoundsException(); + + return xChild; +} + +void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int64 nChildIndex ) +{ + OExternalLockGuard aGuard( this ); + if ( nChildIndex < 0 || nChildIndex >= implGetAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + clearAccessibleSelection(); // a toolbox can only have (n)one selected child +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/accessibility/source/standard/vclxaccessibletoolboxitem.cxx b/accessibility/source/standard/vclxaccessibletoolboxitem.cxx new file mode 100644 index 0000000000..96b8e5ef79 --- /dev/null +++ b/accessibility/source/standard/vclxaccessibletoolboxitem.cxx @@ -0,0 +1,728 @@ +/* -*- 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 <standard/vclxaccessibletoolboxitem.hxx> +#include <toolkit/helper/convert.hxx> +#include <helper/accresmgr.hxx> +#include <strings.hrc> +#include <com/sun/star/awt/Rectangle.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/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/unohelp2.hxx> +#include <vcl/help.hxx> +#include <vcl/settings.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <strings.hxx> +#include <sal/log.hxx> +#include <i18nlangtag/languagetag.hxx> + +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> + +#include <array> + +// class VCLXAccessibleToolBoxItem ------------------------------------------ + +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; +using namespace ::comphelper; + + +// Ctor() and Dtor() + +VCLXAccessibleToolBoxItem::VCLXAccessibleToolBoxItem( ToolBox* _pToolBox, sal_Int32 _nPos ) : + m_pToolBox ( _pToolBox ), + m_nIndexInParent( _nPos ), + m_nRole ( AccessibleRole::PUSH_BUTTON ), + m_nItemId ( 0 ), + m_bHasFocus ( false ), + m_bIsChecked ( false ), + m_bIndeterminate( false ) + +{ + assert( m_pToolBox ); + m_nItemId = m_pToolBox->GetItemId( m_nIndexInParent ); + m_sOldName = GetText(); + m_bIsChecked = m_pToolBox->IsItemChecked( m_nItemId ); + m_bIndeterminate = ( m_pToolBox->GetItemState( m_nItemId ) == TRISTATE_INDET ); + ToolBoxItemType eType = m_pToolBox->GetItemType( m_nIndexInParent ); + switch ( eType ) + { + case ToolBoxItemType::BUTTON : + { + ToolBoxItemBits nBits = m_pToolBox->GetItemBits( m_nItemId ); + if ( + (( nBits & ToolBoxItemBits::DROPDOWN ) == ToolBoxItemBits::DROPDOWN) || + (( nBits & ToolBoxItemBits::DROPDOWNONLY ) == ToolBoxItemBits::DROPDOWNONLY) + ) + m_nRole = AccessibleRole::BUTTON_DROPDOWN; + else if ( + ( ( nBits & ToolBoxItemBits::CHECKABLE ) == ToolBoxItemBits::CHECKABLE ) || + ( ( nBits & ToolBoxItemBits::RADIOCHECK ) == ToolBoxItemBits::RADIOCHECK ) || + ( ( nBits & ToolBoxItemBits::AUTOCHECK ) == ToolBoxItemBits::AUTOCHECK ) + ) + m_nRole = AccessibleRole::TOGGLE_BUTTON; + else if ( m_pToolBox->GetItemWindow( m_nItemId ) ) + m_nRole = AccessibleRole::PANEL; + break; + } + + case ToolBoxItemType::SPACE : + m_nRole = AccessibleRole::FILLER; + break; + + case ToolBoxItemType::SEPARATOR : + case ToolBoxItemType::BREAK : + m_nRole = AccessibleRole::SEPARATOR; + break; + + default: + { + SAL_WARN( "accessibility", "unsupported toolbox itemtype" ); + } + } +} + +VCLXAccessibleToolBoxItem::~VCLXAccessibleToolBoxItem() +{ +} + +OUString VCLXAccessibleToolBoxItem::GetText() const +{ + OUString sRet; + // no text for separators and spaces + if ( m_pToolBox && m_nItemId > ToolBoxItemId(0) ) + { + sRet = m_pToolBox->GetItemText( m_nItemId ); + if (sRet.isEmpty()) + { + sRet = m_pToolBox->GetQuickHelpText( m_nItemId ); + if (sRet.isEmpty()) + { + vcl::Window* pItemWindow = m_pToolBox->GetItemWindow( m_nItemId ); + if ( m_nRole == AccessibleRole::PANEL && pItemWindow && pItemWindow->GetAccessible().is() && + pItemWindow->GetAccessible()->getAccessibleContext().is() ) + { + OUString sWinText = pItemWindow->GetAccessible()->getAccessibleContext()->getAccessibleName(); + if (!sWinText.isEmpty()) + sRet = sWinText; + } + } + } + + } + return sRet; +} + +void VCLXAccessibleToolBoxItem::SetFocus( bool _bFocus ) +{ + if ( m_bHasFocus != _bFocus ) + { + Any aOldValue; + Any aNewValue; + if ( m_bHasFocus ) + aOldValue <<= AccessibleStateType::FOCUSED; + else + aNewValue <<= AccessibleStateType::FOCUSED; + m_bHasFocus = _bFocus; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + +void VCLXAccessibleToolBoxItem::SetChecked( bool _bCheck ) +{ + if( m_nRole == AccessibleRole::PANEL) + return; + if ( m_bIsChecked != _bCheck ) + { + Any aOldValue; + Any aNewValue; + if ( m_bIsChecked ) + aOldValue <<= AccessibleStateType::CHECKED; + else + aNewValue <<= AccessibleStateType::CHECKED; + m_bIsChecked = _bCheck; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + +void VCLXAccessibleToolBoxItem::SetIndeterminate( bool _bIndeterminate ) +{ + if ( m_bIndeterminate != _bIndeterminate ) + { + Any aOldValue, aNewValue; + if ( m_bIndeterminate ) + aOldValue <<= AccessibleStateType::INDETERMINATE; + else + aNewValue <<= AccessibleStateType::INDETERMINATE; + m_bIndeterminate = _bIndeterminate; + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); + } +} + +void VCLXAccessibleToolBoxItem::NameChanged() +{ + OUString sNewName = implGetText(); + if ( sNewName != m_sOldName ) + { + Any aOldValue, aNewValue; + aOldValue <<= m_sOldName; + // save new name as old name for next change + m_sOldName = sNewName; + aNewValue <<= m_sOldName; + NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue ); + } +} + +void VCLXAccessibleToolBoxItem::SetChild( const Reference< XAccessible >& _xChild ) +{ + m_xChild = _xChild; +} + +void VCLXAccessibleToolBoxItem::NotifyChildEvent( const Reference< XAccessible >& _xChild, bool _bShow ) +{ + Any aOld = _bShow ? Any() : Any( _xChild ); + Any aNew = _bShow ? Any( _xChild ) : Any(); + NotifyAccessibleEvent( AccessibleEventId::CHILD, aOld, aNew ); +} + +void VCLXAccessibleToolBoxItem::ToggleEnableState() +{ + std::array<Any, 2> aOldValue, aNewValue; + if ( m_pToolBox->IsItemEnabled( m_nItemId ) ) + { + aNewValue[0] <<= AccessibleStateType::SENSITIVE; + aNewValue[1] <<= AccessibleStateType::ENABLED; + } + else + { + aOldValue[0] <<= AccessibleStateType::ENABLED; + aOldValue[1] <<= AccessibleStateType::SENSITIVE; + } + + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[0], aNewValue[0] ); + NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[1], aNewValue[1] ); +} + +awt::Rectangle VCLXAccessibleToolBoxItem::implGetBounds( ) +{ + awt::Rectangle aRect; + if ( m_pToolBox ) + aRect = AWTRectangle( m_pToolBox->GetItemPosRect( m_nIndexInParent ) ); + + return aRect; +} + +OUString VCLXAccessibleToolBoxItem::implGetText() +{ + return GetText(); +} + +Locale VCLXAccessibleToolBoxItem::implGetLocale() +{ + return Application::GetSettings().GetUILanguageTag().getLocale(); +} + +void VCLXAccessibleToolBoxItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + nStartIndex = 0; + nEndIndex = 0; +} + +// XInterface + +Any SAL_CALL VCLXAccessibleToolBoxItem::queryInterface( const Type& _rType ) +{ + // #i33611# - toolbox buttons without text don't support XAccessibleText + if ( _rType == cppu::UnoType<XAccessibleText>::get() + && ( !m_pToolBox || m_pToolBox->GetButtonType() == ButtonType::SYMBOLONLY ) ) + return Any(); + + return ImplInheritanceHelper::queryInterface( _rType ); +} + +// XComponent + +void SAL_CALL VCLXAccessibleToolBoxItem::disposing() +{ + AccessibleTextHelper_BASE::disposing(); + m_pToolBox = nullptr; +} + +// XServiceInfo + +OUString VCLXAccessibleToolBoxItem::getImplementationName() +{ + return "com.sun.star.comp.toolkit.AccessibleToolBoxItem"; +} + +sal_Bool VCLXAccessibleToolBoxItem::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +Sequence< OUString > VCLXAccessibleToolBoxItem::getSupportedServiceNames() +{ + return {"com.sun.star.accessibility.AccessibleContext", + "com.sun.star.accessibility.AccessibleComponent", + "com.sun.star.accessibility.AccessibleExtendedComponent", + "com.sun.star.accessibility.AccessibleToolBoxItem"}; +} + +// XAccessible + +Reference< XAccessibleContext > SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleContext( ) +{ + return this; +} + +// XAccessibleContext + +sal_Int64 SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleChildCount( ) +{ + OContextEntryGuard aGuard( this ); + + return m_xChild.is() ? 1 : 0; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleChild( sal_Int64 i ) +{ + OContextEntryGuard aGuard( this ); + + // no child -> so index is out of bounds + if ( !m_xChild.is() || i != 0 ) + throw IndexOutOfBoundsException(); + + return m_xChild; +} + +Reference< XAccessible > SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleParent( ) +{ + OContextEntryGuard aGuard( this ); + + return m_pToolBox->GetAccessible(); +} + +sal_Int64 SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleIndexInParent( ) +{ + OContextEntryGuard aGuard( this ); + + return m_nIndexInParent; +} + +sal_Int16 SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleRole( ) +{ + OContextEntryGuard aGuard( this ); + + return m_nRole; +} + +OUString SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleDescription( ) +{ + OExternalLockGuard aGuard( this ); + + if (m_nRole == AccessibleRole::PANEL && m_xChild.is()) + { + return AccResId( RID_STR_ACC_PANEL_DESCRIPTION ); + } + else + { + OUString sDescription; + if ( m_pToolBox ) + sDescription = m_pToolBox->GetHelpText( m_nItemId ); + return sDescription; + } +} + +OUString SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleName( ) +{ + OExternalLockGuard aGuard( this ); + + // entry text == accessible name + return GetText(); +} + +Reference< XAccessibleRelationSet > SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleRelationSet( ) +{ + OContextEntryGuard aGuard( this ); + + return new utl::AccessibleRelationSetHelper; +} + +sal_Int64 SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleStateSet( ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int64 nStateSet = 0; + + if ( m_pToolBox && !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + nStateSet |= AccessibleStateType::FOCUSABLE; + if (m_pToolBox->GetItemBits(m_nItemId) & ToolBoxItemBits::CHECKABLE) + nStateSet |= AccessibleStateType::CHECKABLE; + if ( m_bIsChecked && m_nRole != AccessibleRole::PANEL ) + nStateSet |= AccessibleStateType::CHECKED; + if ( m_bIndeterminate ) + nStateSet |= AccessibleStateType::INDETERMINATE; + if ( m_pToolBox->IsEnabled() && m_pToolBox->IsItemEnabled( m_nItemId ) ) + { + nStateSet |= AccessibleStateType::ENABLED; + nStateSet |= AccessibleStateType::SENSITIVE; + } + if ( m_pToolBox->IsItemVisible( m_nItemId ) ) + nStateSet |= AccessibleStateType::VISIBLE; + if ( m_pToolBox->IsItemReallyVisible( m_nItemId ) ) + nStateSet |= AccessibleStateType::SHOWING; + if ( m_bHasFocus ) + nStateSet |= AccessibleStateType::FOCUSED; + } + else + nStateSet |= AccessibleStateType::DEFUNC; + + return nStateSet; +} + +// XAccessibleText + +OUString VCLXAccessibleToolBoxItem::getText() +{ + OExternalLockGuard aGuard( this ); + + return GetText(); +} + +sal_Int32 VCLXAccessibleToolBoxItem::getCharacterCount() +{ + return GetText().getLength(); +} + +sal_Unicode VCLXAccessibleToolBoxItem::getCharacter( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetCharacter( GetText(), nIndex ); +} + +OUString VCLXAccessibleToolBoxItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::implGetTextRange( GetText(), nStartIndex, nEndIndex ); +} + +sal_Int32 SAL_CALL VCLXAccessibleToolBoxItem::getCaretPosition() +{ + return -1; +} + +sal_Bool SAL_CALL VCLXAccessibleToolBoxItem::setCaretPosition( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nIndex, nIndex, GetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + +Sequence< PropertyValue > SAL_CALL VCLXAccessibleToolBoxItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& ) +{ + OExternalLockGuard aGuard( this ); + + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return Sequence< PropertyValue >(); +} + +awt::Rectangle SAL_CALL VCLXAccessibleToolBoxItem::getCharacterBounds( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( m_pToolBox && m_pToolBox->GetButtonType() != ButtonType::SYMBOLONLY ) // symbol buttons have no character bounds + { + tools::Rectangle aCharRect = m_pToolBox->GetCharacterBounds( m_nItemId, nIndex ); + tools::Rectangle aItemRect = m_pToolBox->GetItemRect( m_nItemId ); + aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); + aBounds = AWTRectangle( aCharRect ); + } + + return aBounds; +} + +sal_Int32 SAL_CALL VCLXAccessibleToolBoxItem::getIndexAtPoint( const awt::Point& aPoint ) +{ + OExternalLockGuard aGuard( this ); + + sal_Int32 nIndex = -1; + if ( m_pToolBox && m_pToolBox->GetButtonType() != ButtonType::SYMBOLONLY ) // symbol buttons have no character bounds + { + ToolBoxItemId nItemId; + tools::Rectangle aItemRect = m_pToolBox->GetItemRect( m_nItemId ); + Point aPnt( VCLPoint( aPoint ) ); + aPnt += aItemRect.TopLeft(); + sal_Int32 nIdx = m_pToolBox->GetIndexForPoint( aPnt, nItemId ); + if ( nIdx != -1 && nItemId == m_nItemId ) + nIndex = nIdx; + } + + return nIndex; +} + +sal_Bool SAL_CALL VCLXAccessibleToolBoxItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + return false; +} + +sal_Bool SAL_CALL VCLXAccessibleToolBoxItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) + throw IndexOutOfBoundsException(); + + bool bReturn = false; + + if ( m_pToolBox ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard = m_pToolBox->GetClipboard(); + if ( xClipboard.is() ) + { + OUString sText( OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex ) ); + + rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText ); + + SolarMutexReleaser aReleaser; + xClipboard->setContents( pDataObj, nullptr ); + + Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + + bReturn = true; + } + } + + return bReturn; +} + +sal_Bool VCLXAccessibleToolBoxItem::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) +{ + return false; +} + +// XAccessibleComponent + +Reference< XAccessible > SAL_CALL VCLXAccessibleToolBoxItem::getAccessibleAtPoint( const awt::Point& ) +{ + return Reference< XAccessible >(); +} + +void SAL_CALL VCLXAccessibleToolBoxItem::grabFocus( ) +{ + Reference< XAccessible > xParent(getAccessibleParent()); + + if( xParent.is() ) + { + Reference< XAccessibleSelection > rxAccessibleSelection(xParent->getAccessibleContext(), UNO_QUERY); + + if ( rxAccessibleSelection.is() ) + { + rxAccessibleSelection -> selectAccessibleChild ( getAccessibleIndexInParent() ); + } + } +} + +sal_Int32 SAL_CALL VCLXAccessibleToolBoxItem::getForeground( ) +{ + OExternalLockGuard aGuard( this ); + + Color nColor; + if ( m_pToolBox ) + nColor = m_pToolBox->GetControlForeground(); + + return sal_Int32(nColor); +} + +sal_Int32 SAL_CALL VCLXAccessibleToolBoxItem::getBackground( ) +{ + OExternalLockGuard aGuard( this ); + + Color nColor; + if ( m_pToolBox ) + nColor = m_pToolBox->GetControlBackground(); + + return sal_Int32(nColor); +} + +// XAccessibleExtendedComponent +Reference< awt::XFont > SAL_CALL VCLXAccessibleToolBoxItem::getFont( ) +{ + return uno::Reference< awt::XFont >(); +} + +OUString SAL_CALL VCLXAccessibleToolBoxItem::getTitledBorderText( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sRet; + if ( m_pToolBox ) + sRet = m_pToolBox->GetItemText( m_nItemId ); + + return sRet; +} + +OUString SAL_CALL VCLXAccessibleToolBoxItem::getToolTipText( ) +{ + OExternalLockGuard aGuard( this ); + + OUString sRet; + if ( m_pToolBox ) + { + if ( Help::IsExtHelpEnabled() ) + sRet = m_pToolBox->GetHelpText( m_nItemId ); + else + sRet = m_pToolBox->GetQuickHelpText( m_nItemId ); + if ( sRet.isEmpty() ) + // no help text set, so use item text + sRet = m_pToolBox->GetItemText( m_nItemId ); + } + return sRet; +} + +// XAccessibleAction + +sal_Int32 VCLXAccessibleToolBoxItem::getAccessibleActionCount( ) +{ + // only one action -> "Click" + return 1; +} + +sal_Bool VCLXAccessibleToolBoxItem::doAccessibleAction ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + if ( m_pToolBox ) + m_pToolBox->TriggerItem( m_nItemId ); + + return true; +} + +OUString VCLXAccessibleToolBoxItem::getAccessibleActionDescription ( sal_Int32 nIndex ) +{ + OExternalLockGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + return RID_STR_ACC_ACTION_CLICK; +} + +Reference< XAccessibleKeyBinding > VCLXAccessibleToolBoxItem::getAccessibleActionKeyBinding( sal_Int32 nIndex ) +{ + OContextEntryGuard aGuard( this ); + + if ( nIndex != 0 ) + throw IndexOutOfBoundsException(); + + return Reference< XAccessibleKeyBinding >(); +} + +// XAccessibleValue + +Any VCLXAccessibleToolBoxItem::getCurrentValue( ) +{ + OExternalLockGuard aGuard( this ); + + Any aValue; + if ( m_pToolBox ) + aValue <<= static_cast<sal_Int32>(m_pToolBox->IsItemChecked( m_nItemId )); + + if( m_nRole == AccessibleRole::PANEL ) + aValue <<= sal_Int32(0); + return aValue; +} + +sal_Bool VCLXAccessibleToolBoxItem::setCurrentValue( const Any& aNumber ) +{ + OExternalLockGuard aGuard( this ); + + bool bReturn = false; + + if ( m_pToolBox ) + { + sal_Int32 nValue = 0; + OSL_VERIFY( aNumber >>= nValue ); + + if ( nValue < 0 ) + nValue = 0; + else if ( nValue > 1 ) + nValue = 1; + + m_pToolBox->CheckItem( m_nItemId, nValue == 1 ); + bReturn = true; + } + + return bReturn; +} + +Any VCLXAccessibleToolBoxItem::getMaximumValue( ) +{ + return Any(sal_Int32(1)); +} + +Any VCLXAccessibleToolBoxItem::getMinimumValue( ) +{ + return Any(sal_Int32(0)); +} + +Any VCLXAccessibleToolBoxItem::getMinimumIncrement( ) +{ + return Any(sal_Int32(1)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |